..
This commit is contained in:
@@ -79,6 +79,8 @@ import bums.lunatic.launcher.home.RssViewBuilder
|
||||
import bums.lunatic.launcher.model.RssData
|
||||
import bums.lunatic.launcher.model.RssDataType
|
||||
import bums.lunatic.launcher.tokiz.Comics
|
||||
import bums.lunatic.launcher.tokiz.Magnet
|
||||
import bums.lunatic.launcher.tokiz.Perplexity
|
||||
import bums.lunatic.launcher.tokiz.Twitter
|
||||
import bums.lunatic.launcher.tokiz.Webtoons
|
||||
import bums.lunatic.launcher.tokiz.Zota
|
||||
@@ -518,15 +520,6 @@ internal class LauncherActivity : CommonActivity() {
|
||||
binding.tabs.setOnCheckedChangeListener { g, id ->
|
||||
showContents(id)
|
||||
}
|
||||
binding.hidden.setOnLongClickListener {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragment_container, RssHome().apply {
|
||||
arguments = Bundle().apply {
|
||||
putBoolean("HIDDEN", true)
|
||||
}}
|
||||
).commit()
|
||||
true
|
||||
}
|
||||
|
||||
/* handle navigation back events */
|
||||
handleBackPress()
|
||||
@@ -559,6 +552,11 @@ internal class LauncherActivity : CommonActivity() {
|
||||
.replace(R.id.fragment_container, Comics())
|
||||
.commit()
|
||||
}
|
||||
R.id.perplexity ->{
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragment_container, Perplexity())
|
||||
.commit()
|
||||
}
|
||||
R.id.zota ->{
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragment_container, Zota())
|
||||
@@ -569,6 +567,11 @@ internal class LauncherActivity : CommonActivity() {
|
||||
.replace(R.id.fragment_container, Twitter())
|
||||
.commit()
|
||||
}
|
||||
R.id.magnet ->{
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragment_container, Magnet())
|
||||
.commit()
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,10 @@ class GeckoWeb : BWebview {
|
||||
super.setVisibility(visibility)
|
||||
decoViews.forEach { it.visibility = visibility }
|
||||
}
|
||||
|
||||
interface OnSave {
|
||||
fun saved()
|
||||
}
|
||||
var mOnSave : OnSave? = null
|
||||
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||
buildWeb()
|
||||
}
|
||||
@@ -173,6 +176,28 @@ class GeckoWeb : BWebview {
|
||||
Blog.LOGE(Gson().toJson(message))
|
||||
mPort?.postMessage(message)
|
||||
}
|
||||
fun sendSearch(keyword: String) {
|
||||
val message: JSONObject = JSONObject()
|
||||
try {
|
||||
message.put("type", "search")
|
||||
message.put("keyword", keyword)
|
||||
} catch (ex: JSONException) {
|
||||
throw RuntimeException(ex)
|
||||
}
|
||||
Blog.LOGE(Gson().toJson(message))
|
||||
mPort?.postMessage(message)
|
||||
}
|
||||
|
||||
fun sendSearchDo() {
|
||||
val message: JSONObject = JSONObject()
|
||||
try {
|
||||
message.put("type", "searchDo")
|
||||
} catch (ex: JSONException) {
|
||||
throw RuntimeException(ex)
|
||||
}
|
||||
Blog.LOGE(Gson().toJson(message))
|
||||
mPort?.postMessage(message)
|
||||
}
|
||||
|
||||
var mExtension: WebExtension? = null
|
||||
var mSession: GeckoSession? = null
|
||||
@@ -342,6 +367,7 @@ class GeckoWeb : BWebview {
|
||||
// 저장 성공 알림 등 후속 처리
|
||||
println("PDF 저장 완료: ${outputFile.absolutePath}")
|
||||
|
||||
mOnSave?.saved()
|
||||
}
|
||||
|
||||
fun downloadImage(context: Context, url: Uri, isGif : Boolean = false) {
|
||||
@@ -604,10 +630,11 @@ class GeckoWeb : BWebview {
|
||||
}
|
||||
|
||||
}
|
||||
fun saveMd() {
|
||||
fun saveMd(fast : Boolean? = false) {
|
||||
val message: JSONObject = JSONObject()
|
||||
try {
|
||||
message.put("type", "saveContent")
|
||||
message.put("fast", fast)
|
||||
} catch (ex: JSONException) {
|
||||
throw RuntimeException(ex)
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ internal class RssHome : Fragment() {
|
||||
var infosJob: Job? = null
|
||||
// var rssId = ""
|
||||
lateinit var mRssAdapter: RssItemAdapter
|
||||
|
||||
var mLastedQuery: RealmQuery<RssData>? = null
|
||||
var mRssDataResult: RealmResults<RssData>? = null
|
||||
|
||||
val mSimpleFingerGestures =
|
||||
@@ -199,7 +199,7 @@ internal class RssHome : Fragment() {
|
||||
return false
|
||||
}
|
||||
})
|
||||
var useHiddenMenu = false
|
||||
var useHiddenMenu = true
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
arguments?.let {
|
||||
@@ -319,39 +319,72 @@ internal class RssHome : Fragment() {
|
||||
|
||||
|
||||
fun ask() {
|
||||
val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
|
||||
builder.setTitle("Command Line")
|
||||
val viewInflated: View = LayoutInflater.from(requireContext())
|
||||
.inflate(R.layout.text_inpu_password, binding.root as ViewGroup?, false)
|
||||
val input = viewInflated.findViewById<View>(R.id.input) as EditText
|
||||
val privateMode = viewInflated.findViewById<CheckBox>(R.id.private_mode) as CheckBox
|
||||
(viewInflated.findViewById<CheckBox>(R.id.add_vote) as CheckBox)?.let{ it.visibility = View.GONE}
|
||||
(viewInflated.findViewById<CheckBox>(R.id.add_read) as CheckBox)?.let{ it.visibility = View.GONE}
|
||||
privateMode.setOnCheckedChangeListener { v,c->
|
||||
binding.geckoWeb.privateMode = c
|
||||
}
|
||||
privateMode.isChecked = true
|
||||
binding.geckoWeb.privateMode = true
|
||||
builder.setView(viewInflated)
|
||||
builder.setPositiveButton(
|
||||
android.R.string.ok,
|
||||
DialogInterface.OnClickListener { dialog, which ->
|
||||
dialog.dismiss()
|
||||
var command = input.editableText?.toString()
|
||||
if (command?.length ?: 0 > 0) {
|
||||
binding.geckoWeb.loadUrl(
|
||||
"aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=",
|
||||
"/?searchTerm=${command}"
|
||||
)
|
||||
} else {
|
||||
binding.geckoWeb.loadUrl("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=")
|
||||
}
|
||||
})
|
||||
builder.setNegativeButton(
|
||||
android.R.string.cancel,
|
||||
DialogInterface.OnClickListener { dialog, which -> dialog.cancel() })
|
||||
val bottomSheet = WebBottomSheet()
|
||||
bottomSheet.listener = object : WebBottomSheet.OnGoToWebListener{
|
||||
override fun enterSearch() {
|
||||
binding.geckoWeb.sendSearchDo()
|
||||
}
|
||||
override fun onGotoWeb(
|
||||
keyword: String,
|
||||
category: RssDataType,
|
||||
privateMode: Boolean
|
||||
) {
|
||||
when (category) {
|
||||
RssDataType.GOOGLE -> {
|
||||
if (binding.geckoWeb.lastedUrl?.contains("www.google") == true) {
|
||||
binding.geckoWeb.sendSearch(keyword)
|
||||
} else {
|
||||
binding.geckoWeb.loadUrl("https://www.google.com/", if (keyword.length ?: 0 > 0) { "/?q=${keyword}" } else { null })
|
||||
}
|
||||
binding.geckoWeb.privateMode = false
|
||||
}
|
||||
RssDataType.NAMU -> {
|
||||
if (binding.geckoWeb.lastedUrl?.contains("namu.wiki") == true) {
|
||||
binding.geckoWeb.sendSearch(keyword)
|
||||
} else {
|
||||
binding.geckoWeb.loadUrl("https://namu.wiki", if (keyword.length ?: 0 > 0) {"/Search?q=${keyword}"} else {null})
|
||||
}
|
||||
binding.geckoWeb.privateMode = false
|
||||
}
|
||||
RssDataType.NAVER -> {
|
||||
if (binding.geckoWeb.lastedUrl?.contains("naver") == true) {
|
||||
binding.geckoWeb.sendSearch(keyword)
|
||||
} else {
|
||||
binding.geckoWeb.loadUrl("https://search.naver.com/", if (keyword.length ?: 0 > 0) {"search.naver?where=nexearch&query==${keyword}"} else {null})
|
||||
}
|
||||
binding.geckoWeb.privateMode = false
|
||||
}
|
||||
RssDataType.NEWSFEED -> {
|
||||
if (binding.geckoWeb.lastedUrl?.contains("news.google") == true) {
|
||||
binding.geckoWeb.sendSearch(keyword)
|
||||
} else {
|
||||
binding.geckoWeb.loadUrl("https://news.google.com/", if (keyword.length ?: 0 > 0) {"search?q=${keyword}&hl=ko&gl=KR&ceid=KR%3Ako"} else {null})
|
||||
}
|
||||
binding.geckoWeb.privateMode = false
|
||||
}
|
||||
RssDataType.NEWS -> {
|
||||
if (binding.geckoWeb.lastedUrl?.contains("bigkinds") == true) {
|
||||
binding.geckoWeb.sendSearch(keyword)
|
||||
} else {
|
||||
binding.geckoWeb.loadUrl("https://www.bigkinds.or.kr/", if (keyword.length ?: 0 > 0) {"search?q=${keyword}&hl=ko&gl=KR&ceid=KR%3Ako"} else {null})
|
||||
}
|
||||
binding.geckoWeb.privateMode = false
|
||||
}
|
||||
RssDataType.PRIVATE -> {
|
||||
// if (binding.geckoWeb.lastedUrl?.contains("naver") == true) {
|
||||
//
|
||||
// } else {
|
||||
binding.geckoWeb.privateMode = privateMode
|
||||
binding.geckoWeb.loadUrl("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=", if (keyword.length ?: 0 > 0) {"/?searchTerm=${keyword}"} else {null})
|
||||
// }
|
||||
}
|
||||
else -> {
|
||||
|
||||
builder.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bottomSheet.show(childFragmentManager, "SearchBottomSheet")
|
||||
}
|
||||
|
||||
var currentRss : RssData? = null
|
||||
@@ -500,7 +533,25 @@ internal class RssHome : Fragment() {
|
||||
binding.privateBtn.visibility = View.GONE
|
||||
binding.search.visibility = View.GONE
|
||||
}
|
||||
|
||||
binding.geckoWeb?.mOnSave = object : GeckoWeb.OnSave{
|
||||
override fun saved() {
|
||||
currentRss?.originPage.let {
|
||||
Blog.LOGE("Arrow Center Click")
|
||||
WorkersDb.getRealm().apply {
|
||||
writeBlocking {
|
||||
val result = query<RssData>().query(
|
||||
if (imageView) "thumbnail == $0" else "originPage == $0",
|
||||
it
|
||||
).find()
|
||||
if (result.size > 0) {
|
||||
result.forEach { it.vote = true }
|
||||
}
|
||||
}
|
||||
}
|
||||
doNextPage()
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.hide.setOnClickListener {
|
||||
if (binding.geckoWeb.isVisible) {
|
||||
WorkersDb.getRealm().apply {
|
||||
@@ -583,22 +634,7 @@ internal class RssHome : Fragment() {
|
||||
}
|
||||
|
||||
fun vote() {
|
||||
binding.geckoWeb?.saveMd()
|
||||
currentRss?.originPage.let {
|
||||
Blog.LOGE("Arrow Center Click")
|
||||
WorkersDb.getRealm().apply {
|
||||
writeBlocking {
|
||||
val result = query<RssData>().query(
|
||||
if (imageView) "thumbnail == $0" else "originPage == $0",
|
||||
it
|
||||
).find()
|
||||
if (result.size > 0) {
|
||||
result.forEach { it.vote = true }
|
||||
}
|
||||
}
|
||||
}
|
||||
doNextPage()
|
||||
}
|
||||
binding.geckoWeb?.saveMd(true)
|
||||
}
|
||||
|
||||
|
||||
@@ -654,14 +690,11 @@ internal class RssHome : Fragment() {
|
||||
Blog.LOGE("updateQuery >>> ${q.description()}")
|
||||
infosJob?.cancel()
|
||||
commandHandler.removeCallbacks(infoUpdate)
|
||||
|
||||
mRssDataResult =
|
||||
q.sort("pubDate ", Sort.DESCENDING).limit(300).distinct("originPage", "title").find()
|
||||
mLastedQuery = q.sort("pubDate ", Sort.DESCENDING).limit(300).distinct("originPage", "title")
|
||||
mRssDataResult = mLastedQuery?.find()
|
||||
mRssDataResult?.asFlow()?.let { flow ->
|
||||
infosJob = CoroutineScope(Dispatchers.IO).launch {
|
||||
flow.collect { changes: ResultsChange<RssData> ->
|
||||
// when (changes) {
|
||||
// is InitialResults -> {
|
||||
synchronized(lasted) {
|
||||
commandHandler.removeCallbacks(infoUpdate)
|
||||
WorkersDb.getRealm().apply {
|
||||
@@ -670,17 +703,6 @@ internal class RssHome : Fragment() {
|
||||
}
|
||||
commandHandler.post(infoUpdate)
|
||||
}
|
||||
// }
|
||||
//
|
||||
// is UpdatedResults -> {
|
||||
// CoroutineScope(Dispatchers.Main).launch {
|
||||
// changes.changeRanges.forEach {
|
||||
// mRssAdapter.notifyItemRangeChanged(it.startIndex, it.length)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
}
|
||||
}
|
||||
infosJob?.start()
|
||||
@@ -771,18 +793,7 @@ internal class RssHome : Fragment() {
|
||||
|
||||
Blog.LOGE("onViewCreated()")
|
||||
|
||||
|
||||
// fragManager.addOnBackStackChangedListener {
|
||||
// Blog.LOGE("addOnBackStackChangedListener()")
|
||||
// shouldResume = if (fragManager.backStackEntryCount == 0) {
|
||||
// binding.root.visibility = View.VISIBLE
|
||||
// true
|
||||
// } else {
|
||||
// binding.root.visibility = View.GONE
|
||||
// false
|
||||
// }
|
||||
// }
|
||||
enableSwipeToDeleteAndUndo()
|
||||
// enableSwipeToDeleteAndUndo()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -64,17 +64,12 @@ class SearchBottomSheet : BottomSheetDialogFragment() {
|
||||
text = category.name
|
||||
isAllCaps = false
|
||||
setBackgroundResource(android.R.drawable.btn_default)
|
||||
|
||||
// 초기 색상(활성 상태 색 표시)
|
||||
updateButtonStyle(this, true)
|
||||
|
||||
setTextColor(Color.WHITE)
|
||||
setBackgroundResource(R.color.tabs_black)
|
||||
setOnClickListener {
|
||||
// 상태 반전
|
||||
val current = categoryStates[category.name] ?: true
|
||||
categoryStates[category.name] = !current
|
||||
|
||||
// 스타일 업데이트
|
||||
updateButtonStyle(this, !current)
|
||||
this.isSelected = !this.isSelected
|
||||
triggerSearchWithDebounce(inputKeyword.text.toString())
|
||||
}
|
||||
}
|
||||
@@ -113,15 +108,6 @@ class SearchBottomSheet : BottomSheetDialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateButtonStyle(button: Button, isActive: Boolean) {
|
||||
if (isActive) {
|
||||
button.setBackgroundColor(Color.parseColor("#FF9800")) // 활성화 색상
|
||||
button.setTextColor(Color.WHITE)
|
||||
} else {
|
||||
button.setBackgroundColor(Color.LTGRAY) // 비활성화 색상
|
||||
button.setTextColor(Color.DKGRAY)
|
||||
}
|
||||
}
|
||||
|
||||
private fun triggerSearchWithDebounce(keyword: String) {
|
||||
searchRunnable?.let { debounceHandler.removeCallbacks(it) }
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
package bums.lunatic.launcher.home
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Button
|
||||
import android.widget.CheckBox
|
||||
import android.widget.EditText
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RadioButton
|
||||
import android.widget.RadioGroup
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.children
|
||||
import bums.lunatic.launcher.R
|
||||
import bums.lunatic.launcher.model.RssDataType
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
|
||||
class WebBottomSheet : BottomSheetDialogFragment() {
|
||||
|
||||
private val debounceHandler = Handler(Looper.getMainLooper())
|
||||
private var searchRunnable: Runnable? = null
|
||||
private val debounceDelay = 300L // 0.3초 지연
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.bottom_sheet_web, container, false)
|
||||
}
|
||||
|
||||
interface OnGoToWebListener {
|
||||
fun onGotoWeb(keyword: String, category: RssDataType, privateMode : Boolean)
|
||||
fun enterSearch()
|
||||
}
|
||||
|
||||
var listener: OnGoToWebListener? = null
|
||||
|
||||
var selectedRssType : RssDataType = RssDataType.GOOGLE
|
||||
lateinit var privateMode : CheckBox
|
||||
lateinit var inputKeyword : EditText
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
inputKeyword = view.findViewById<EditText>(R.id.inputKeyword)
|
||||
val categoryContainer = view.findViewById<RadioGroup>(R.id.categoryContainer)
|
||||
privateMode = view.findViewById<CheckBox>(R.id.check_private) as CheckBox
|
||||
privateMode.setOnCheckedChangeListener {v,b->triggerSearchWithDebounce(inputKeyword.text.toString())}
|
||||
// 카테고리 목록
|
||||
val categories = listOf<RssDataType>(RssDataType.GOOGLE, RssDataType.NAVER,RssDataType.NEWS,RssDataType.NEWSFEED,RssDataType.NAMU,RssDataType.PRIVATE)
|
||||
|
||||
// 버튼 동적 생성
|
||||
categoryContainer.removeAllViews()
|
||||
|
||||
categoryContainer.setOnCheckedChangeListener { g,checked ->
|
||||
((g.findViewById<RadioButton>(checked))?.tag as? RssDataType)?.let {
|
||||
selectedRssType = it
|
||||
}
|
||||
}
|
||||
|
||||
for (category in categories) {
|
||||
val btn = RadioButton(requireContext()).apply {
|
||||
layoutParams = RadioGroup.LayoutParams(RadioGroup.LayoutParams.WRAP_CONTENT,RadioGroup.LayoutParams.MATCH_PARENT)
|
||||
setPadding(50,2,50,2)
|
||||
tag = category
|
||||
text = category.name
|
||||
isAllCaps = false
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
setButtonIcon(null)
|
||||
}
|
||||
setTextColor(Color.WHITE)
|
||||
setBackgroundResource(R.color.tabs_black)
|
||||
setOnClickListener {
|
||||
triggerSearchWithDebounce(inputKeyword.text.toString())
|
||||
}
|
||||
}
|
||||
categoryContainer.addView(btn)
|
||||
}
|
||||
|
||||
(categoryContainer.getChildAt(0) as? RadioButton)?.let { it.isChecked = true }
|
||||
|
||||
inputKeyword.requestFocus()
|
||||
// 키보드 강제 오픈
|
||||
inputKeyword.postDelayed( {
|
||||
val imm = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.showSoftInput(inputKeyword, InputMethodManager.SHOW_IMPLICIT)
|
||||
},150L)
|
||||
|
||||
// EditText 입력 실시간 감지 + debounce
|
||||
inputKeyword.addTextChangedListener(object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
triggerSearchWithDebounce(s.toString())
|
||||
}
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
|
||||
})
|
||||
// 키보드 "검색" 액션 처리
|
||||
inputKeyword.setOnEditorActionListener { _, actionId, _ ->
|
||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||
val keyword = inputKeyword.text.toString()
|
||||
if (keyword.isNotEmpty()) {
|
||||
triggerSearchWithDebounce(keyword)
|
||||
dismiss() // 필요 시 닫기
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun triggerSearchWithDebounce(keyword: String) {
|
||||
searchRunnable?.let { debounceHandler.removeCallbacks(it) }
|
||||
searchRunnable = Runnable {
|
||||
listener?.onGotoWeb(keyword, selectedRssType, privateMode.isChecked)
|
||||
}
|
||||
debounceHandler.postDelayed(searchRunnable!!, debounceDelay)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
// 전체 창 높이를 키보드에 맞게 조정
|
||||
dialog?.window?.setSoftInputMode(
|
||||
WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE or
|
||||
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ enum class RssDataType {
|
||||
TORRENT,
|
||||
YOUTUBE,
|
||||
NEWSFEED,
|
||||
NEWS,
|
||||
TAGS,
|
||||
REDDIT,
|
||||
REDDIT_NSFW,
|
||||
@@ -19,6 +20,9 @@ enum class RssDataType {
|
||||
RULIWEB,
|
||||
CLIEN,
|
||||
THEQOO,
|
||||
NAVER,
|
||||
GOOGLE,
|
||||
NAMU,
|
||||
ARCA;
|
||||
|
||||
fun getResId() = when (this) {
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
package bums.lunatic.launcher.tokiz
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.text.InputType
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.RelativeSizeSpan
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.View.GONE
|
||||
import android.view.View.OnTouchListener
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.View.inflate
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
|
||||
import bums.lunatic.launcher.R
|
||||
import bums.lunatic.launcher.tokiz.common.PairArray
|
||||
import bums.lunatic.launcher.tokiz.common.TouchArea
|
||||
import bums.lunatic.launcher.tokiz.common.colorz
|
||||
import bums.lunatic.launcher.tokiz.common.getIndex
|
||||
import bums.lunatic.launcher.tokiz.common.typesfacez
|
||||
import bums.lunatic.launcher.tokiz.data.HistoryManager
|
||||
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
|
||||
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
|
||||
import bums.lunatic.launcher.tokiz.data.model.PageInfosJ
|
||||
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
|
||||
import bums.lunatic.launcher.tokiz.data.model.LastInfo
|
||||
import bums.lunatic.launcher.tokiz.data.model.PortMessage
|
||||
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
|
||||
import bums.lunatic.launcher.tokiz.dialog.DefaultList
|
||||
import bums.lunatic.launcher.tokiz.view.JxEvent
|
||||
import bums.lunatic.launcher.tokiz.view.PagedTextLayout
|
||||
import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface
|
||||
import bums.lunatic.launcher.databinding.BooktokiBinding
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
import com.google.gson.Gson
|
||||
import io.realm.kotlin.Realm
|
||||
import io.realm.kotlin.UpdatePolicy
|
||||
import io.realm.kotlin.ext.copyFromRealm
|
||||
import io.realm.kotlin.ext.query
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import org.mozilla.gecko.util.ThreadUtils
|
||||
import org.mozilla.geckoview.GeckoResult
|
||||
import org.mozilla.geckoview.GeckoSession
|
||||
import org.mozilla.geckoview.MediaSession
|
||||
import org.mozilla.geckoview.WebExtension
|
||||
import org.mozilla.geckoview.WebExtension.MessageDelegate
|
||||
import org.mozilla.geckoview.WebExtension.PortDelegate
|
||||
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
|
||||
import org.mozilla.geckoview.WebRequestError
|
||||
import java.lang.System.currentTimeMillis
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.List
|
||||
import kotlin.collections.MutableList
|
||||
import kotlin.collections.arrayListOf
|
||||
import kotlin.collections.first
|
||||
import kotlin.collections.isNotEmpty
|
||||
import kotlin.collections.last
|
||||
import kotlin.collections.sortBy
|
||||
import kotlin.random.Random
|
||||
import kotlin.text.contains
|
||||
import kotlin.text.endsWith
|
||||
import kotlin.text.equals
|
||||
import kotlin.text.replace
|
||||
import kotlin.text.split
|
||||
import kotlin.text.startsWith
|
||||
import kotlin.text.toInt
|
||||
import kotlin.text.toRegex
|
||||
import kotlin.text.trim
|
||||
|
||||
|
||||
class Magnet : BaseToki(), PagedTextViewInterface {
|
||||
// "https://btsearch.love/
|
||||
override val contentsType = "btsearch"
|
||||
override var lastNumber : Int = 143
|
||||
override val webcontentsName : String = "btsearch"
|
||||
override val afterDot = "love"
|
||||
override fun getLastedDoamin(): String {
|
||||
return String.format("https://%s.%s", webcontentsName, afterDot)
|
||||
}
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
loadLastInfo()
|
||||
}
|
||||
|
||||
override fun onTouch(touchArea: TouchArea) {
|
||||
Blog.LOGD(log = "onTouch ${touchArea}")
|
||||
when (touchArea) {
|
||||
TouchArea.Center -> {
|
||||
|
||||
}
|
||||
|
||||
TouchArea.Right -> {
|
||||
actionNextEvent()
|
||||
}
|
||||
|
||||
TouchArea.Left -> {
|
||||
actionPrevEvent()
|
||||
}
|
||||
|
||||
TouchArea.DoubleRight -> {
|
||||
actionNextEvent(true)
|
||||
}
|
||||
|
||||
TouchArea.DoubleLeft -> {
|
||||
actionPrevEvent(true)
|
||||
}
|
||||
else -> {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onLongClick() {
|
||||
Blog.LOGD(log = "onLongClick")
|
||||
|
||||
}
|
||||
|
||||
override fun onSwipeLeft(count: Int) {
|
||||
Blog.LOGD(log = "onSwipeLeft ${count}")
|
||||
actionNextEvent(count > 1)
|
||||
|
||||
}
|
||||
|
||||
override fun onSwipeRight(count: Int) {
|
||||
Blog.LOGD(log = "onSwipeRight ${count}")
|
||||
actionPrevEvent(count > 1)
|
||||
}
|
||||
|
||||
override fun onSwipeUp(touchCount: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onSwipeDown(touchCount: Int) {
|
||||
if (touchCount == 2) {
|
||||
if (binding.pagedLayer.isVisible) {
|
||||
binding.pagedLayer.visibility = GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTimeoverTouch() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package bums.lunatic.launcher.tokiz
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.text.InputType
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.RelativeSizeSpan
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.View.GONE
|
||||
import android.view.View.OnTouchListener
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.View.inflate
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
|
||||
import bums.lunatic.launcher.R
|
||||
import bums.lunatic.launcher.tokiz.common.PairArray
|
||||
import bums.lunatic.launcher.tokiz.common.TouchArea
|
||||
import bums.lunatic.launcher.tokiz.common.colorz
|
||||
import bums.lunatic.launcher.tokiz.common.getIndex
|
||||
import bums.lunatic.launcher.tokiz.common.typesfacez
|
||||
import bums.lunatic.launcher.tokiz.data.HistoryManager
|
||||
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
|
||||
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
|
||||
import bums.lunatic.launcher.tokiz.data.model.PageInfosJ
|
||||
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
|
||||
import bums.lunatic.launcher.tokiz.data.model.LastInfo
|
||||
import bums.lunatic.launcher.tokiz.data.model.PortMessage
|
||||
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
|
||||
import bums.lunatic.launcher.tokiz.dialog.DefaultList
|
||||
import bums.lunatic.launcher.tokiz.view.JxEvent
|
||||
import bums.lunatic.launcher.tokiz.view.PagedTextLayout
|
||||
import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface
|
||||
import bums.lunatic.launcher.databinding.BooktokiBinding
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
import com.google.gson.Gson
|
||||
import io.realm.kotlin.Realm
|
||||
import io.realm.kotlin.UpdatePolicy
|
||||
import io.realm.kotlin.ext.copyFromRealm
|
||||
import io.realm.kotlin.ext.query
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import org.mozilla.gecko.util.ThreadUtils
|
||||
import org.mozilla.geckoview.GeckoResult
|
||||
import org.mozilla.geckoview.GeckoSession
|
||||
import org.mozilla.geckoview.MediaSession
|
||||
import org.mozilla.geckoview.WebExtension
|
||||
import org.mozilla.geckoview.WebExtension.MessageDelegate
|
||||
import org.mozilla.geckoview.WebExtension.PortDelegate
|
||||
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
|
||||
import org.mozilla.geckoview.WebRequestError
|
||||
import java.lang.System.currentTimeMillis
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.List
|
||||
import kotlin.collections.MutableList
|
||||
import kotlin.collections.arrayListOf
|
||||
import kotlin.collections.first
|
||||
import kotlin.collections.isNotEmpty
|
||||
import kotlin.collections.last
|
||||
import kotlin.collections.sortBy
|
||||
import kotlin.random.Random
|
||||
import kotlin.text.contains
|
||||
import kotlin.text.endsWith
|
||||
import kotlin.text.equals
|
||||
import kotlin.text.replace
|
||||
import kotlin.text.split
|
||||
import kotlin.text.startsWith
|
||||
import kotlin.text.toInt
|
||||
import kotlin.text.toRegex
|
||||
import kotlin.text.trim
|
||||
|
||||
|
||||
class Perplexity : BaseToki(), PagedTextViewInterface {
|
||||
// "https://btsearch.love/
|
||||
override val contentsType = "perplexity"
|
||||
override var lastNumber : Int = 143
|
||||
override val webcontentsName : String = "www.perplexity"
|
||||
override val afterDot = "ai"
|
||||
override fun getLastedDoamin(): String {
|
||||
return String.format("https://%s.%s", webcontentsName, afterDot)
|
||||
}
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
loadLastInfo()
|
||||
}
|
||||
|
||||
override fun onTouch(touchArea: TouchArea) {
|
||||
Blog.LOGD(log = "onTouch ${touchArea}")
|
||||
when (touchArea) {
|
||||
TouchArea.Center -> {
|
||||
|
||||
}
|
||||
|
||||
TouchArea.Right -> {
|
||||
actionNextEvent()
|
||||
}
|
||||
|
||||
TouchArea.Left -> {
|
||||
actionPrevEvent()
|
||||
}
|
||||
|
||||
TouchArea.DoubleRight -> {
|
||||
actionNextEvent(true)
|
||||
}
|
||||
|
||||
TouchArea.DoubleLeft -> {
|
||||
actionPrevEvent(true)
|
||||
}
|
||||
else -> {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onLongClick() {
|
||||
Blog.LOGD(log = "onLongClick")
|
||||
|
||||
}
|
||||
|
||||
override fun onSwipeLeft(count: Int) {
|
||||
Blog.LOGD(log = "onSwipeLeft ${count}")
|
||||
actionNextEvent(count > 1)
|
||||
|
||||
}
|
||||
|
||||
override fun onSwipeRight(count: Int) {
|
||||
Blog.LOGD(log = "onSwipeRight ${count}")
|
||||
actionPrevEvent(count > 1)
|
||||
}
|
||||
|
||||
override fun onSwipeUp(touchCount: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onSwipeDown(touchCount: Int) {
|
||||
if (touchCount == 2) {
|
||||
if (binding.pagedLayer.isVisible) {
|
||||
binding.pagedLayer.visibility = GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTimeoverTouch() {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user