...
This commit is contained in:
@@ -731,7 +731,7 @@ internal class LauncherActivity : CommonActivity() {
|
||||
when(currentFragment) {
|
||||
is RssHome ->{
|
||||
if (currentFragment.binding.layoutRssSummary.root.isVisible) {
|
||||
currentFragment.openGecko("")
|
||||
currentFragment.openGecko(rssData = currentFragment.lasted.randomOrNull())
|
||||
} else {
|
||||
currentFragment.doNextPage()
|
||||
}
|
||||
|
||||
@@ -24,12 +24,18 @@ import android.content.Context
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import bums.lunatic.launcher.helpers.PrefHelper
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
import com.squareup.picasso.OkHttp3Downloader
|
||||
import com.squareup.picasso.Picasso
|
||||
import kr.lunaticbum.Base
|
||||
import okhttp3.Cache
|
||||
import okhttp3.OkHttpClient
|
||||
import org.json.JSONObject
|
||||
import org.mozilla.geckoview.ExperimentDelegate
|
||||
import org.mozilla.geckoview.GeckoResult
|
||||
import org.mozilla.geckoview.GeckoRuntime
|
||||
import org.mozilla.geckoview.GeckoRuntimeSettings
|
||||
import java.io.File
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
internal class LunaticLauncher : Application() {
|
||||
@@ -43,6 +49,33 @@ internal class LunaticLauncher : Application() {
|
||||
appContext = this
|
||||
Base.initialize(this)
|
||||
PrefHelper.initialize(this)
|
||||
|
||||
val cacheSize = 1024L * 1024 * 1024 // 60MB
|
||||
val cache = Cache(File(this.filesDir, "picasso-cache"), cacheSize)
|
||||
val okHttpClient = OkHttpClient.Builder()
|
||||
.cache(cache)
|
||||
.addInterceptor { chain ->
|
||||
val newRequest = chain.request().newBuilder()
|
||||
.addHeader("Host","images.ijavtorrent.com")
|
||||
.addHeader("User-Agent","Mozilla/5.0 (Android 15; Mobile; rv:139.0) Gecko/139.0 Firefox/139.0")
|
||||
.addHeader("Accept","image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5")
|
||||
.addHeader("Accept-Language","ko-KR,en-US;q=0.5")
|
||||
.addHeader("Accept-Encoding","gzip, deflate, br, zstd")
|
||||
.addHeader("Referer","https://ijavtorrent.com/")
|
||||
.build()
|
||||
chain.proceed(newRequest)
|
||||
}
|
||||
.connectTimeout(10, TimeUnit.SECONDS) // 연결 타임아웃
|
||||
.readTimeout(30, TimeUnit.SECONDS) // 읽기 타임아웃
|
||||
.writeTimeout(30, TimeUnit.SECONDS) // 쓰기 타임아웃
|
||||
.build()
|
||||
|
||||
val picasso = Picasso.Builder(this)
|
||||
.downloader(OkHttp3Downloader(okHttpClient))
|
||||
.build()
|
||||
|
||||
// 앱 전체에 해당 인스턴스를 사용하려면
|
||||
Picasso.setSingletonInstance(picasso)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -482,8 +482,12 @@ class GeckoWeb : BWebview {
|
||||
copyToRealm(it, UpdatePolicy.ALL)
|
||||
}
|
||||
}
|
||||
Toast.makeText(context, "Received Msg privates form ${lPortMessage.currentPage} data => ${lPortMessage.privates?.size ?: 0}", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
"Cookies"->{
|
||||
Blog.LOGE("cookies >>> ${lPortMessage.cookies}")
|
||||
}
|
||||
"PagerContents" -> {
|
||||
if (lPortMessage.contents?.isNotEmpty() == true) {
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package bums.lunatic.launcher.home
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
@@ -30,9 +31,11 @@ import android.view.LayoutInflater
|
||||
import android.view.PointerIcon
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.NonNull
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.databinding.BindingAdapter
|
||||
import androidx.fragment.app.Fragment
|
||||
@@ -64,6 +67,7 @@ import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.google.android.material.imageview.ShapeableImageView
|
||||
import com.google.gson.Gson
|
||||
import com.squareup.picasso.Picasso
|
||||
import io.realm.kotlin.UpdatePolicy
|
||||
import io.realm.kotlin.ext.query
|
||||
import io.realm.kotlin.notifications.InitialResults
|
||||
@@ -76,6 +80,8 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
|
||||
|
||||
internal class RssHome : Fragment() {
|
||||
@@ -113,7 +119,7 @@ internal class RssHome : Fragment() {
|
||||
): Boolean {
|
||||
Blog.LOGE("")
|
||||
if (imageView){
|
||||
openGecko("")
|
||||
openGecko(rssData = lasted.randomOrNull())
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -125,7 +131,7 @@ internal class RssHome : Fragment() {
|
||||
gestureDistance: Double
|
||||
): Boolean {
|
||||
if (imageView){
|
||||
openGecko("")
|
||||
openGecko(rssData = lasted.randomOrNull())
|
||||
}
|
||||
Blog.LOGE("")
|
||||
return true
|
||||
@@ -217,7 +223,7 @@ internal class RssHome : Fragment() {
|
||||
RssDataType.REDDIT_NSFW,RssDataType.PRIVATE -> {
|
||||
v.findViewById<ShapeableImageView>(R.id.circle_preview)?.let {
|
||||
if (RssDataType.PRIVATE.equals(rss.category()) && imageView) {
|
||||
openGecko("")
|
||||
openGecko(rssData = lasted.randomOrNull())
|
||||
} else {
|
||||
if (it.visibility == View.GONE) {
|
||||
it.visibility = View.VISIBLE
|
||||
@@ -257,62 +263,88 @@ internal class RssHome : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
fun openGecko(originPage: String) {
|
||||
if (!imageView) {
|
||||
rssId = originPage
|
||||
targetList.clear()
|
||||
|
||||
var setString = hashSetOf<String>()
|
||||
setString.addAll(rssList)
|
||||
setString.removeAll { it.equals(rssId) }
|
||||
|
||||
targetList.addAll(setString)
|
||||
binding.geckoWeb.loadUrl(rssId)
|
||||
} else {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||
if (lasted.size > 0) {
|
||||
lasted?.removeFirst()?.let {
|
||||
Blog.LOGE("removeFirst >>> ${Gson().toJson(it)}")
|
||||
binding.layoutRssSummary.root.visibility = View.VISIBLE
|
||||
it.title()?.let {
|
||||
Blog.LOGE(it)
|
||||
binding.layoutRssSummary.title.text = it
|
||||
}
|
||||
|
||||
it.description()?.let {
|
||||
Blog.LOGE(it)
|
||||
binding.layoutRssSummary.desc.text = it
|
||||
}
|
||||
it.getMagnet().let {
|
||||
Blog.LOGE(it)
|
||||
binding.layoutRssSummary.link.text = it
|
||||
}
|
||||
it.thumbnailUrl().let {
|
||||
Blog.LOGE(it)
|
||||
loadImage(binding.layoutRssSummary.cover, it)
|
||||
}
|
||||
it.getScreen().let {
|
||||
Blog.LOGE(it)
|
||||
loadImage(binding.layoutRssSummary.screen, it)
|
||||
}
|
||||
}
|
||||
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
|
||||
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.home.performClick()
|
||||
binding.geckoWeb.loadUrl("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=")
|
||||
}
|
||||
})
|
||||
builder.setNegativeButton(android.R.string.cancel,
|
||||
DialogInterface.OnClickListener { dialog, which -> dialog.cancel() })
|
||||
|
||||
builder.show()
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
fun openGecko(originPage: String? = null, rssData: RssData? = null) {
|
||||
if (!imageView) {
|
||||
originPage?.let {
|
||||
rssId = originPage
|
||||
targetList.clear()
|
||||
|
||||
var setString = hashSetOf<String>()
|
||||
setString.addAll(rssList)
|
||||
setString.removeAll { it.equals(rssId) }
|
||||
|
||||
targetList.addAll(setString)
|
||||
binding.geckoWeb.loadUrl(rssId)
|
||||
}
|
||||
} else {
|
||||
rssData?.let {
|
||||
Blog.LOGE("removeFirst >>> ${Gson().toJson(it)}")
|
||||
binding.layoutRssSummary.title.tag = it
|
||||
binding.layoutRssSummary.root.visibility = View.VISIBLE
|
||||
it.title()?.let {
|
||||
Blog.LOGE(it)
|
||||
binding.layoutRssSummary.title.text = it
|
||||
}
|
||||
|
||||
it.pubDate()?.let {
|
||||
Blog.LOGE("")
|
||||
binding.layoutRssSummary.date.text =
|
||||
SimpleDateFormat("yyyy.MM.dd HH-mm").format(Date(it))
|
||||
}
|
||||
binding.layoutRssSummary.desc.tag = it
|
||||
it.description()?.let {
|
||||
Blog.LOGE(it)
|
||||
binding.layoutRssSummary.desc.text = it
|
||||
}
|
||||
binding.layoutRssSummary.link.tag = it
|
||||
it.getMagnet().let {
|
||||
Blog.LOGE(it)
|
||||
binding.layoutRssSummary.link.text = it
|
||||
}
|
||||
binding.layoutRssSummary.cover.tag = it
|
||||
it.thumbnailUrl().let {
|
||||
Blog.LOGE(it)
|
||||
loadImage(binding.layoutRssSummary.cover, it)
|
||||
binding.layoutRssSummary.coverLink.text = it
|
||||
|
||||
}
|
||||
binding.layoutRssSummary.screen.tag = it
|
||||
it.getScreen().let {
|
||||
Blog.LOGE(it)
|
||||
loadImage(binding.layoutRssSummary.screen, it)
|
||||
binding.layoutRssSummary.screenLink.text = it
|
||||
}
|
||||
}
|
||||
|
||||
// targetList.clear()
|
||||
// lasted?.forEach {
|
||||
// it.thumbnail?.let {
|
||||
// targetList.add(it)
|
||||
// }
|
||||
// }
|
||||
// rssId = targetList.removeAt(0)
|
||||
// binding.geckoWeb.loadUrl(rssId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@@ -347,7 +379,7 @@ internal class RssHome : Fragment() {
|
||||
|
||||
}
|
||||
binding.geckoWeb.visibility = View.GONE
|
||||
binding.geckoWeb.loadUrl("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=")
|
||||
ask()
|
||||
}
|
||||
|
||||
binding.hide.setOnClickListener {
|
||||
@@ -384,8 +416,19 @@ internal class RssHome : Fragment() {
|
||||
binding.prv.setOnClickListener {
|
||||
queryPrevate()
|
||||
}
|
||||
binding.layoutRssSummary.link.setOnClickListener {
|
||||
(it.tag as? RssData)?.let {
|
||||
appendReadCount(it, 1, true)
|
||||
}
|
||||
}
|
||||
binding.layoutRssSummary.title.setOnClickListener {
|
||||
(it.tag as? RssData)?.let {
|
||||
appendReadCount(it, nomoreShowCount, false)
|
||||
openGecko(rssData = lasted.randomOrNull())
|
||||
}
|
||||
}
|
||||
binding.layoutRssSummary.close.setOnClickListener {
|
||||
binding.home.performClick()
|
||||
binding.layoutRssSummary.root.visibility = View.GONE
|
||||
}
|
||||
|
||||
queryInfos()
|
||||
@@ -461,7 +504,7 @@ internal class RssHome : Fragment() {
|
||||
delete(
|
||||
query<RssData>()
|
||||
.query("pubDate < $0", beforeDay(30))
|
||||
// .query("category != $0 AND category != $1 ", RssDataType.GURU.name, RssDataType.MOST.name)
|
||||
.query("category != $0 AND category != $1 ", RssDataType.PRIVATE.name, RssDataType.REDDIT_NSFW.name)
|
||||
.query("vote != $0", true).find()
|
||||
)
|
||||
}
|
||||
@@ -554,6 +597,20 @@ internal class RssHome : Fragment() {
|
||||
lasted?.let { mRssAdapter.updateData(it) }
|
||||
}
|
||||
|
||||
fun appendReadCount(rss: RssData, appendCount : Int, vote : Boolean = false) {
|
||||
WorkersDb.getRealm().apply {
|
||||
writeBlocking {
|
||||
var results = query<RssData>("originPage == $0", rss.originPage).find()
|
||||
results.forEach { rss ->
|
||||
if (false == rss.vote) {
|
||||
rss.vote = vote
|
||||
}
|
||||
rss.read = rss.read.plus(appendCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun enableSwipeToDeleteAndUndo() {
|
||||
val swipeToDeleteCallback: SwipeToDeleteCallback =
|
||||
object : SwipeToDeleteCallback(requireContext()) {
|
||||
@@ -619,17 +676,40 @@ internal class RssHome : Fragment() {
|
||||
}
|
||||
|
||||
|
||||
@BindingAdapter("imageUrl")
|
||||
fun loadImage(imageView: ImageView, url: String?) {
|
||||
url?.let {
|
||||
if (it.length > 4) {
|
||||
Blog.LOGE("loadImage >>> $it")
|
||||
Glide.with(imageView.context)
|
||||
.load(url)
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.fitCenter()
|
||||
.into(imageView)
|
||||
imageView.visibility = View.VISIBLE
|
||||
|
||||
fun loadImage(imageView: ImageView, url: String?, retryCount: Int = 3) {
|
||||
Picasso.get().cancelRequest(imageView)
|
||||
url?.let { url ->
|
||||
if (url.length > 4) {
|
||||
try {
|
||||
imageView.visibility = View.VISIBLE
|
||||
imageView.setAlpha(0.05f)
|
||||
Blog.LOGE("loadImage >>> $url")
|
||||
Picasso.get()
|
||||
.load(url)
|
||||
.into(imageView, object : com.squareup.picasso.Callback {
|
||||
override fun onSuccess() {
|
||||
imageView.setAlpha(0.05f)
|
||||
}
|
||||
|
||||
override fun onError(e: Exception?) {
|
||||
e?.printStackTrace()
|
||||
if (retryCount > 0) {
|
||||
// 메인 스레드에서 재시도
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
loadImage(imageView, url, retryCount - 1)
|
||||
}
|
||||
} else {
|
||||
// 3회 모두 실패: 대체 이미지 표시
|
||||
imageView.setImageResource(R.drawable.ic_info)
|
||||
imageView.setAlpha(1f)
|
||||
}
|
||||
}
|
||||
})
|
||||
imageView.contentDescription = url
|
||||
}catch (e: Exception){
|
||||
|
||||
}
|
||||
} else {
|
||||
imageView.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ class PortMessage {
|
||||
var msg : String? = null
|
||||
var contents : String? = null
|
||||
var privates : ArrayList<RssData>? = null
|
||||
var currentPage : String? = null
|
||||
var cookies : String? = null
|
||||
}
|
||||
class BookContents {
|
||||
var chapterTitle : String? = null
|
||||
|
||||
@@ -160,11 +160,14 @@ open class BWebview : GeckoView {
|
||||
|
||||
var lastDomain : String = ""
|
||||
|
||||
fun loadUrl(url: String) {
|
||||
fun loadUrl(url: String, param : String? = null) {
|
||||
var nUrl = url
|
||||
Blog.LOGE("url >>>> ${url}")
|
||||
if (url.endsWith("=")) {
|
||||
nUrl = String(Base64.getMimeDecoder().decode(url.toByteArray()))
|
||||
param?.let {
|
||||
nUrl = nUrl.plus(param)
|
||||
}
|
||||
} else if (url.startsWith("http") == false) {
|
||||
nUrl = lastDomain
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ object WorkersDb {
|
||||
}
|
||||
}
|
||||
fun getPrivate() = getRealm().query<RssData>().query("category == $0 ",
|
||||
RssDataType.PRIVATE.name).distinct("originPage", "title").sort("pubDate", Sort.DESCENDING)
|
||||
RssDataType.PRIVATE.name).distinct("originPage", "title").query("read < $0", 5).query("vote != $0", true)
|
||||
|
||||
fun getVotedRss() = getRealm().query<RssData>().query("vote == $0", true).distinct("originPage", "title")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user