This commit is contained in:
lun_admin 2024-07-31 20:38:44 +09:00
parent ae743bf784
commit 4c620872af
25 changed files with 1230 additions and 875 deletions

View File

@ -2,7 +2,7 @@ plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'io.realm.kotlin'
id 'kotlin-android-extensions'
// id 'kotlin-android-extensions'
}
android {

View File

@ -23,12 +23,12 @@ import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.ImageButton
import android.widget.ProgressBar
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.AppCompatButton
import com.google.gson.Gson
import com.lge.display.DisplayManagerHelper
import com.mime.dualscreenview.R
import com.mime.dualscreenview.common.Blog
import com.mime.dualscreenview.common.PairArray
@ -38,6 +38,7 @@ import com.mime.dualscreenview.common.typesfacez
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.BookPageInfosJ
import com.mime.dualscreenview.data.model.HistoryItem
import com.mime.dualscreenview.data.model.LastInfo
import com.mime.dualscreenview.data.model.ReaderConfig
@ -47,14 +48,14 @@ import com.mime.dualscreenview.view.PagedTextViewInterface
import com.mime.dualscreenview.view.TouchArea
import com.mime.dualscreenview.webcontents.BaseWebContentsViewer
import com.mime.dualscreenview.webcontents.MainControllInterface
import com.mime.dualscreenview.webcontents.contentsinfo.Agit
import com.mime.dualscreenview.webcontents.contentsinfo.Booktoki
import com.mime.dualscreenview.webcontents.contentsinfo.GotoSomeWhere
import io.realm.kotlin.Realm
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.copyFromRealm
import io.realm.kotlin.ext.query
import kotlinx.android.synthetic.main.intro.paged_layer
import kotlinx.android.synthetic.main.intro.textview_title
import kotlinx.android.synthetic.main.settings.preview
import io.realm.kotlin.query.find
import java.lang.System.currentTimeMillis
import java.text.SimpleDateFormat
import java.util.Date
@ -62,33 +63,21 @@ import java.util.Date
class Intro : Base() , MainControllInterface, PagedTextViewInterface {
private var displayManagerHelper: DisplayManagerHelper? = null
// This callbacks where receive events from the cover
private var coverDisplayCallback: MainCoverDisplayCallback? = null
private var smartCoverCallback: MainSmartCoverCallback? = null
// Save previous state of dual screens
private var prevDualScreenState = DisplayManagerHelper.STATE_UNMOUNT
private var isLGDualScreen: Boolean = false
private lateinit var mBaseWebContentsViewer : BaseWebContentsViewer
var lastInfo : LastInfo? = null
lateinit var paged_layer : PagedTextLayout
lateinit var textview_title : TextView
val handle = object : Handler() {
override fun handleMessage(msg: Message) {
// super.handleMessage(msg)
if (msg.what == 0 ) {
(msg.obj as? ReaderConfig)?.let {
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)
paged_layer?.forceUpdateUI()
}
}
@ -106,35 +95,16 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
setContentView(R.layout.intro)
mBaseWebContentsViewer = BaseWebContentsViewer(findViewById<WebView>(R.id.menu_web),this)
try {
// Try to construct the DisplayMangerHelper.
// If it isn't successful, this device isn't LG dual screens
displayManagerHelper = DisplayManagerHelper(applicationContext)
coverDisplayCallback = MainCoverDisplayCallback()
smartCoverCallback = MainSmartCoverCallback()
// Register the callbacks for covers
displayManagerHelper?.registerCoverDisplayEnabledCallback(
applicationContext.packageName,
coverDisplayCallback
)
displayManagerHelper?.registerSmartCoverCallback(smartCoverCallback)
isLGDualScreen = true
} catch (e: Exception) {
isLGDualScreen = false
Log.e(TAG, "This device isn't LG dual screens", e)
}
paged_layer =findViewById<PagedTextLayout>(R.id.paged_layer)
textview_title =findViewById<TextView>(R.id.textview_title)
findViewById<ImageButton>(R.id.btn_list).setOnClickListener { v ->
mBaseWebContentsViewer?.findListItem {result ->
if (result != null && "null".equals(result) == false && result?.length ?: 0 > 10) {
try {
Gson().fromJson(result, BookPageInfos::class.java)?.let{
showList(it)
}
} catch (e : Exception) {
}
mBaseWebContentsViewer?.webview?.url?.let {
Uri.parse(it).path?.let {
HistoryManager.getBooInfo(it, {
it?.let { showList(it) }
})
}
}
}
@ -142,8 +112,9 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
findViewById<View>(R.id.btn_rotate).setOnClickListener { v->
switcvhOrient()
}
findViewById<View>(R.id.btn_setting).setOnClickListener { v->
startActivity(Intent(this@Intro, Settings::class.java))
// startActivity(Intent(this@Intro, Settings::class.java))
}
findViewById<View>(R.id.btn_history).setOnClickListener { v->
var realm = openRealm()
@ -157,7 +128,7 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
findViewById<View>(R.id.btn_home).setOnClickListener { v->
paged_layer?.visibility = GONE
mBaseWebContentsViewer.loadContents(Booktoki)
mBaseWebContentsViewer.loadContents(Agit)
}
loadLastInfo()
@ -175,12 +146,51 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
}
}
override fun onBookInfos(jsonString: String) {
Blog.LOGE("onBookInfos" , "onBookInfos >> ${jsonString}")
val realm = openRealm()
var infos : BookPageInfos? = null
realm.writeBlocking {
try {
var infosj : BookPageInfosJ? = null
infosj = Gson().fromJson(jsonString, BookPageInfosJ::class.java)
Blog.LOGE("onBookInfos" , "onBookInfos 2 >> ${infosj}")
Blog.LOGE("onBookInfos" , "onBookInfos 2 - 1 >> ${infosj?.pages}")
// realm.createObjectFromJson
Blog.LOGE("onBookInfos" , "onBookInfos 2 - 1 >> ${infosj?.getR()}")
infos = infosj?.getR()
if (infos != null) {
infos = copyToRealm(infos!!, UpdatePolicy.ALL)
for (item in infosj.pages) {
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}")
}
} catch (e :Exception) {
e.printStackTrace()
}
}
realm.close()
infos?.let {
Blog.LOGE("onBookInfos" , "onBookInfos it >> ${it}")
showList(it)
}
}
fun reloadTo(lastInfo: LastInfo?) {
findViewById<WebView>(R.id.menu_web)?.postDelayed({
if (lastInfo != null) {
mBaseWebContentsViewer.loadLastInfo(lastInfo!!)
} else {
mBaseWebContentsViewer.loadContents(Booktoki)
mBaseWebContentsViewer.loadContents(Agit)
}
},200L)
}
@ -266,17 +276,17 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
}
fun showList(infos: BookPageInfos) {
DefaultList.showDefaultList(this@Intro,"현제는 ${currentTitle} - ${currentChapter} -> 다른화를 골라",infos.getTitleArray(),currentChapter, { position ->
return@showDefaultList infos.list?.get(position)?.title ?: ""
DefaultList.showDefaultList(this@Intro,"현제는 ${currentTitle} - ${currentChapter} -> 다른화를 골라",infos.getTitleArray().reversed(),currentChapter, { position ->
return@showDefaultList infos.pages?.get(position)?.chapterTitle ?: ""
},{position ->
infos.list?.get(position)?.let{moveTo(it)}
infos.pages?.reversed()?.get(position)?.let{moveTo(it)}
})
}
private fun moveTo(item: BookPageInfo?) {
item?.link?.let { newPath ->
item?.pathUrl?.let { newPath ->
mBaseWebContentsViewer?.webview?.url?.let { currentUrl ->
Uri.parse(currentUrl)?.lastPathSegment?.let {
Uri.parse(currentUrl)?.path?.let {
currentUrl.replace(it, newPath)?.let {
mBaseWebContentsViewer?.webview?.loadUrl(it)
}
@ -296,417 +306,357 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
// }
override fun onDestroy() {
// Remove all callbacks when this activity is destroyed
displayManagerHelper?.unregisterCoverDisplayEnabledCallback(applicationContext.packageName)
displayManagerHelper?.unregisterSmartCoverCallback(smartCoverCallback)
super.onDestroy()
}
override fun onDestroy() {
/**
* Convert cover display states to string to serve for logging
*
* @param state is the value integer of state
* @return a string for this state
*/
private fun coverDisplayStateToString(state: Int): String {
return when (state) {
DisplayManagerHelper.STATE_UNMOUNT -> "STATE_UNMOUNT"
DisplayManagerHelper.STATE_DISABLED -> "STATE_DISABLED"
DisplayManagerHelper.STATE_ENABLED -> "STATE_ENABLED"
else -> "UNKNOWN_STATE"
super.onDestroy()
}
var onNextClickAction: GotoSomeWhere? = null
override fun showNextBtn(find : Boolean , onClickAction: GotoSomeWhere) {
onNextClickAction = onClickAction
findViewById<AppCompatButton>(R.id.btn_right)?.let{
it.text = "다음 페이지"
it.setOnClickListener {
actionNextEvent()
}
it.visibility= if(find) VISIBLE else GONE
}
}
/**
* Convert smart cover display states to string to serve for logging
*
* @param state is the value integer of state
* @return a string for this state
*/
private fun smartCoverStateToString(state: Int): String {
return when (state) {
DisplayManagerHelper.STATE_COVER_OPENED -> "STATE_COVER_OPENED"
DisplayManagerHelper.STATE_COVER_CLOSED -> "STATE_COVER_CLOSED"
DisplayManagerHelper.STATE_COVER_FLIPPED_OVER -> "STATE_COVER_FLIPPED_OVER"
else -> "UNKNOWN_STATE"
}
}
/**
* Navigate to the second screen.
*
* See more at https://developer.android.com/guide/topics/ui/foldables?#using_secondary_screens
*/
private fun toSecondScreen(screenNumStr : String) {
var screenNum = screenNumStr.toInt()
// DisplayManager manages the properties of attached displays.
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
// List displays was attached
val displays = displayManager.displays
if (displays.size > screenNum) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Activity options are used to select the display screen.
val options = ActivityOptions.makeBasic()
// Select the display screen that you want to show the second activity
options.launchDisplayId = displays[screenNum].displayId
// To display on the second screen that your intent must be set flag to make
// single task (combine FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_NEW_TASK)
// or you also set it in the manifest (see more at the manifest file)
startActivity(
Intent(this@Intro, Main::class.java).apply {
},
options.toBundle()
)
}
} else {
Toast.makeText(this, "Not found the second screen", Toast.LENGTH_SHORT).show()
}
}
private inner class MainCoverDisplayCallback : DisplayManagerHelper.CoverDisplayCallback() {
override fun onCoverDisplayEnabledChangedCallback(state: Int) {
displayManagerHelper?.coverDisplayState?.let {
Log.i(TAG, "Current DualScreen Callback state: ${coverDisplayStateToString(it)}")
}
if (prevDualScreenState != state) {
when (state) {
DisplayManagerHelper.STATE_UNMOUNT -> {
Log.i(TAG, "Changed DualScreen State to STATE_UNMOUNT")
}
DisplayManagerHelper.STATE_DISABLED -> {
Log.i(TAG, "Changed DualScreen State to STATE_DISABLED")
}
DisplayManagerHelper.STATE_ENABLED -> {
// toSecondScreen()
Log.i(TAG, "Changed DualScreen State to STATE_ENABLED")
fun actionNextEvent() {
if (paged_layer != null && paged_layer!!.visibility == View.VISIBLE && paged_layer!!.size() > 0 && (paged_layer!!.current() < paged_layer!!.size() - 1) ) {
paged_layer!!.doNext()
updateLastInfo(paged_layer!!)
}else {
Uri.parse(mBaseWebContentsViewer.webview.url)?.let {
it.path?.let {
HistoryManager.getNextPage(it) {
Blog.LOGE("HistoryManager.getNextPage(${it})")
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(${Agit.getLastedDoamin()})")
mBaseWebContentsViewer.webview.loadUrl(Agit.getLastedDoamin() + it?.pathUrl!!)
paged_layer?.visibility = GONE
}
}
}
prevDualScreenState = state
}
}
// onNextClickAction?.let { it() }
}
}
private inner class MainSmartCoverCallback : DisplayManagerHelper.SmartCoverCallback() {
override fun onTypeChanged(type: Int) {
Log.i(TAG, "SmartCoverCallback type: ${displayManagerHelper?.coverType}")
var onPrevClickAction: GotoSomeWhere? = null
override fun showPrevBtn(find : Boolean, onClickAction: GotoSomeWhere) {
onPrevClickAction = onClickAction
findViewById<AppCompatButton>(R.id.btn_left)?.let{
it.text = "이전 페이지"
it.setOnClickListener {
actionPrevEvent()
}
it.visibility= if(find) VISIBLE else GONE
}
}
override fun onStateChanged(state: Int) {
displayManagerHelper?.coverState?.let {
Log.i(TAG, "Current SmartCoverCallback state: ${smartCoverStateToString(it)}")
}
when (state) {
DisplayManagerHelper.STATE_COVER_OPENED -> {
Log.i(TAG, "Received SmartCoverCallback is STATE_COVER_OPENED")
}
DisplayManagerHelper.STATE_COVER_CLOSED -> {
Log.i(TAG, "Received SmartCoverCallback is STATE_COVER_CLOSED")
}
DisplayManagerHelper.STATE_COVER_FLIPPED_OVER -> {
Log.i(TAG, "Received SmartCoverCallback is STATE_COVER_FLIPPED_OVER")
fun actionPrevEvent() {
if (paged_layer != null && paged_layer!!.visibility == View.VISIBLE && paged_layer!!.size() > 0 && paged_layer!!.current() > 0 ) {
paged_layer!!.doPrev()
updateLastInfo(paged_layer!!)
} else {
Uri.parse(mBaseWebContentsViewer.webview.url)?.let {
it.path?.let {
HistoryManager.getPrevPage(it) {
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(Agit.getLastedDoamin() + it?.pathUrl!!)
}
}
}
}
}
// onPrevClickAction?.let{ it() }
}
}
override fun onBackPressed() {
super.onBackPressed()
var layer = findViewById<PagedTextLayout>(R.id.paged_layer)
if (!didBackPress) {
firstBackPress()
return
}
var onNextClickAction: GotoSomeWhere? = null
override fun showNextBtn(find : Boolean , onClickAction: GotoSomeWhere) {
onNextClickAction = onClickAction
findViewById<AppCompatButton>(R.id.btn_right)?.let{
it.text = "다음 페이지"
it.setOnClickListener {
actionNextEvent()
}
it.visibility= if(find) VISIBLE else GONE
}
}
fun actionNextEvent() {
if (paged_layer != null && paged_layer!!.visibility == View.VISIBLE && paged_layer!!.size() > 0 && (paged_layer!!.current() < paged_layer!!.size() - 1) ) {
paged_layer!!.doNext()
updateLastInfo(paged_layer!!)
}else {
onNextClickAction?.let { it() }
}
}
var onPrevClickAction: GotoSomeWhere? = null
override fun showPrevBtn(find : Boolean, onClickAction: GotoSomeWhere) {
onPrevClickAction = onClickAction
findViewById<AppCompatButton>(R.id.btn_left)?.let{
it.text = "이전 페이지"
it.setOnClickListener {
actionPrevEvent()
}
it.visibility= if(find) VISIBLE else GONE
}
}
fun actionPrevEvent() {
if (paged_layer != null && paged_layer!!.visibility == View.VISIBLE && paged_layer!!.size() > 0 && paged_layer!!.current() > 0 ) {
paged_layer!!.doPrev()
updateLastInfo(paged_layer!!)
} else {
onPrevClickAction?.let{ it() }
}
}
override fun onBackPressed() {
var layer = findViewById<PagedTextLayout>(R.id.paged_layer)
if (!didBackPress) {
firstBackPress()
return
}
if (layer != null && layer.visibility == View.VISIBLE) {
didBackPress = false
layer.visibility = GONE
onTouch(TouchArea.Center)
return
}
if (mBaseWebContentsViewer.webview.canGoBack()) {
mBaseWebContentsViewer.webview.goBack()
return
}
if (!didBackPress) {
firstBackPress()
return
}
finish()
if (layer != null && layer.visibility == View.VISIBLE) {
didBackPress = false
layer.visibility = GONE
onTouch(TouchArea.Center)
return
}
override fun showAlert(alert: String) {
Log.i(TAG,"showAlert >> " + alert)
if (mBaseWebContentsViewer.webview.canGoBack()) {
mBaseWebContentsViewer.webview.goBack()
return
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onLoadedContents(contents: String) {
paged_layer.apply {
if (contents != null) {
visibility = VISIBLE
mPagedTextViewInterface = this@Intro
var realm = HistoryManager.openRealm()
realm.query<ReaderConfig>()?.find()?.let {
if (it.size > 0) {
realm.copyFromRealm(it.first())?.let {
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)
if (!didBackPress) {
firstBackPress()
return
}
finish()
didBackPress = false
}
var typeface = typesfacez.get(getIndex(typesfacez as PairArray<Any>,it.font ?: ""))
paged_layer?.setTypeface(resources.getFont(typeface.second))
val color = colorz.get(it.style ?: 0)
paged_layer?.setColorStyle(color.second)
}
override fun showAlert(alert: String) {
Log.i(TAG,"showAlert >> " + alert)
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onLoadedContents(aContents: String) {
paged_layer.apply {
if (aContents != null) {
var contents = aContents.replace("\\\"","\"")
visibility = VISIBLE
mPagedTextViewInterface = this@Intro
var realm = HistoryManager.openRealm()
realm.query<ReaderConfig>()?.find()?.let {
if (it.size > 0) {
realm.copyFromRealm(it.first())?.let {
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 ?: ""))
paged_layer?.setTypeface(resources.getFont(typeface.second))
val color = colorz.get(it.style ?: 0)
paged_layer?.setColorStyle(color.second)
}
}
realm.close()
}
realm.close()
setText(contents.replace("\\n", System.getProperty("line.separator")))
if(lastInfo != null && lastInfo!!.pageUrl.equals(mBaseWebContentsViewer.webview.url)) {
this@Intro.findViewById<ProgressBar>(R.id.progress)?.visibility = VISIBLE
paged_layer?.postDelayed({
next(lastInfo!!.pageIndex)
paged_layer?.post {
this@Intro.findViewById<ProgressBar>(R.id.progress)?.visibility = GONE
text = (contents.replace("\\n", System.getProperty("line.separator")))
if(lastInfo != null && lastInfo!!.pageUrl.equals(mBaseWebContentsViewer.webview.url)) {
this@Intro.findViewById<ProgressBar>(R.id.progress)?.visibility = VISIBLE
paged_layer?.postDelayed({
next(lastInfo!!.pageIndex)
paged_layer?.post {
this@Intro.findViewById<ProgressBar>(R.id.progress)?.visibility = GONE
}
},1000)
}
forceUpdateUI()
HistoryManager.getBooPageInfo(mBaseWebContentsViewer.webview.url!!){
HistoryManager.openRealm().apply {
this.writeBlocking {
it?.contents = contents
if (it != null) {
copyToRealm(it, UpdatePolicy.ALL)
}
},1000)
}
forceUpdateUI()
}
}.close()
HistoryManager.save(historyItem = HistoryItem().putHistory(it,mBaseWebContentsViewer.webview.url!!))
}
}
Log.i(TAG,"onLoadedContents >> " + contents)
}
Log.i(TAG,"onLoadedContents >> " + aContents)
}
var currentTitle : String = ""
var currentChapter : Int = 0
var currentTitle : String = ""
var currentChapter : Int = 0
override fun onFindTitle(contents: String) {
textview_title.text = contents
textview_title.setOnClickListener {
val builder = AlertDialog.Builder(this)
builder.setTitle("Title")
val input = EditText(this)
input.setText(mBaseWebContentsViewer?.webview?.url ?: "")
input.inputType = InputType.TYPE_CLASS_TEXT
builder.setView(input)
builder.setPositiveButton(
"OK"
) { dialog, which ->
var m_Text = input.text.toString()
mBaseWebContentsViewer?.webview?.loadUrl(m_Text.trim())
}
builder.setNegativeButton(
"Cancel"
) { dialog, which -> dialog.cancel() }
builder.show()
override fun onFindTitle(contents: String) {
textview_title.text = contents
textview_title.setOnClickListener {
val builder = AlertDialog.Builder(this)
builder.setTitle("Title")
val input = EditText(this)
input.setText(mBaseWebContentsViewer?.webview?.url ?: "")
input.inputType = InputType.TYPE_CLASS_TEXT
builder.setView(input)
builder.setPositiveButton(
"OK"
) { dialog, which ->
var m_Text = input.text.toString()
mBaseWebContentsViewer?.webview?.loadUrl(m_Text.trim())
}
var testRegex = """[^0-9]""".toRegex();
Blog.LOGI(TAG,"onFindTitle >> " + contents + " ::: ${testRegex.replace(contents,"")}")
if(contents.contains("-")) {
currentTitle = contents.split("-")[0]
try {
currentChapter = testRegex.replace(contents.split("-")[1],"").toInt()
} catch (e : Exception) {
currentChapter = 0
}
} else if(testRegex.replace(contents,"").length > 0){
currentChapter = testRegex.replace(contents,"").toInt()
currentTitle = contents.split(testRegex.replace(contents,""))[0]
} else {
val dateFormat = "yyyyMMdd-HH"
val date = Date(currentTimeMillis())
val simpleDateFormat = SimpleDateFormat(dateFormat)
currentTitle = simpleDateFormat.format(date)
builder.setNegativeButton(
"Cancel"
) { dialog, which -> dialog.cancel() }
builder.show()
}
var testRegex = """[^0-9]""".toRegex();
Blog.LOGI(TAG,"onFindTitle >> " + contents + " ::: ${testRegex.replace(contents,"")}")
if(contents.contains("-")) {
currentTitle = contents.split("-")[0]
try {
currentChapter = testRegex.replace(contents.split("-")[1],"").toInt()
} catch (e : Exception) {
currentChapter = 0
}
} else if(testRegex.replace(contents,"").length > 0){
currentChapter = testRegex.replace(contents,"").toInt()
currentTitle = contents.split(testRegex.replace(contents,""))[0]
} else {
val dateFormat = "yyyyMMdd-HH"
val date = Date(currentTimeMillis())
val simpleDateFormat = SimpleDateFormat(dateFormat)
currentTitle = simpleDateFormat.format(date)
}
override fun onStartLoad() {
findViewById<ProgressBar>(R.id.progress).visibility = VISIBLE
}
override fun onStartLoad() {
findViewById<ProgressBar>(R.id.progress).visibility = VISIBLE
}
override fun completePageLoad(lastInfo: LastInfo) {
val configuration: Configuration = getResources().getConfiguration()
if(this.lastInfo == null || !(this.lastInfo?.pageUrl.equals(lastInfo?.pageUrl)) || this.lastInfo?.displayOrientation != configuration?.orientation) {
lastInfo.displayOrientation = configuration?.orientation ?: ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
saveLastInfo(lastInfo)
}
findViewById<ProgressBar>(R.id.progress).visibility = GONE
}
override fun completePageLoad(lastInfo: LastInfo) {
val configuration: Configuration = getResources().getConfiguration()
if(this.lastInfo == null || !(this.lastInfo?.pageUrl.equals(lastInfo?.pageUrl)) || this.lastInfo?.displayOrientation != configuration?.orientation) {
lastInfo.displayOrientation = configuration?.orientation ?: ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
saveLastInfo(lastInfo)
}
findViewById<ProgressBar>(R.id.progress).visibility = GONE
}
fun saveLastInfo(lastInfo: LastInfo) {
val realm = openRealm()
if((realm.query<LastInfo>()?.count()?.find() ?: 0) > 0) {
realm.writeBlocking {
this.query<LastInfo>()?.find()?.last()?.let{
it.pageUrl = lastInfo.pageUrl
it.title = currentTitle
it.chapter = currentChapter
it.pageIndex = lastInfo.pageIndex
it.contentsName = lastInfo.contentsName
it.displayOrientation = lastInfo.displayOrientation
this@Intro.lastInfo = copyFromRealm(it)
}
}
} else {
realm.writeBlocking {
copyToRealm(lastInfo)
}
}
Blog.LOGD(log ="Successfully opened realm: ${realm.configuration.name}")
realm.close()
}
fun updateLastInfo(pagedTextLayout: PagedTextLayout) {
val configuration: Configuration = getResources().getConfiguration()
val realm = openRealm()
fun saveLastInfo(lastInfo: LastInfo) {
val realm = openRealm()
if((realm.query<LastInfo>()?.count()?.find() ?: 0) > 0) {
realm.writeBlocking {
this.query<LastInfo>()?.find()?.last()?.let{
it.displayOrientation = configuration.orientation
it.pageUrl = lastInfo.pageUrl
it.title = currentTitle
it.chapter = currentChapter
it.pageIndex = pagedTextLayout.current()
it.pageIndex = lastInfo.pageIndex
it.contentsName = lastInfo.contentsName
it.displayOrientation = lastInfo.displayOrientation
this@Intro.lastInfo = copyFromRealm(it)
}
if (currentTitle.length > 0 && currentChapter > 0) {
this@Intro.lastInfo?.makeHistoryItem()?.let{
copyToRealm(it, UpdatePolicy.ALL)
}
}
} else {
realm.writeBlocking {
copyToRealm(lastInfo)
}
}
Blog.LOGD(log ="Successfully opened realm: ${realm.configuration.name}")
realm.close()
}
fun updateLastInfo(pagedTextLayout: PagedTextLayout) {
val configuration: Configuration = getResources().getConfiguration()
val realm = openRealm()
realm.writeBlocking {
this.query<LastInfo>()?.find()?.last()?.let{
it.displayOrientation = configuration.orientation
it.title = currentTitle
it.chapter = currentChapter
it.pageIndex = pagedTextLayout.current()
this@Intro.lastInfo = copyFromRealm(it)
}
if (currentTitle.length > 0 && currentChapter > 0) {
this@Intro.lastInfo?.makeHistoryItem()?.let{
copyToRealm(it, UpdatePolicy.ALL)
}
}
Blog.LOGD(log ="Successfully opened realm: ${realm.configuration.name}")
realm.close()
}
override fun onKeyClick(keyCode: Int): Boolean {
when(keyCode) {
KeyEvent.KEYCODE_VOLUME_DOWN ->{actionNextEvent()}
KeyEvent.KEYCODE_VOLUME_UP ->{actionPrevEvent()}
KeyEvent.KEYCODE_VOLUME_MUTE -> {actionNextEvent()}
Blog.LOGD(log ="Successfully opened realm: ${realm.configuration.name}")
realm.close()
}
override fun onKeyClick(keyCode: Int): Boolean {
when(keyCode) {
KeyEvent.KEYCODE_VOLUME_DOWN ->{actionNextEvent()}
KeyEvent.KEYCODE_VOLUME_UP ->{actionPrevEvent()}
KeyEvent.KEYCODE_VOLUME_MUTE -> {actionNextEvent()}
}
return super.onKeyClick(keyCode)
}
override fun onTouch(touchArea: TouchArea) {
Blog.LOGD(log="onTouch")
when (touchArea) {
TouchArea.Center-> {
findViewById<View>(R.id.btn_right).visibility = VISIBLE
findViewById<View>(R.id.btn_left).visibility = VISIBLE
findViewById<View>(R.id.btn_setting).visibility = VISIBLE
textview_title.visibility = VISIBLE
findViewById<View>(R.id.btn_home).visibility = VISIBLE
findViewById<View>(R.id.btn_list).visibility = VISIBLE
findViewById<View>(R.id.btn_history).visibility = VISIBLE
findViewById<View>(R.id.btn_rotate).visibility = VISIBLE
}
return super.onKeyClick(keyCode)
}
override fun onTouch(touchArea: TouchArea) {
Blog.LOGD(log="onTouch")
when (touchArea) {
TouchArea.Center-> {
findViewById<View>(R.id.btn_right).visibility = VISIBLE
findViewById<View>(R.id.btn_left).visibility = VISIBLE
findViewById<View>(R.id.btn_setting).visibility = VISIBLE
textview_title.visibility = VISIBLE
findViewById<View>(R.id.btn_home).visibility = VISIBLE
findViewById<View>(R.id.btn_list).visibility = VISIBLE
findViewById<View>(R.id.btn_history).visibility = VISIBLE
findViewById<View>(R.id.btn_rotate).visibility = VISIBLE
}
TouchArea.Right -> {
actionNextEvent()
}
TouchArea.Left-> {
actionPrevEvent()
}
else -> {
}
TouchArea.Right -> {
actionNextEvent()
}
TouchArea.Left-> {
actionPrevEvent()
}
else -> {
}
override fun onSwipeLeft() {
Blog.LOGD(log="onSwipeLeft")
actionNextEvent()
}
override fun onSwipeRight() {
Blog.LOGD(log="onSwipeRight")
actionPrevEvent()
}
}
override fun onTimeoverTouch() {
Blog.LOGD(log="onTimeoverTouch")
findViewById<View>(R.id.btn_right).visibility = GONE
findViewById<View>(R.id.btn_left).visibility = GONE
findViewById<View>(R.id.btn_setting).visibility = GONE
textview_title.visibility = GONE
findViewById<View>(R.id.btn_home).visibility = GONE
findViewById<View>(R.id.btn_list).visibility = GONE
findViewById<View>(R.id.btn_history).visibility = GONE
findViewById<View>(R.id.btn_rotate).visibility = GONE
}
override fun onLongClick() {
Blog.LOGD(log="onLongClick")
if (paged_layer?.visibility == VISIBLE) {
paged_layer?.visibility = GONE
}
}
override fun onSwipeLeft() {
Blog.LOGD(log="onSwipeLeft")
actionNextEvent()
companion object {
private const val TAG = "DualScreenStatus"
}
}
}
override fun onSwipeRight() {
Blog.LOGD(log="onSwipeRight")
actionPrevEvent()
}
override fun onTimeoverTouch() {
Blog.LOGD(log="onTimeoverTouch")
findViewById<View>(R.id.btn_right).visibility = GONE
findViewById<View>(R.id.btn_left).visibility = GONE
findViewById<View>(R.id.btn_setting).visibility = GONE
textview_title.visibility = GONE
findViewById<View>(R.id.btn_home).visibility = GONE
findViewById<View>(R.id.btn_list).visibility = GONE
findViewById<View>(R.id.btn_history).visibility = GONE
findViewById<View>(R.id.btn_rotate).visibility = GONE
}
companion object {
private const val TAG = "DualScreenStatus"
}
}

View File

@ -1,128 +1,128 @@
package com.mime.dualscreenview.activity
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import androidx.annotation.RequiresApi
import com.mime.dualscreenview.R
import com.mime.dualscreenview.common.PairArray
import com.mime.dualscreenview.common.colorz
import com.mime.dualscreenview.common.getIndex
import com.mime.dualscreenview.common.typesfacez
import com.mime.dualscreenview.data.HistoryManager
import com.mime.dualscreenview.data.model.ReaderConfig
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
import kotlinx.android.synthetic.main.settings.letter_space
import kotlinx.android.synthetic.main.settings.line_space
import kotlinx.android.synthetic.main.settings.page_padding
import kotlinx.android.synthetic.main.settings.page_style
import kotlinx.android.synthetic.main.settings.page_typesface
import kotlinx.android.synthetic.main.settings.preview
import kotlinx.android.synthetic.main.settings.text_size
class Settings : Base() {
var readerConfig : ReaderConfig? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.settings)
var realm = HistoryManager.openRealm()
realm.writeBlocking {
this.query<ReaderConfig>()?.find()?.let {
if (it.size > 0) {
readerConfig = copyFromRealm(it.first())
} else {
readerConfig = ReaderConfig()
}
}
}
realm.close()
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onResume() {
super.onResume()
text_size.displayFormat = "글자 크기 : %d"
text_size.value = readerConfig?.textSize ?: 14
text_size.mValueChange = {
preview.textSize = it.toFloat() ;
if (readerConfig?.textSize != it) {
readerConfig?.textSize = it
configSave()
}
}
page_padding.displayFormat = "페이지 여백 : %d"
page_padding.value = readerConfig?.padding ?: 5
page_padding.mValueChange = {
preview.setPadding(it,it,it,it) ;
if (readerConfig?.padding != it) {
readerConfig?.padding = it
configSave()
}
}
letter_space.displayFormat = "자간 : %d"
letter_space.value = readerConfig?.letterSpace ?: 1
letter_space.mValueChange = {
preview.letterSpacing = it.times(0.01).toFloat() ;
if (readerConfig?.letterSpace != it) {
readerConfig?.letterSpace = it
configSave()
}
}
line_space.displayFormat = "행간 : %d"
line_space.value = readerConfig?.lineSpace ?: 1
line_space.mValueChange = {
preview.setLineSpacing(1f, 1f.plus(it.times(0.01f))) ;
if (readerConfig?.lineSpace != it) {
readerConfig?.lineSpace = it
configSave()
}
}
page_typesface.displayFormat = "폰트 : %s"
page_typesface.titleArray = typesfacez.map { it.first }.toTypedArray()
page_typesface.value = getIndex(typesfacez as PairArray<Any>,readerConfig?.font ?: "")
page_typesface.mValueChange = {
val pair = typesfacez.get(it)
preview.setTypeface(resources.getFont(pair.second))
if (readerConfig?.font != pair.first) {
readerConfig?.font = pair.first ?: ""
configSave()
}
}
page_style.displayFormat = "스타일 : %s"
page_style.titleArray = colorz.map { it.first }.toTypedArray()
page_style.value = readerConfig?.style ?: 0
page_style.mValueChange = {
val pair = colorz.get(it)
preview.setBackgroundColor(Color.parseColor(pair.second.last()))
preview.setTextColor(Color.parseColor(pair.second.first()))
if (readerConfig?.style != it) {
readerConfig?.style = it ?: 0
configSave()
}
}
}
fun configSave() {
var realm = HistoryManager.openRealm()
realm.writeBlocking {
copyToRealm(readerConfig!!, UpdatePolicy.ALL)
}
realm.close()
}
}
//package com.mime.dualscreenview.activity
//
//import android.graphics.Color
//import android.os.Build
//import android.os.Bundle
//import androidx.annotation.RequiresApi
//import com.mime.dualscreenview.R
//import com.mime.dualscreenview.common.PairArray
//import com.mime.dualscreenview.common.colorz
//import com.mime.dualscreenview.common.getIndex
//import com.mime.dualscreenview.common.typesfacez
//import com.mime.dualscreenview.data.HistoryManager
//import com.mime.dualscreenview.data.model.ReaderConfig
//import io.realm.kotlin.UpdatePolicy
//import io.realm.kotlin.ext.query
//import kotlinx.android.synthetic.main.settings.letter_space
//import kotlinx.android.synthetic.main.settings.line_space
//import kotlinx.android.synthetic.main.settings.page_padding
//import kotlinx.android.synthetic.main.settings.page_style
//import kotlinx.android.synthetic.main.settings.page_typesface
//import kotlinx.android.synthetic.main.settings.preview
//import kotlinx.android.synthetic.main.settings.text_size
//
//class Settings : Base() {
//
// var readerConfig : ReaderConfig? = null
// override fun onCreate(savedInstanceState: Bundle?) {
// super.onCreate(savedInstanceState)
// setContentView(R.layout.settings)
// var realm = HistoryManager.openRealm()
// realm.writeBlocking {
// this.query<ReaderConfig>()?.find()?.let {
// if (it.size > 0) {
// readerConfig = copyFromRealm(it.first())
// } else {
// readerConfig = ReaderConfig()
// }
// }
//
// }
// realm.close()
// }
//
// @RequiresApi(Build.VERSION_CODES.O)
// override fun onResume() {
// super.onResume()
// text_size.displayFormat = "글자 크기 : %d"
// text_size.value = readerConfig?.textSize ?: 14
// text_size.mValueChange = {
// preview.textSize = it.toFloat() ;
// if (readerConfig?.textSize != it) {
// readerConfig?.textSize = it
// configSave()
// }
// }
//
//
// page_padding.displayFormat = "페이지 여백 : %d"
// page_padding.value = readerConfig?.padding ?: 5
// page_padding.mValueChange = {
// preview.setPadding(it,it,it,it) ;
// if (readerConfig?.padding != it) {
// readerConfig?.padding = it
// configSave()
// }
// }
//
//
// letter_space.displayFormat = "자간 : %d"
// letter_space.value = readerConfig?.letterSpace ?: 1
// letter_space.mValueChange = {
// preview.letterSpacing = it.times(0.01).toFloat() ;
// if (readerConfig?.letterSpace != it) {
// readerConfig?.letterSpace = it
// configSave()
// }
// }
//
//
// line_space.displayFormat = "행간 : %d"
// line_space.value = readerConfig?.lineSpace ?: 1
// line_space.mValueChange = {
// preview.setLineSpacing(1f, 1f.plus(it.times(0.01f))) ;
// if (readerConfig?.lineSpace != it) {
// readerConfig?.lineSpace = it
// configSave()
// }
// }
//
//
//
// page_typesface.displayFormat = "폰트 : %s"
// page_typesface.titleArray = typesfacez.map { it.first }.toTypedArray()
// page_typesface.value = getIndex(typesfacez as PairArray<Any>,readerConfig?.font ?: "")
// page_typesface.mValueChange = {
// val pair = typesfacez.get(it)
// preview.setTypeface(resources.getFont(pair.second))
// if (readerConfig?.font != pair.first) {
// readerConfig?.font = pair.first ?: ""
// configSave()
// }
// }
//
// page_style.displayFormat = "스타일 : %s"
// page_style.titleArray = colorz.map { it.first }.toTypedArray()
// page_style.value = readerConfig?.style ?: 0
// page_style.mValueChange = {
// val pair = colorz.get(it)
// preview.setBackgroundColor(Color.parseColor(pair.second.last()))
// preview.setTextColor(Color.parseColor(pair.second.first()))
// if (readerConfig?.style != it) {
// readerConfig?.style = it ?: 0
// configSave()
// }
// }
//
// }
//
//
//
// fun configSave() {
// var realm = HistoryManager.openRealm()
// realm.writeBlocking {
// copyToRealm(readerConfig!!, UpdatePolicy.ALL)
// }
// realm.close()
// }
//}

View File

@ -31,6 +31,10 @@ object Blog {
LOG(BLogType.E,tag,log)
}
fun LOGE(log: String){
LOG(BLogType.E,DEFAULT_TAG,log)
}
private fun LOG(type : BLogType, tag : String, log : String) {
if (BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.contains("debug")) {
when(type) {

View File

@ -1,20 +1,27 @@
package com.mime.dualscreenview.data
import com.mime.dualscreenview.common.Blog
import com.mime.dualscreenview.data.model.BookPageInfo
import com.mime.dualscreenview.data.model.BookPageInfos
import com.mime.dualscreenview.data.model.HistoryItem
import com.mime.dualscreenview.data.model.LastInfo
import com.mime.dualscreenview.data.model.ReaderConfig
import io.realm.kotlin.Realm
import io.realm.kotlin.RealmConfiguration
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.log.LogLevel
import io.realm.kotlin.types.BaseRealmObject
import io.realm.kotlin.types.TypedRealmObject
import kotlin.reflect.KClass
object HistoryManager {
val clazz : Set<KClass<out BaseRealmObject>> = setOf(LastInfo::class, HistoryItem::class, ReaderConfig::class)
val schemaVersion : Long = 3
val clazz : Set<KClass<out BaseRealmObject>> = setOf(LastInfo::class, HistoryItem::class, ReaderConfig::class, BookPageInfos::class, BookPageInfo::class)
val schemaVersion : Long = 5
fun openRealm() : Realm = Realm.open(RealmConfiguration.Builder(clazz)
fun openRealm() : Realm = Realm.open(RealmConfiguration.Builder(clazz as Set<KClass<out TypedRealmObject>>)
.schemaVersion(schemaVersion)
.log(LogLevel.ALL)
// .deleteRealmIfMigrationNeeded()
.build())
fun save(lastInfo: LastInfo) {
@ -46,4 +53,76 @@ object HistoryManager {
}
}?.close()
}
fun getBooInfo(url : String ,callback : (BookPageInfos?)->Unit) {
openRealm()?.apply{
Blog.LOGE("get ${url}" )
Blog.LOGE("get ${this.query(BookPageInfo::class).count().find()}" )
var bookPageInfo = this.query(BookPageInfo::class).query("pathUrl == $0","${url}").find().first()
if (bookPageInfo != null) {
Blog.LOGE("get ${bookPageInfo}" )
this.query(BookPageInfos::class,"bookPageUrl == $0",bookPageInfo.bookPageUrl).find().first().let {
Blog.LOGE("get ${it} , ${it?.pages}" )
callback.invoke(this.copyFromRealm(it))
}
}
}?.close()
}
fun getBooPageInfo(url : String ,callback : (BookPageInfo?)->Unit) {
openRealm()?.apply{
Blog.LOGE("get ${url}" )
Blog.LOGE("get ${this.query(BookPageInfo::class).count().find()}" )
var result = this.query(BookPageInfo::class).query("pathUrl == $0","${url}").find()
if (result.size > 0) {
var bookPageInfo = result?.first()
if (bookPageInfo != null) {
callback.invoke(this.copyFromRealm(bookPageInfo))
}
}
}?.close()
}
fun getNextPage(url : String ,callback : (BookPageInfo?)->Unit) {
openRealm()?.apply{
Blog.LOGE("getNextPage ${url}" )
Blog.LOGE("getNextPage ${this.query(BookPageInfo::class).count().find()}" )
var bookPageInfo = this.query(BookPageInfo::class).query("pathUrl == $0","${url}").find()?.first()
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)
}
}
}
}?.close()
}
fun getPrevPage(url : String ,callback : (BookPageInfo?)->Unit) {
openRealm()?.apply{
Blog.LOGE("getPrevPage ${url}" )
Blog.LOGE("getPrevPage ${this.query(BookPageInfo::class).count().find()}" )
var bookPageInfo = this.query(BookPageInfo::class).query("pathUrl == $0","${url}").find()?.first()
Blog.LOGE("getNextPage ${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 && bookPageUrl == $1",bookPageInfo.chapterNum + 1,"${bookPageInfo.bookPageUrl}").find()
if(results.size > 0) {
results.first()?.let {
callback.invoke(it)
}
}
}
}?.close()
}
}

View File

@ -1,15 +1,89 @@
package com.mime.dualscreenview.data.model
import com.mime.dualscreenview.common.Blog
import io.realm.kotlin.ext.realmListOf
import io.realm.kotlin.types.RealmList
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.RealmSet
import io.realm.kotlin.types.annotations.PrimaryKey
class BookPageInfos {
var list : ArrayList<BookPageInfo>? = null
class BookPageInfosJ : RealmObject {
var bookTitle : String = ""
var bookPageUrl : String = ""
var pages : ArrayList<BookPageInfoJ> = arrayListOf<BookPageInfoJ>()
fun getTitleArray() : ArrayList<String> {
var arrayList = ArrayList<String>()
list?.forEach { arrayList.add(it.title ?: "") }
pages?.forEach { arrayList.add(it.bookTitle ?: "") }
return arrayList
}
fun getR() : BookPageInfos{
var r = BookPageInfos()
r.bookTitle = this.bookTitle
r.bookPageUrl = this.bookPageUrl
// for (item in this.pages) {
//// Blog.LOGE("item >>> ${item}")
// r.pages.add(item.getRealm())
// }
return r
}
}
class BookPageInfo {
var title : String? = ""
var link : String? = ""
class BookPageInfoJ : RealmObject {
var chapterID : Int = 0
var contents : String? = ""
var bookPageUrl : String? = ""
var chapterTitle : String? = ""
var bookTitle : String? = ""
var chapterNum : Int = 0
var lastPage : Int? = 0
var pathUrl : String? = ""
fun getRealm() : BookPageInfo {
var r = BookPageInfo()
r.chapterID = this.chapterID
r.contents = this.contents
r.bookPageUrl = this.bookPageUrl ?: ""
r.chapterTitle = this.chapterTitle
r.bookTitle = this.bookTitle ?: ""
r.chapterNum = this.chapterNum
r.lastPage = this.lastPage
r.pathUrl = this.pathUrl?.replace("'","")
return r
}
}
class BookPageInfos : RealmObject {
var bookTitle : String = ""
@PrimaryKey
var bookPageUrl : String? = ""
var pages : RealmList<BookPageInfo> = realmListOf()
fun getTitleArray() : ArrayList<String> {
var arrayList = ArrayList<String>()
pages?.forEach {
Blog.LOGE("chapterTitle >> ${it.chapterTitle} ")
arrayList.add(it.chapterTitle ?: "") }
return arrayList
}
}
class BookPageInfo : RealmObject {
var chapterID : Int = 0
var contents : String? = ""
var bookPageUrl : String? = ""
var chapterTitle : String? = ""
var bookTitle : String? = ""
var chapterNum : Int = 0
var lastPage : Int? = 0
@PrimaryKey
var pathUrl : String? = ""
}

View File

@ -3,6 +3,8 @@ package com.mime.dualscreenview.data.model
import android.content.pm.ActivityInfo
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.PrimaryKey
import java.text.SimpleDateFormat
import java.util.Date
class LastInfo() : RealmObject {
@ -42,6 +44,14 @@ class HistoryItem() : RealmObject {
contentsName = this@HistoryItem.contentsName
displayOrientation = this@HistoryItem.displayOrientation
}
fun putHistory(bookPageInfo: BookPageInfo? , currentPath : String) : HistoryItem {
title = bookPageInfo?.bookTitle ?: SimpleDateFormat("YY-mm-DD-HH:mm").format(Date())
pageUrl = bookPageInfo?.pathUrl ?: ""
chapter = bookPageInfo?.chapterNum ?: 0
pageIndex = bookPageInfo?.lastPage ?: 0
contentsName = bookPageInfo?.chapterTitle ?: ""
return this
}
}
class Bookmark() : RealmObject {
@PrimaryKey

View File

@ -15,7 +15,6 @@ object DefaultList {
arrayAdapter.addAll(items)
builderSingle.setNegativeButton("닫기",
DialogInterface.OnClickListener { dialog, which -> dialog.dismiss() })
builderSingle.setAdapter(arrayAdapter,
DialogInterface.OnClickListener { dialog, position ->
val strName = arrayAdapter.getItem(position)

View File

@ -18,6 +18,8 @@ abstract class OnSwipeTouchListener(val context: Context?) : View.OnTouchListene
private val gestureDetector: GestureDetector
abstract fun onSwipeLeft()
abstract fun onSwipeRight()
abstract fun onSwipeDown()
abstract fun onSwipeUp()
abstract fun onSingleTap(area : TouchArea)
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
@ -34,6 +36,7 @@ abstract class OnSwipeTouchListener(val context: Context?) : View.OnTouchListene
return true
}
override fun onSingleTapUp(e: MotionEvent): Boolean {
val width: Int = context?.resources?.displayMetrics?.widthPixels ?: 0
val height: Int = context?.resources?.displayMetrics?.heightPixels ?: 0
@ -53,14 +56,27 @@ abstract class OnSwipeTouchListener(val context: Context?) : View.OnTouchListene
return super.onSingleTapUp(e)
}
override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
val distanceX = e2.x - e1.x
val distanceY = e2.y - e1.y
override fun onFling(
e1: MotionEvent,
e2: MotionEvent,
velocityX: Float,
velocityY: Float
): Boolean {
val distanceX = e2.x - (e1?.x ?: 0f)
val distanceY = e2.y - (e1?.y ?: 0f)
if (Math.abs(distanceX) > Math.abs(distanceY)
&& Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD
&& Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (distanceX > 0) onSwipeRight() else onSwipeLeft()
return true
} else if (Math.abs(distanceY) > Math.abs(distanceX)
&& Math.abs(distanceY) > SWIPE_DISTANCE_THRESHOLD
&& Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (distanceY > 0) onSwipeDown() else onSwipeUp()
return true
} else {
}
return false
}

View File

@ -7,6 +7,7 @@ import android.graphics.Typeface
import android.os.Build
import android.os.Handler
import android.util.AttributeSet
import android.view.View
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.Guideline
@ -32,14 +33,18 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
) : super(context, attrs, defStyleAttr, defStyleRes) {initView(context)}
var mainTextView : TextView? = null
var sencondTextView : TextView? = null
var demp : View? = null
var hiddenTextView : PagedTextView? = null
var guideLine : Guideline? = null
var pageList: ArrayList<CharSequence>? = null
var text : String = ""
set(new) {
Blog.LOGE("field >> ${field}")
Blog.LOGE("new >> ${new}")
field = new
hiddenTextView?.text = text
hiddenTextView?.forceLayout()
Blog.LOGE("field >> ${field}")
hiddenTextView?.setTxtF(field)
hiddenTextView?.visibility = VISIBLE
}
private val hanler = Handler()
@ -52,11 +57,23 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
inflate(context, R.layout.layout_textviewer, this)
mainTextView = findViewById(R.id.first_view)
sencondTextView = findViewById(R.id.sencond_view)
demp = findViewById(R.id.demp)
hiddenTextView = findViewById(R.id.hidden_view)
guideLine = findViewById(R.id.center_guide)
hiddenTextView?.mPagedTextGenerateInterface = this
hanler.removeCallbacks(touchTimeover)
setOnLongClickListener { v ->
mPagedTextViewInterface?.onLongClick()
return@setOnLongClickListener false
}
setOnTouchListener(object : OnSwipeTouchListener(context) {
override fun onSwipeUp() {
mPagedTextViewInterface?.onLongClick()
}
override fun onSwipeDown() {
mPagedTextViewInterface?.onLongClick()
}
override fun onSwipeLeft() {
mPagedTextViewInterface?.onSwipeLeft()
}
@ -74,26 +91,25 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
mPagedTextViewInterface?.onTouch(touchArea)
}
}
})
}
fun layoutChange(needDualPage: Boolean) {
Blog.LOGD(log = "layoutChange>> ${this::class.java.name}")
if (needDualPage) {
findViewById<Guideline>(R.id.center_guide).updateLayoutParams<ConstraintLayout.LayoutParams> {
guidePercent = 0.5f
}
sencondTextView?.visibility = VISIBLE
demp?.visibility = VISIBLE
} else {
findViewById<Guideline>(R.id.center_guide).updateLayoutParams<ConstraintLayout.LayoutParams> {
guidePercent = 1f
}
sencondTextView?.visibility = GONE
demp?.visibility = GONE
}
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
Blog.LOGD(log = "onLayout>> ${this::class.java.name} changed >> ${changed}")
if(!changed) {
if(changed) {
hiddenTextView?.text = text
forceUpdateUI()
}
@ -121,6 +137,7 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
this.pageList = pageList
setPageBy(0)
}
hiddenTextView?.visibility = GONE
}
fun setColorStyle(colors : Array<String>) {
@ -132,7 +149,8 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
}
// fun setPagedTextViewInterface(pagedTextViewInterface: PagedTextViewInterface) = hiddenTextView?.setPagedTextViewInterface(pagedTextViewInterface)
fun setText(replace: String) = hiddenTextView?.setText(replace)
// fun setText(replace: String) = hiddenTextView?.setText(replace)
fun setTextSize(fl: Float) {
hiddenTextView?.setTextSize(fl)
mainTextView?.setTextSize(fl)
@ -144,7 +162,7 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
}
fun isDualPage() : Boolean {
return (guideLine?.layoutParams as ConstraintLayout.LayoutParams).guidePercent != 1f
return sencondTextView?.visibility == VISIBLE
}
fun setPageBy(num : Int) {
@ -189,7 +207,7 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun setLetterSpacing(letterSpacing: Float) {
fun setLetterSpacing(letterSpacing: Float) {
hiddenTextView?.letterSpacing = letterSpacing.times(0.01f)
mainTextView?.letterSpacing = letterSpacing.times(0.01f)
sencondTextView?.letterSpacing = letterSpacing.times(0.01f)

View File

@ -9,6 +9,8 @@ import android.text.StaticLayout
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
import com.mime.dualscreenview.common.Blog
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlin.math.min
@ -60,13 +62,21 @@ class PagedTextView : AppCompatTextView {
}
private fun setPageText() {
isPaginating = true
text = pageList[pageIndex]
isPaginating = false
if(pageList.size > 0) {
isPaginating = true
text = pageList[pageIndex]
isPaginating = false
}
}
fun setTxtF(text: CharSequence?) {
needPaginate = true
this.setText(text , null)
}
override fun setText(text: CharSequence?, type: BufferType?) {
if (!isPaginating) {
needPaginate = true
originalText = text ?: ""
}
super.setText(text, type)
@ -160,30 +170,34 @@ class PagedTextView : AppCompatTextView {
}
}
private fun paginate() {
pageList.clear()
Blog.LOGD(log = "paginate>> ${this::class.java.name}")
val layout = from(layout)
val lines = min(maxLines, layout.lineCount)
var startOffset = 0
val heightWithoutPaddings = pageHeight - paddingTop - paddingBottom
var height = heightWithoutPaddings
if (layout != null) {
MainScope().launch {
pageList.clear()
Blog.LOGD(log = "paginate>> ${this::class.java.name} && ${layout.text}")
val layout = from(layout)
val lines = if(min(maxLines, layout.lineCount) > 10) {min(maxLines, layout.lineCount) - 2} else {min(maxLines, layout.lineCount)}
var startOffset = 0
val heightWithoutPaddings = (pageHeight - (paddingTop + paddingBottom)) * 0.85
var height = heightWithoutPaddings
for (i in 0 until lines) {
if (height < layout.getLineBottom(i)) {
pageList.add(
layout.text.subSequence(startOffset, layout.getLineStart(i))
)
startOffset = layout.getLineStart(i)
height = layout.getLineTop(i) + heightWithoutPaddings
}
for (i in 0 until lines) {
if (height < layout.getLineBottom(i)) {
pageList.add(
layout.text.subSequence(startOffset, layout.getLineStart(i))
)
startOffset = layout.getLineStart(i)
height = layout.getLineTop(i) + heightWithoutPaddings
}
if (i == lines - 1) {
pageList.add(
layout.text.subSequence(startOffset, layout.getLineEnd(i))
)
if (i == lines - 1) {
pageList.add(
layout.text.subSequence(startOffset, layout.getLineEnd(i))
)
}
}
mPagedTextGenerateInterface?.completePagination(pageList)
}
}
mPagedTextGenerateInterface?.completePagination(pageList)
}
private fun from(layout: Layout): Layout =
@ -200,7 +214,7 @@ class PagedTextView : AppCompatTextView {
))
} else {
StaticLayout.Builder
.obtain(originalText, 0, originalText.length, paint, layout.width)
.obtain(originalText, 0, originalText.length, paint, layout.width - (paddingLeft + paddingRight))
.setAlignment(layout.alignment)
.setLineSpacing(lineSpacingExtra, lineSpacingMultiplier)
.setIncludePad(includeFontPadding)

View File

@ -5,4 +5,5 @@ interface PagedTextViewInterface {
fun onTimeoverTouch()
fun onSwipeLeft()
fun onSwipeRight()
fun onLongClick()
}

View File

@ -1,62 +1,62 @@
package com.mime.dualscreenview.view
import android.content.Context
import android.util.AttributeSet
import com.mime.dualscreenview.R
import kotlinx.android.synthetic.main.layout_steps_editor.view.btn_decrement
import kotlinx.android.synthetic.main.layout_steps_editor.view.btn_increment
import kotlinx.android.synthetic.main.layout_steps_editor.view.text_value
class ScopeEditor: SideButtonTextView {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
var titleArray : Array<String>? = null
set(value) {
if(value != null && value.size < 1) {
Error("titleArray는 최소 한개 이상이여야됨.")
return
}
field = value
maxValue = field!!.size
}
var maxValue : Int = 1
set(value) {
if (value < 1) {
Error("maxValue는 무조건 0보다 커야하눈뎅....")
return
}
field = value
}
override var value : Int = 14
set(newValue) {
field = newValue
text_value.text = displayFormat.format(titleArray?.get(field) ?:"defulat")
mValueChange?.invoke(field)
}
constructor(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes)
init {
inflate(context, R.layout.layout_steps_editor,this)
btn_decrement.setOnClickListener { value = Math.abs(value.dec()).rem(maxValue) }
btn_increment.setOnClickListener { value = value.inc().rem(maxValue) }
leftButtonTitle = "<"
rightButtonTitle = ">"
}
}
//package com.mime.dualscreenview.view
//
//import android.content.Context
//import android.util.AttributeSet
//import com.mime.dualscreenview.R
//import kotlinx.android.synthetic.main.layout_steps_editor.view.btn_decrement
//import kotlinx.android.synthetic.main.layout_steps_editor.view.btn_increment
//import kotlinx.android.synthetic.main.layout_steps_editor.view.text_value
//
//class ScopeEditor: SideButtonTextView {
// constructor(context: Context) : super(context)
// constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
// constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
// context,
// attrs,
// defStyleAttr
// )
// var titleArray : Array<String>? = null
// set(value) {
// if(value != null && value.size < 1) {
// Error("titleArray는 최소 한개 이상이여야됨.")
// return
// }
// field = value
// maxValue = field!!.size
// }
//
// var maxValue : Int = 1
// set(value) {
// if (value < 1) {
// Error("maxValue는 무조건 0보다 커야하눈뎅....")
// return
// }
// field = value
// }
//
// override var value : Int = 14
// set(newValue) {
// field = newValue
// text_value.text = displayFormat.format(titleArray?.get(field) ?:"defulat")
// mValueChange?.invoke(field)
// }
//
//
// constructor(
// context: Context,
// attrs: AttributeSet?,
// defStyleAttr: Int,
// defStyleRes: Int
// ) : super(context, attrs, defStyleAttr, defStyleRes)
//
// init {
// inflate(context, R.layout.layout_steps_editor,this)
// btn_decrement.setOnClickListener { value = Math.abs(value.dec()).rem(maxValue) }
// btn_increment.setOnClickListener { value = value.inc().rem(maxValue) }
// leftButtonTitle = "<"
// rightButtonTitle = ">"
// }
//
//
//
//}

View File

@ -1,70 +1,70 @@
package com.mime.dualscreenview.view
import android.content.Context
import android.util.AttributeSet
import androidx.constraintlayout.widget.ConstraintLayout
import com.mime.dualscreenview.R
import kotlinx.android.synthetic.main.layout_steps_editor.view.btn_decrement
import kotlinx.android.synthetic.main.layout_steps_editor.view.btn_increment
import kotlinx.android.synthetic.main.layout_steps_editor.view.text_value
import java.lang.Exception
open class SideButtonTextView : ConstraintLayout {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
constructor(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes)
var leftButtonTitle : String = ""
set(value) {
field = value
btn_decrement.text = field
}
var rightButtonTitle : String = ""
set(value) {
field = value
btn_increment.text = field
}
open var value : Int = 14
set(newValue) {
field = newValue
text_value.text = displayFormat.format(field)
mValueChange?.invoke(field)
}
var displayFormat = "글자 크기 : %d"
set(newValue) {
field = newValue
try {
text_value.text = displayFormat.format(value)
} catch (e : Exception) {
}
}
var mValueChange : ValueChange? = null
set(newValue) {
field = newValue
if (newValue != null) {
newValue(value)
}
}
init {
// inflate(context, R.layout.layout_steps_editor,this)
// btn_decrement.setOnClickListener { value = value.dec() }
// btn_increment.setOnClickListener { value = value.inc() }
}
}
//package com.mime.dualscreenview.view
//
//import android.content.Context
//import android.util.AttributeSet
//import androidx.constraintlayout.widget.ConstraintLayout
//import com.mime.dualscreenview.R
//import kotlinx.android.synthetic.main.layout_steps_editor.view.btn_decrement
//import kotlinx.android.synthetic.main.layout_steps_editor.view.btn_increment
//import kotlinx.android.synthetic.main.layout_steps_editor.view.text_value
//import java.lang.Exception
//
//open class SideButtonTextView : ConstraintLayout {
// constructor(context: Context) : super(context)
// constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
// constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
// context,
// attrs,
// defStyleAttr
// )
//
// constructor(
// context: Context,
// attrs: AttributeSet?,
// defStyleAttr: Int,
// defStyleRes: Int
// ) : super(context, attrs, defStyleAttr, defStyleRes)
//
// var leftButtonTitle : String = ""
// set(value) {
// field = value
// btn_decrement.text = field
// }
//
// var rightButtonTitle : String = ""
// set(value) {
// field = value
// btn_increment.text = field
// }
//
// open var value : Int = 14
// set(newValue) {
// field = newValue
// text_value.text = displayFormat.format(field)
// mValueChange?.invoke(field)
// }
//
// var displayFormat = "글자 크기 : %d"
// set(newValue) {
// field = newValue
// try {
// text_value.text = displayFormat.format(value)
// } catch (e : Exception) {
//
// }
// }
//
// var mValueChange : ValueChange? = null
// set(newValue) {
// field = newValue
// if (newValue != null) {
// newValue(value)
// }
// }
//
// init {
//// inflate(context, R.layout.layout_steps_editor,this)
//// btn_decrement.setOnClickListener { value = value.dec() }
//// btn_increment.setOnClickListener { value = value.inc() }
// }
//}

View File

@ -1,37 +1,37 @@
package com.mime.dualscreenview.view
import android.content.Context
import android.util.AttributeSet
import androidx.constraintlayout.widget.ConstraintLayout
import com.mime.dualscreenview.R
import kotlinx.android.synthetic.main.layout_steps_editor.view.btn_decrement
import kotlinx.android.synthetic.main.layout_steps_editor.view.btn_increment
import kotlinx.android.synthetic.main.layout_steps_editor.view.text_value
import java.lang.Exception
typealias ValueChange = (Int)->Unit
class StepsEditor : SideButtonTextView {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
constructor(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes)
init {
inflate(context, R.layout.layout_steps_editor,this)
btn_decrement.setOnClickListener { value = value.dec() }
btn_increment.setOnClickListener { value = value.inc() }
leftButtonTitle = "-"
rightButtonTitle = "+"
}
}
//package com.mime.dualscreenview.view
//
//import android.content.Context
//import android.util.AttributeSet
//import androidx.constraintlayout.widget.ConstraintLayout
//import com.mime.dualscreenview.R
//import kotlinx.android.synthetic.main.layout_steps_editor.view.btn_decrement
//import kotlinx.android.synthetic.main.layout_steps_editor.view.btn_increment
//import kotlinx.android.synthetic.main.layout_steps_editor.view.text_value
//import java.lang.Exception
//
//typealias ValueChange = (Int)->Unit
//
//class StepsEditor : SideButtonTextView {
// constructor(context: Context) : super(context)
// constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
// constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
// context,
// attrs,
// defStyleAttr
// )
//
// constructor(
// context: Context,
// attrs: AttributeSet?,
// defStyleAttr: Int,
// defStyleRes: Int
// ) : super(context, attrs, defStyleAttr, defStyleRes)
//
// init {
// inflate(context, R.layout.layout_steps_editor,this)
// btn_decrement.setOnClickListener { value = value.dec() }
// btn_increment.setOnClickListener { value = value.inc() }
// leftButtonTitle = "-"
// rightButtonTitle = "+"
// }
//}

View File

@ -8,6 +8,9 @@ import android.webkit.*
import com.mime.dualscreenview.common.Blog
import com.mime.dualscreenview.data.model.LastInfo
import com.mime.dualscreenview.webcontents.contentsinfo.DidFindContents
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.json.JSONObject
open class BaseWebContentsViewer {
@ -16,12 +19,27 @@ open class BaseWebContentsViewer {
lateinit var webview : WebView
lateinit var mainControllInterface : MainControllInterface
@JavascriptInterface
fun onBookInfo(jsonData : String) {
GlobalScope.launch {
try {
Blog.LOGE("BaseWebContentsViewer",jsonData)
val data: JSONObject = JSONObject(jsonData)
Blog.LOGE("BaseWebContentsViewer",data.toString())
mainControllInterface?.onBookInfos(jsonData)
} catch (e : Exception) {
}
}
}
constructor(webview : WebView, mainControllInterface : MainControllInterface ) {
this.webview = webview
this.mainControllInterface = mainControllInterface
webview.webChromeClient = rootWebChromeClient
webview.webViewClient = rootWebViewClient
webview.settings.textZoom = 100
webview.addJavascriptInterface(this,"PAgit")
webview.settings.javaScriptEnabled = true
webview.settings.javaScriptCanOpenWindowsAutomatically = false
webview.settings.loadWithOverviewMode = true
@ -33,6 +51,8 @@ open class BaseWebContentsViewer {
WebView.setWebContentsDebuggingEnabled(true)
}
constructor()
fun loadContents(webContents: BaseWebContents) {
currentContentsProvider = webContents
currentContentsProvider?.let {
@ -69,9 +89,9 @@ open class BaseWebContentsViewer {
if(request?.url?.toString()?.contains("gif") ?: false) {
return WebResourceResponse("text/javascript", "UTF-8", null);
}
if(request?.url?.toString()?.contains(currentContentsProvider?.acccceptResourceKeyword() ?: "") == false && request?.url?.toString()?.contains(currentContentsProvider?.getLastedDoamin() ?: "") == false) {
return WebResourceResponse("text/javascript", "UTF-8", null);
}
// if(request?.url?.toString()?.contains(currentContentsProvider?.acccceptResourceKeyword() ?: "") == false && request?.url?.toString()?.contains(currentContentsProvider?.getLastedDoamin() ?: "") == false) {
// return WebResourceResponse("text/javascript", "UTF-8", null);
// }
return super.shouldInterceptRequest(view, request)
}
@ -142,6 +162,11 @@ open class BaseWebContentsViewer {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
view?.let {
if(url?.contains("/list/") ?: false){
findListItem {
Blog.LOGE("onPageFinished", url ?: "")
}
}
currentContentsProvider?.doOnloaded(it , { result ->
result?.let { mainControllInterface.onLoadedContents(it) }
} , {

View File

@ -15,5 +15,6 @@ interface MainControllInterface {
fun onLoadedContents(contents :String)
fun onFindTitle(contents :String)
fun onBookInfos(jsonString : String)
}

View File

@ -1,12 +1,13 @@
package com.mime.dualscreenview.webcontents
import com.mime.dualscreenview.webcontents.contentsinfo.Agit
import com.mime.dualscreenview.webcontents.contentsinfo.Booktoki
object WebContentsManger {
val allContentsList : ArrayList<BaseWebContents> = arrayListOf(Booktoki)
val allContentsList : ArrayList<BaseWebContents> = arrayListOf(Agit)
fun getBaseWebContentsBy(name : String) : BaseWebContents {
var correctContents : BaseWebContents = Booktoki
var correctContents : BaseWebContents = Agit
for (contents in allContentsList) {
if(name.equals(contents.getWebcontentsName())) {
correctContents = contents

View File

@ -0,0 +1,138 @@
package com.mime.dualscreenview.webcontents.contentsinfo
import com.mime.dualscreenview.webcontents.BaseWebContents
object Agit : BaseWebContents() {
override var lastNumber : Int = 664
override fun getWebcontentsName(): String {
return "Agit"
}
override fun getLastedDoamin(): String {
return String.format("https://agit%d.xyz/", lastNumber)
}
override fun getContentsList(): String {
return " var datasets = [];\n" +
" var pageNum = 0;\n" +
" var totalCount = 0;\n" +
" var currentIdx = 0;\n" +
" function getContentList() {\n" +
" \n" +
" if(document.getElementById('count_list') != undefined && totalCount <= 0) {\n" +
" totalCount = Number(document.getElementById('count_list').textContent);\n" +
" console.log(\"totalCount \" + totalCount);\n" +
" currentIdx = totalCount;\n" +
" }\n" +
" \n" +
" var bookTitle = document.getElementsByClassName('pt-2')[1].textContent;\n" +
" var bookPageUrl = new URL(location.href).pathname;\n" +
" var pages = document.getElementById('id_page_novel_c').childNodes;\n" +
" var list = document.getElementById('id_list_novel_c').childNodes;\n" +
" console.log(\"list.length >> \" + list.length);\n" +
" for (i = 0; i < list.length; i++) {\n" +
" var onclickValue = list[i].attributes['onclick'].value;\n" +
" var pageUrl = onclickValue.split('location.href=')[1].replace(';', '');\n" +
" var chapterTitle = list[i].childNodes[1].children[0].textContent;\n" +
" var chapterID = list[i].childNodes[1].getAttribute('data-wr-id-c');\n" +
" \n" +
" var data = {\n" +
" 'chapterID': Number(chapterID),\n" +
" 'idx': Number(currentIdx),\n" +
" 'pathUrl': pageUrl,\n" +
" 'bookPageUrl': bookPageUrl,\n" +
" 'chapterTitle': chapterTitle,\n" +
" 'bookTitle': bookTitle,\n" +
" };\n" +
" datasets.push(data);\n" +
" currentIdx = currentIdx - 1\n" +
" }\n" +
" \n" +
" \n" +
" \n" +
" var currentTime = 500;\n" +
" try { currentTime = new Date().valueOf() % 1000;\n" +
" \n" +
" } catch (e) {\n" +
" \n" +
" }\n" +
" \n" +
" console.log(\"pages.length >> \" + pages.length);\n" +
" console.log(\"datasets.length >> \" + datasets.length);\n" +
" console.log(\"totalCount >> \" + totalCount);\n" +
" console.log(\"pages.length >> \" + pages.length);\n" +
" \n" +
" if ((pages.length > pageNum) ||\n" +
" (totalCount > datasets.length)) {\n" +
" pageNum += 1;\n" +
" get_data_novel_list_c(pageNum);\n" +
" setTimeout(function() {\n" +
" getContentList();\n" +
" }, 2000 + currentTime);\n" +
" } else if ((pages.length == pageNum) ||\n" +
" (totalCount > 10 &&\n" +
" totalCount == datasets.length)) {\n" +
" datasets.sort((a, b) => b.idx < a.idx);\n" +
" var i = 0;\n" +
" datasets.forEach(function(item) {\n" +
" item['chapterNum'] = i;\n" +
" i = i + 1;\n" +
" } );\n" +
" \n" +
" PAgit.onBookInfo(JSON.stringify({\n" +
" 'bookTitle': bookTitle,\n" +
" 'bookPageUrl': new URL(location.href)\n" +
" .pathname,\n" +
" 'pages': datasets ,\n" +
" }));\n" +
" }\n" +
" }\n" +
" \n" +
" function wait(sec) {\n" +
" let start = Date.now(),\n" +
" now = start;\n" +
" while (now - start < sec * 1000) {\n" +
" now = Date.now();\n" +
" }\n" +
" }\n" +
" getContentList();"
}
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(\"id_wr_content\") != null ? document.getElementById(\"id_wr_content\").innerText : null"
}
override fun checkCorrectContents(contents: String): String {
return if (contents != null && !contents.isNullOrEmpty()) {
contents
} else {
"fail load"
}
}
override fun onLoadedJs(): String {
return "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();"
}
}

View File

@ -10,6 +10,7 @@
<WebView
android:id="@+id/menu_web"
android:layout_margin="20dp"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
@ -18,17 +19,7 @@
app:layout_constraintTop_toBottomOf="@id/textview_title" />
<com.mime.dualscreenview.view.PagedTextLayout
android:id="@+id/paged_layer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="invisible"
android:background="@color/black"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/btn_setting"
app:layout_constraintTop_toBottomOf="@id/textview_title" />
<ImageButton
android:id="@+id/btn_home"
@ -49,7 +40,7 @@
android:layout_width="0dp"
android:layout_height="@dimen/main_top_height"
android:text="@string/app_name"
android:background="#8FFF"
android:background="@color/black"
android:gravity="center"
android:textSize="24sp"
app:layout_constraintRight_toLeftOf="@id/btn_list"
@ -104,7 +95,7 @@
android:tag="1"
android:text="@string/display_the_second_screen"
android:visibility="visible"
android:background="#8FFF"
android:background="@color/black"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_chainStyle="spread"
@ -114,7 +105,7 @@
android:id="@+id/btn_setting"
android:layout_width="0dp"
android:layout_height="@dimen/main_top_height"
android:background="#8FFF"
android:background="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/btn_left"
app:layout_constraintRight_toLeftOf="@+id/btn_right"
@ -128,12 +119,27 @@
android:layout_marginStart="16dp"
android:tag="0"
android:text="@string/display_the_second_screen"
android:background="#8FFF"
android:background="@color/black"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_chainStyle="spread" />
<com.mime.dualscreenview.view.PagedTextLayout
android:id="@+id/paged_layer"
android:layout_margin="1dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="invisible"
android:background="@color/black"
android:elevation="5dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/btn_setting"
app:layout_constraintTop_toBottomOf="@id/textview_title" />
<ProgressBar
android:id="@+id/progress"
android:layout_width="0dp"

View File

@ -1,52 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="@dimen/main_top_height"
android:paddingBottom="@dimen/main_top_height"
android:layout_margin="0dp"
android:layout_margin="5dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/center_guide"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"
android:layout_width="0dp"
android:layout_height="0dp"/>
<LinearLayout
android:layout_margin="8dp"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mime.dualscreenview.view.PagedTextView
android:layout_margin="5dp"
android:padding="2dp"
android:id="@+id/hidden_view"
android:visibility="visible"
android:layout_width="0dp"
android:layout_weight="1"
android:includeFontPadding="false"
android:lineSpacingExtra="0dp"
style="@style/sss"
android:layout_height="match_parent"/>
<View
android:id="@+id/demp"
android:layout_margin="5dp"
android:padding="2dp"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"/>
</LinearLayout>
<com.mime.dualscreenview.view.PagedTextView
android:padding="@dimen/textview_padding"
android:id="@+id/hidden_view"
android:visibility="invisible"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/sencond_view"
android:layout_width="0dp"
style="@style/sss"
android:layout_height="match_parent"/>
<LinearLayout
android:layout_margin="5dp"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatTextView
android:layout_margin="5dp"
android:padding="2dp"
android:gravity="center"
android:includeFontPadding="false"
android:id="@+id/first_view"
android:lineSpacingExtra="0dp"
android:layout_width="0dp"
android:layout_weight="1"
style="@style/sss"
android:layout_height="match_parent"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/first_view"
android:padding="@dimen/textview_padding"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@id/sencond_view"
android:layout_width="0dp"
style="@style/sss"
android:layout_height="match_parent"/>
<androidx.appcompat.widget.AppCompatTextView
android:layout_margin="5dp"
android:padding="2dp"
android:includeFontPadding="false"
android:lineSpacingExtra="0dp"
android:visibility="visible"
android:id="@+id/sencond_view"
android:layout_width="0dp"
android:layout_weight="1"
style="@style/sss"
android:layout_height="match_parent"/>
<androidx.appcompat.widget.AppCompatTextView
android:padding="@dimen/textview_padding"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@id/center_guide"
android:id="@+id/sencond_view"
android:layout_width="0dp"
style="@style/sss"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</RelativeLayout>

View File

@ -3,53 +3,53 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/vertical_guide"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatTextView
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/preview"
android:text="@string/preview_text"
android:layout_width="0dp"
android:layout_height="0dp"/>
<ScrollView
android:id="@+id/config_setting"
android:background="#99444444"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/vertical_guide"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="0dp"
android:layout_height="0dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/item_setting_title"/>
<com.mime.dualscreenview.view.StepsEditor
android:id="@+id/text_size"
style="@style/StepsEditorStyle" />
<com.mime.dualscreenview.view.StepsEditor
android:id="@+id/letter_space"
style="@style/StepsEditorStyle" />
<com.mime.dualscreenview.view.StepsEditor
android:id="@+id/line_space"
style="@style/StepsEditorStyle" />
<com.mime.dualscreenview.view.StepsEditor
android:id="@+id/page_padding"
style="@style/StepsEditorStyle" />
<com.mime.dualscreenview.view.ScopeEditor
android:id="@+id/page_typesface"
style="@style/StepsEditorStyle" />
<com.mime.dualscreenview.view.ScopeEditor
android:id="@+id/page_style"
style="@style/StepsEditorStyle" />
</LinearLayout>
</ScrollView>
<!-- <androidx.constraintlayout.widget.Guideline-->
<!-- android:id="@+id/vertical_guide"-->
<!-- android:orientation="horizontal"-->
<!-- app:layout_constraintGuide_percent="0.5"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"/>-->
<!-- <androidx.appcompat.widget.AppCompatTextView-->
<!-- app:layout_constraintLeft_toLeftOf="parent"-->
<!-- app:layout_constraintRight_toRightOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- android:id="@+id/preview"-->
<!-- android:text="@string/preview_text"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp"/>-->
<!-- <ScrollView-->
<!-- android:id="@+id/config_setting"-->
<!-- android:background="#99444444"-->
<!-- app:layout_constraintLeft_toLeftOf="parent"-->
<!-- app:layout_constraintRight_toRightOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="@id/vertical_guide"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp">-->
<!-- <LinearLayout-->
<!-- android:orientation="vertical"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content">-->
<!-- <include layout="@layout/item_setting_title"/>-->
<!-- <com.mime.dualscreenview.view.StepsEditor-->
<!-- android:id="@+id/text_size"-->
<!-- style="@style/StepsEditorStyle" />-->
<!-- <com.mime.dualscreenview.view.StepsEditor-->
<!-- android:id="@+id/letter_space"-->
<!-- style="@style/StepsEditorStyle" />-->
<!-- <com.mime.dualscreenview.view.StepsEditor-->
<!-- android:id="@+id/line_space"-->
<!-- style="@style/StepsEditorStyle" />-->
<!-- <com.mime.dualscreenview.view.StepsEditor-->
<!-- android:id="@+id/page_padding"-->
<!-- style="@style/StepsEditorStyle" />-->
<!-- <com.mime.dualscreenview.view.ScopeEditor-->
<!-- android:id="@+id/page_typesface"-->
<!-- style="@style/StepsEditorStyle" />-->
<!-- <com.mime.dualscreenview.view.ScopeEditor-->
<!-- android:id="@+id/page_style"-->
<!-- style="@style/StepsEditorStyle" />-->
<!-- </LinearLayout>-->
<!-- </ScrollView>-->
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -2,8 +2,8 @@
<!-- Base application theme. -->
<style name="Theme.DualScreenView" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorPrimary">@color/black</item>
<item name="colorPrimaryVariant">@color/black</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>

View File

@ -1,11 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="sss">
<item name="android:statusBarColor" tools:targetApi="l">@color/black</item>
<item name="android:fontFamily">@font/kcc_sonkeechung</item>
<item name="android:textSize">14dp</item>
<item name="android:textAlignment">textStart</item>
</style>
<style name="StepsEditorStyle">
<item name="android:statusBarColor" tools:targetApi="l">@color/black</item>
<item name="android:layout_width">match_parent</item>>
<item name="android:layout_height">@dimen/setting_item_height</item>>
</style>

View File

@ -2,15 +2,15 @@
<!-- Base application theme. -->
<style name="Theme.DualScreenView" parent="Theme.MaterialComponents.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnSecondary">@color/black</item>
<item name="colorPrimary">@color/black</item>
<item name="colorPrimaryVariant">@color/black</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<item name="android:statusBarColor">?attr/colorOnSecondary</item>
<!-- Customize your theme here. -->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>