From a72b1778a942c8c3d336311ed7b1b3d73ab36033 Mon Sep 17 00:00:00 2001 From: lunaticbum Date: Thu, 12 Mar 2026 17:09:35 +0900 Subject: [PATCH] ... --- .../extensions/my_extension/messaging.js | 28 ++- .../launcher/common/RemoteGestureFragment.kt | 17 ++ .../bums/lunatic/launcher/home/GeckoWeb.kt | 5 + .../lunatic/launcher/home/NeoRssActivity.kt | 183 +++++++++++++++--- .../bums/lunatic/launcher/home/RssHome.kt | 123 ++++++++++-- .../launcher/home/adapters/RssItemAdapter.kt | 10 +- .../launcher/home/tokiz/TokiFragment.kt | 84 ++++++-- 7 files changed, 383 insertions(+), 67 deletions(-) create mode 100644 app/src/main/kotlin/bums/lunatic/launcher/common/RemoteGestureFragment.kt diff --git a/app/src/main/assets/extensions/my_extension/messaging.js b/app/src/main/assets/extensions/my_extension/messaging.js index 25fc3d07..a1b1932b 100644 --- a/app/src/main/assets/extensions/my_extension/messaging.js +++ b/app/src/main/assets/extensions/my_extension/messaging.js @@ -53,7 +53,7 @@ function afterDay(date, before) { const port = browser.runtime.connectNative("browser"); port.onMessage.addListener(response => { var type= response["type"]; - + switch (type) { case "fetchAllImages": { const targetSrc = response["targetSrc"]; @@ -96,6 +96,16 @@ port.onMessage.addListener(response => { // try {contents = toonContents(document.querySelector("#novel_content"))}catch (e) {} // console.log("listBody", listBody); // console.log("title", title); + + const keyword = "보안"; + const elements = document.querySelectorAll(".main-content"); // 또는 getElementsByClassName("item") + + const matched = Array.from(elements).filter(el => + el.textContent.includes(keyword) // 대소문자 구분 + ); + + + if(listBody) { // getList(listBody.children) } else if(title && contents) { @@ -110,6 +120,8 @@ port.onMessage.addListener(response => { // } // ); // } + } else if(matched.length > 0){ + hideBook() } else { loadComplete() } @@ -129,7 +141,8 @@ port.onMessage.addListener(response => { } break; case "ViewerTouch": { - if (document.querySelector(".show_viewer")) { + if (document.querySelector(".show_viewer") && document.querySelector(".mcv-visible")) { + var area = response["area"] var current = Number(document.querySelector("#mcv_currentPageNum").innerHTML) var total = Number(document.querySelector("#mcv_totalPagesNum").innerHTML) @@ -146,8 +159,10 @@ port.onMessage.addListener(response => { }else { document.querySelector("#goNextBtn").click() } - document.querySelector(".link_ad") } + + } else if(document.querySelector(".show_viewer")){ + document.querySelector(".show_viewer").click(); } } break; @@ -350,8 +365,13 @@ function scrollByPercentUpDown(isToDown , max) { window.scrollTo({ top: currentScroll + (moveAmount * isToDown) , behavior: "smooth" }); } function loadComplete() { - // try {port.postMessage(JSON.stringify({type: "NotRegistered"}));}catch (e) {} + try {port.postMessage(JSON.stringify({type: "NotRegistered"}));}catch (e) {} } + +function hideBook() { + try {port.postMessage(JSON.stringify({type: "NotRegistered"}));}catch (e) {} +} + function sendMessage(msg) { port.postMessage(JSON.stringify(msg)); } diff --git a/app/src/main/kotlin/bums/lunatic/launcher/common/RemoteGestureFragment.kt b/app/src/main/kotlin/bums/lunatic/launcher/common/RemoteGestureFragment.kt new file mode 100644 index 00000000..fec5c1db --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/common/RemoteGestureFragment.kt @@ -0,0 +1,17 @@ +package bums.lunatic.launcher.common + +import androidx.fragment.app.Fragment + +abstract class RemoteGestureFragment : Fragment() { + + // 자식에서 필요한 동작만 구현 (기본적으로는 소비하지 않음) + open fun onRemoteUp(isDouble : Boolean) {} + open fun onRemoteDown(isDouble : Boolean) {} + open fun onRemoteLeft(isDouble : Boolean) {} + open fun onRemoteRight(isDouble : Boolean) {} + open fun onRemoteCenterClick() {} + open fun onRemoteCenterDoubleClick() {} + + // 이벤트를 가로챌지 여부를 결정하는 플래그 + open val isRemoteEnabled: Boolean = true +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt index 248b5d5f..0efebe30 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt @@ -348,6 +348,11 @@ open class GeckoWeb @JvmOverloads constructor( } } + fun goBack() { + if (true == canGoBack) + session?.goBack() + } + // [Progress Delegate] private val progressDelegate = object : GeckoSession.ProgressDelegate { override fun onProgressChange(session: GeckoSession, progress: Int) { diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/NeoRssActivity.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/NeoRssActivity.kt index 8bf4b0b4..6d9e772c 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/NeoRssActivity.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/NeoRssActivity.kt @@ -9,6 +9,7 @@ import android.os.Build import android.os.Bundle import android.os.Handler import android.os.Looper +import android.view.GestureDetector import android.view.KeyEvent import android.view.KeyEvent.ACTION_UP import android.view.KeyEvent.KEYCODE_BUTTON_A @@ -19,6 +20,11 @@ import android.view.KeyEvent.KEYCODE_BUTTON_X import android.view.KeyEvent.KEYCODE_BUTTON_Y import android.view.KeyEvent.KEYCODE_DPAD_DOWN import android.view.KeyEvent.KEYCODE_DPAD_UP +import android.view.KeyEvent.KEYCODE_MEDIA_PAUSE +import android.view.KeyEvent.KEYCODE_MEDIA_PLAY +import android.view.KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE +import android.view.KeyEvent.KEYCODE_VOLUME_DOWN +import android.view.KeyEvent.KEYCODE_VOLUME_UP import android.view.MotionEvent import android.view.PointerIcon import android.view.View @@ -35,6 +41,7 @@ import androidx.fragment.app.Fragment import bums.lunatic.launcher.LunaticLauncher import bums.lunatic.launcher.R import bums.lunatic.launcher.common.CommonActivity +import bums.lunatic.launcher.common.RemoteGestureFragment import bums.lunatic.launcher.databinding.RssActivityBinding import bums.lunatic.launcher.helpers.ForeGroundService import bums.lunatic.launcher.helpers.HeadsetActionButtonReceiver @@ -61,6 +68,7 @@ import org.mozilla.geckoview.GeckoRuntime import org.mozilla.geckoview.GeckoRuntimeSettings import org.mozilla.geckoview.GeckoRuntimeSettings.ALLOW_ALL import java.io.File +import kotlin.math.abs interface KeyEventHandler { // 이벤트를 소비(consume)했으면 true, 아니면 false 반환 @@ -117,9 +125,35 @@ open class NeoRssActivity : CommonActivity() { var actionButtonPressY = 0f var onExit = false var lastAction = MotionEvent.ACTION_HOVER_EXIT + + + override fun onKeyLongPress(keyCode: Int, ev: KeyEvent?): Boolean { + Blog.LOGE("keyEvent >>>>> ${ev?.device?.name}:${keyCode}: onKeyLongPress >>> ${ev} ") + return super.onKeyLongPress(keyCode, ev) + } + override fun dispatchKeyEvent(ev: KeyEvent): Boolean { - Blog.LOGE("dispatchKeyEvent >>> ${ev}") - if (ev?.device?.name?.contains("SM-031N Mouse") == true) { + Blog.LOGE("keyEvent >>>>> ${ev?.device?.name}:dispatchKeyEvent >>> ${ev} ") + if (ev?.device?.name?.contains("JX-05") == true) { +// (ev.action?.equals(KeyEvent.ACTION_DOWN) == true || ev.action?.equals(KeyEvent.ACTION_UP) == true) + if (ev.action?.equals(KeyEvent.ACTION_UP) == true) { + when(ev.keyCode) { + KEYCODE_MEDIA_PLAY_PAUSE->{ + onRemoteKeyDetected("RIGHT_ARROW", true) + } + KEYCODE_MEDIA_PAUSE->{ +// onRemoteKeyDetected("LEFT_ARROW", true) + } + KEYCODE_VOLUME_UP->{ + onRemoteKeyDetected("UP_ARROW", true) + } + KEYCODE_VOLUME_DOWN->{ + onRemoteKeyDetected("DOWN_ARROW", true) + } + }} + return true + }else + if (ev?.device?.name?.contains("SM-031N Mouse") == true) { when(ev.action) { ACTION_UP -> { Blog.LOGE("dispatch dispatchKeyEvent>>> ${ev}") @@ -175,39 +209,116 @@ open class NeoRssActivity : CommonActivity() { return super.dispatchKeyEvent(ev) } + private val flingHandler = Handler(Looper.getMainLooper()) + private var pendingFlingRunnable: Runnable? = null + private var lastFlingTime = 0L + private var lastFlingDirection = "" + private val DOUBLE_TAP_TIMEOUT = 300L + + private val remoteGestureDetector by lazy { + GestureDetector(this, object : GestureDetector.SimpleOnGestureListener() { + + private fun processFling(direction: String) { + // 이전에 예약된 싱글 실행이 있다면 일단 제거 (더블 체크를 위해) + pendingFlingRunnable?.let { flingHandler.removeCallbacks(it) } + + val currentTime = System.currentTimeMillis() + + // 1. 방향이 같고 시간 내에 들어왔는가? + if (direction == lastFlingDirection && (currentTime - lastFlingTime) < DOUBLE_TAP_TIMEOUT) { + Blog.LOGE("Detected DOUBLE FLING: $direction") + onRemoteKeyDetected(direction, true) // isDouble = true 전달 + lastFlingTime = 0L // 더블 처리 후 시간 초기화 + lastFlingDirection = "" + } else { + // 2. 일단 싱글 후보로 등록 + lastFlingTime = currentTime + lastFlingDirection = direction + + pendingFlingRunnable = Runnable { + Blog.LOGE("Detected SINGLE FLING: $direction") + onRemoteKeyDetected(direction, false) // isDouble = false 전달 + // 실행 후 상태 초기화는 하지 않음 (다음 클릭이 더블이 될 수 있으므로) + }.also { + flingHandler.postDelayed(it, DOUBLE_TAP_TIMEOUT) + } + } + } + + override fun onFling(e1: MotionEvent?, e2: MotionEvent, vx: Float, vy: Float): Boolean { + if (abs(vy) > abs(vx)) { + if (vy > 0) processFling("UP_ARROW") + else processFling("DOWN_ARROW") + } else { + if (vx > 0) processFling("LEFT_ARROW") + else processFling("RIGHT_ARROW") + } + return true + } + + // 중앙 버튼은 기존대로 유지 (탭 기반이므로 잘 동작함) + override fun onSingleTapConfirmed(e: MotionEvent): Boolean { + onRemoteKeyDetected("CENTER_SINGLE_TAP") + return true + } + + override fun onDoubleTap(e: MotionEvent): Boolean { + onRemoteKeyDetected("CENTER_DOUBLE_TAP") + return true + } + }) + } + + private fun onRemoteKeyDetected(keyType: String, isDouble : Boolean = false) { + Blog.LOGE("Remote Mapping Success: $keyType") + val currentFragment = supportFragmentManager.fragments.find { it.isVisible } + if (currentFragment is RemoteGestureFragment && currentFragment.isRemoteEnabled) { + when(keyType) { + "UP_ARROW"->{currentFragment.onRemoteUp(isDouble)} + "DOWN_ARROW"->{currentFragment.onRemoteDown(isDouble)} + "RIGHT_ARROW"->{currentFragment.onRemoteRight(isDouble)} + "LEFT_ARROW"->{currentFragment.onRemoteLeft(isDouble)} + "CENTER_SINGLE_TAP" -> { currentFragment.onRemoteCenterClick() } + "CENTER_DOUBLE_TAP" -> { currentFragment.onRemoteCenterDoubleClick() } + } + } else { + when(keyType) { + "UP_ARROW"->{showContents(R.id.feeds)} + "DOWN_ARROW"->{showContents(R.id.close)} + "RIGHT_ARROW"->{showContents(R.id.books)} + "LEFT_ARROW"->{ } + "CENTER_SINGLE_TAP" -> { } + "CENTER_DOUBLE_TAP" -> { showContents(R.id.btn_torrent) } + } + } + } + + override fun dispatchTouchEvent(ev: MotionEvent?): Boolean { + Blog.LOGE("keyEvent >>>>> dispatchTouchEvent ${ev}") + if (ev?.device?.name?.contains("JX-05") == true) { + // 리모컨 이벤트인 경우 제스처 디텍터에 위임 + if (remoteGestureDetector.onTouchEvent(ev)) { + return true // 앱의 다른 터치 로직(GeckoView 등)으로 전파되지 않도록 차단 + } + return true + } + return super.dispatchTouchEvent(ev) + } + override fun dispatchTrackballEvent(event: MotionEvent?): Boolean { + Blog.LOGE("keyEvent >>>>> dispatchTrackballEvent ${event}") return super.dispatchTrackballEvent(event) } @SuppressLint("RestrictedApi") override fun dispatchKeyShortcutEvent(event: KeyEvent): Boolean { + Blog.LOGE("keyEvent >>>>> dispatchKeyShortcutEvent ${event}") return super.dispatchKeyShortcutEvent(event) } - fun onClickCenterButton() { - WorkersDb.getRealm().apply { - writeBlocking { - delete( - query() - .query("pubDate < $0", - beforeDay(28) - ) - .query("vote != $0", true).apply { - Blog.LOGE("onClickCenterButton DELETE >> ${this.description()}") - }.find() - ) - var ddd = copyFromRealm(WorkersDb.getRssQuery("", RssDataType.getExcAdt(),false).limit(100).query("read == $0", 0).query("vote != $0", true).apply { - Blog.LOGE("onClickCenterButton SELECT >> ${this.description()}") - }.find()).map { it.originPage() } - var origin = ddd.first() - var jjjj = hashSetOf() - jjjj.addAll(ddd) - } - } - } override fun dispatchGenericMotionEvent(ev: MotionEvent?): Boolean { + Blog.LOGE("keyEvent >>>>> dispatchGenericMotionEvent ${ev}") if (ev?.device?.name?.contains("BLE-M3") == true) { - Blog.LOGE("keyEvent >>>>> dispatchGenericMotionEvent ${ev}") ev?.action?.let { action -> when(action) { MotionEvent.ACTION_HOVER_ENTER -> { @@ -267,6 +378,27 @@ open class NeoRssActivity : CommonActivity() { } return super.dispatchGenericMotionEvent(ev) } + fun onClickCenterButton() { + WorkersDb.getRealm().apply { + writeBlocking { + delete( + query() + .query("pubDate < $0", + beforeDay(28) + ) + .query("vote != $0", true).apply { + Blog.LOGE("onClickCenterButton DELETE >> ${this.description()}") + }.find() + ) + var ddd = copyFromRealm(WorkersDb.getRssQuery("", RssDataType.getExcAdt(),false).limit(100).query("read == $0", 0).query("vote != $0", true).apply { + Blog.LOGE("onClickCenterButton SELECT >> ${this.description()}") + }.find()).map { it.originPage() } + var origin = ddd.first() + var jjjj = hashSetOf() + jjjj.addAll(ddd) + } + } + } fun floatClick(v : View) { showContents(v.id) @@ -475,6 +607,7 @@ open class NeoRssActivity : CommonActivity() { private fun handleBackPress() { onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { + Blog.LOGE("handleBackPress") val currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container) if (currentFragment == null) showContents(R.id.close) when(currentFragment) { @@ -499,7 +632,7 @@ open class NeoRssActivity : CommonActivity() { }) } -// val experimentDelegate = object : ExperimentDelegate { + // val experimentDelegate = object : ExperimentDelegate { // override fun onGetExperimentFeature(feature: String): GeckoResult { // Blog.LOGE("onGetExperimentFeature $feature") // return super.onGetExperimentFeature(feature) diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/RssHome.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/RssHome.kt index 4dbf175a..44a61569 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/RssHome.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/RssHome.kt @@ -45,6 +45,7 @@ import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import bums.lunatic.launcher.R +import bums.lunatic.launcher.common.RemoteGestureFragment import bums.lunatic.launcher.common.letTrue import bums.lunatic.launcher.databinding.LauncherHomeBinding import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS @@ -83,7 +84,7 @@ import java.text.SimpleDateFormat import java.util.Date -internal class RssHome : Fragment() , KeyEventHandler { +internal class RssHome : RemoteGestureFragment() , KeyEventHandler { lateinit var binding: LauncherHomeBinding private lateinit var fragManager: FragmentManager @@ -95,6 +96,75 @@ internal class RssHome : Fragment() , KeyEventHandler { var lastedFinishedPageUrl: String = "" } + fun doubleCount(isDouble : Boolean) = if(isDouble) {8}else{1} + + override fun onRemoteUp(isDouble : Boolean) { + if (binding.lunaticBrowser.isVisible) { + binding.lunaticBrowser.geckoWeb.pageUp() + } else { + moveSelection(doubleCount(isDouble) * -1) + } + } + + override fun onRemoteDown(isDouble : Boolean) { + if (binding.lunaticBrowser.isVisible) { + binding.lunaticBrowser.geckoWeb.pageDown() + } else { + moveSelection(doubleCount(isDouble) * +1) + } + } + + override fun onRemoteLeft(isDouble : Boolean) { + if (binding.lunaticBrowser.isVisible) { + doNextPage() + } else { + + } + } + + override fun onRemoteRight(isDouble : Boolean) { + if (binding.lunaticBrowser.isVisible) { + binding.lunaticBrowser.geckoWeb.goBack() + } else { + + } + } + + override fun onRemoteCenterClick() { + if (binding.lunaticBrowser.isVisible) { + vote() + } else { + if (selectedIndex > -1) { + openGecko(lasted.get(selectedIndex)) + } + } + } + + override fun onRemoteCenterDoubleClick() { + if (binding.lunaticBrowser.isVisible) { + binding.lunaticBrowser.visibility = View.GONE + } + } + private var selectedIndex = -1 + private fun moveSelection(delta: Int) { + if (lasted.isEmpty()) return + + // 인덱스 갱신 + val nextIndex = selectedIndex + delta + if (nextIndex in 0 until lasted.size) { + val oldIndex = selectedIndex + selectedIndex = nextIndex + + // 1. 이전 선택된 아이템 UI 초기화, 2. 새 아이템 UI 강조 + mRssAdapter.notifyItemChanged(oldIndex) + mRssAdapter.selectedIndex = selectedIndex + mRssAdapter.notifyItemChanged(selectedIndex) + + // 3. 해당 위치로 부드럽게 스크롤 + binding.infoList.smoothScrollToPosition(selectedIndex) + } + } + val commandHandler = Handler(Looper.getMainLooper()) val infoUpdate = Runnable { chooseAdpater() } @@ -227,7 +297,7 @@ internal class RssHome : Fragment() , KeyEventHandler { binding.lunaticBrowser.geckoWeb.pageDown() } } - true + true } KeyEvent.KEYCODE_VOLUME_UP -> { @@ -436,6 +506,7 @@ internal class RssHome : Fragment() , KeyEventHandler { var currentRss : RssData? = null @SuppressLint("SimpleDateFormat") fun openGecko(rssData: RssData? = null) { + lasted.removeIf { it.originPage.equals(currentRss?.originPage) } binding.layoutRssSummary.root.visibility = View.GONE binding.lunaticBrowser.visibility = View.GONE binding.lunaticBrowser.setupForRssHome() @@ -544,10 +615,10 @@ internal class RssHome : Fragment() , KeyEventHandler { // 1. 상단 바 RssHome 전용 기능 연결 browser.binding.btnHome.setOnClickListener { // if (binding.lunaticBrowser.isVisible || binding.layoutRssSummary.root.isVisible) { - binding.lunaticBrowser.visibility = View.GONE - binding.layoutRssSummary.root.visibility = View.GONE + binding.lunaticBrowser.visibility = View.GONE + binding.layoutRssSummary.root.visibility = View.GONE // } else { - queryInfos() + queryInfos() // } } @@ -643,7 +714,20 @@ internal class RssHome : Fragment() , KeyEventHandler { } fun vote() { - binding.lunaticBrowser.geckoWeb?.saveMd(true) + WorkersDb.getRealm().apply { + writeBlocking { + currentRss?.originPage?.let { + val result = query().query("originPage == $0", it).find() + if (result.size > 0) { + result.forEach { + it.vote = true + } + } + } + } + } + doNextPage() +// binding.lunaticBrowser.geckoWeb?.saveMd(true) } // TokiFragment 또는 GeckoView를 사용하는 프래그먼트 내부 @@ -663,19 +747,20 @@ internal class RssHome : Fragment() , KeyEventHandler { @SuppressLint("NewApi") fun doNextPage() { - currentRss?.originPage.let { - WorkersDb.getRealm().apply { - writeBlocking { - val result = query().query( - if (imageView) "thumbnail == $0" else "originPage == $0", - it - ).find() - if (result.size > 0) { - result.forEach { it.read = it.read + nomoreShowCount } - } - } - } - } +// currentRss?.originPage.let { +// WorkersDb.getRealm().apply { +// writeBlocking { +// val result = query().query( +// if (imageView) "thumbnail == $0" else "originPage == $0", +// it +// ).find() +// if (result.size > 0) { +// result.forEach { it.read = it.read + nomoreShowCount } +// } +// } +// } +// } + openGecko(randomOrNull()) } diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/RssItemAdapter.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/RssItemAdapter.kt index 3c2e2152..96058557 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/RssItemAdapter.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/RssItemAdapter.kt @@ -20,6 +20,7 @@ package bums.lunatic.launcher.home.adapters import android.annotation.SuppressLint import android.content.Context +import android.graphics.Color import android.view.LayoutInflater import android.view.MotionEvent import android.view.View @@ -81,7 +82,7 @@ internal class RssItemAdapter ( return rssDataItemLis.size } - + var selectedIndex = -1 val mSimpleFingerGestures = SimpleFingerGestures(omfgl = object : SimpleFingerGestures.OnFingerGestureListener{ override fun onSwipeUp( @@ -171,7 +172,7 @@ internal class RssItemAdapter ( }) @SuppressLint("SetTextI18n", "ClickableViewAccessibility") - override fun onBindViewHolder(holder: RssHolder, position: Int) { + override fun onBindViewHolder(holder: RssHolder, @SuppressLint("RecyclerView") position: Int) { synchronized(rssDataItemLis) { if (rssDataItemLis.isNotEmpty() && rssDataItemLis.size > position) { try { @@ -238,6 +239,11 @@ internal class RssItemAdapter ( // } // } holder.itemView.setOnLongClickListener(mLongClickListener) + if (position == selectedIndex) { + holder.view.root.setBackgroundColor(Color.parseColor("#33FFFFFF")) // 강조색 + } else { + holder.view.root.setBackgroundColor(Color.TRANSPARENT) + } } catch (e: Exception){} } diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/tokiz/TokiFragment.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/tokiz/TokiFragment.kt index 5cb4d633..6c48f59e 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/tokiz/TokiFragment.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/tokiz/TokiFragment.kt @@ -32,6 +32,7 @@ import androidx.core.net.toUri import androidx.core.view.isVisible import androidx.fragment.app.Fragment import bums.lunatic.launcher.R +import bums.lunatic.launcher.common.RemoteGestureFragment import bums.lunatic.launcher.databinding.BooktokiBinding import bums.lunatic.launcher.home.GeckoWeb import bums.lunatic.launcher.home.GeckoWeb.JxEvent @@ -66,7 +67,7 @@ import java.util.Date import kotlin.random.Random // 기존 BaseToki 및 하위 클래스들을 통합한 단일 클래스 -class TokiFragment : Fragment(), PagedTextViewInterface,KeyEventHandler { +class TokiFragment : RemoteGestureFragment(), PagedTextViewInterface,KeyEventHandler { // --- Configuration Properties (Arguments에서 로드) --- private lateinit var contentsType: String @@ -101,7 +102,7 @@ class TokiFragment : Fragment(), PagedTextViewInterface,KeyEventHandler { var canGoBack: Boolean? = null protected lateinit var binding: BooktokiBinding - var mPort: WebExtension.Port? = null +// var mPort: WebExtension.Port? = null val mPortNam = "browser" val extPath = "resource://android/assets/extensions/my_extension/" val extId = "messaging@booktoki468.com" @@ -230,7 +231,56 @@ class TokiFragment : Fragment(), PagedTextViewInterface,KeyEventHandler { } } - // --- Unified Gesture Implementation --- + override fun onRemoteCenterClick() { + super.onRemoteCenterClick() + } + + override fun onRemoteCenterDoubleClick() { + if (binding.pagedLayer.isVisible) { + onSwipeDown(2) + } + } + + override fun onRemoteRight(isDouble : Boolean) { + if (binding.pagedLayer.isVisible) { + actionNextEvent(isDouble) + } else if (contentsType.contains("comics")) { + if (contentsType == "comics") sendViewerTouch("right") else actionNextEvent() + } + } + + override fun onRemoteLeft(isDouble : Boolean) { + if (binding.pagedLayer.isVisible) { + actionPrevEvent(isDouble) + } else if (contentsType.contains("comics")) { + if (contentsType == "comics") sendViewerTouch("left") else actionNextEvent() + } + } + + override fun onRemoteDown(isDouble : Boolean) { + if (binding.pagedLayer.isVisible) { + + } else { + if (binding.lunaticBrowser.geckoWeb.scrollState > 0) { + + } else { + binding.lunaticBrowser.geckoWeb.pageDown() + } + + } + } + + override fun onRemoteUp(isDouble : Boolean) { + if (binding.pagedLayer.isVisible) { + + } else { + if (binding.lunaticBrowser.geckoWeb.scrollState < 0) { + + } else { + binding.lunaticBrowser.geckoWeb.pageUp() + } + } + } override fun onTouch(touchArea: TouchArea) { if (!enableGestures) return @@ -435,7 +485,7 @@ class TokiFragment : Fragment(), PagedTextViewInterface,KeyEventHandler { // 일반 WebView라면: webView.onPause() 및 webView.pauseTimers() } else { // 💡 다시 나타날 때: 다시 시작 -// binding.menuWeb?.onResume() + binding.lunaticBrowser.geckoWeb?.onResume() // 일반 WebView라면: webView.onResume() 및 webView.resumeTimers() } } @@ -506,15 +556,15 @@ class TokiFragment : Fragment(), PagedTextViewInterface,KeyEventHandler { } it.setOnGenericMotionListener(mOnGenericMotionListener) it.onPageStopCallback = { success-> - if (success && mPort != null) { - if (mPort != null) { - if (lastedUrl?.contains("youtube.com") == true) { - - } else { - - } - } - } +// if (success && mPort != null) { +//// if (mPort != null) { +//// if (lastedUrl?.contains("youtube.com") == true) { +//// +//// } else { +//// +//// } +//// } +// } } it.onPageStartCallback = { url -> // binding.lunaticBrowser.binding.progress.visibility = VISIBLE @@ -564,6 +614,7 @@ class TokiFragment : Fragment(), PagedTextViewInterface,KeyEventHandler { e.printStackTrace() } } + it.onPortMessageCallback it.onLocationChangeCallback = { url -> if (url?.startsWith("about") ?: true) { @@ -1282,7 +1333,7 @@ class TokiFragment : Fragment(), PagedTextViewInterface,KeyEventHandler { } catch (ex: JSONException) { throw RuntimeException(ex) } - mPort?.postMessage(message) + binding.lunaticBrowser.geckoWeb.mPort?.postMessage(message) // Blog.LOGD(log = "Successfully opened realm: ${realm.configuration.name}") } private fun sendViewerTouch(string: String) { @@ -1293,8 +1344,7 @@ class TokiFragment : Fragment(), PagedTextViewInterface,KeyEventHandler { } catch (ex: JSONException) { throw RuntimeException(ex) } - Blog.LOGE(Gson().toJson(message)) - mPort?.postMessage(message) + binding.lunaticBrowser.geckoWeb.mPort?.postMessage(message) } fun sendScrollDown(isUp: Boolean) { val message: JSONObject = JSONObject() @@ -1305,7 +1355,7 @@ class TokiFragment : Fragment(), PagedTextViewInterface,KeyEventHandler { throw RuntimeException(ex) } Blog.LOGE(Gson().toJson(message)) - mPort?.postMessage(message) + binding.lunaticBrowser.geckoWeb.mPort?.postMessage(message) } private fun goToHome() {