This commit is contained in:
lunaticbum 2025-07-27 19:15:12 +09:00
parent ee7cee7638
commit 867ee66499
7 changed files with 181 additions and 58 deletions

View File

@ -423,7 +423,8 @@ function gotoNext() {
if(e.hasAttribute("href") &&
(
(e.getAttribute("href").search("page=2") > -1 && location.href.search("page") < 0) ||
(e.getAttribute("href").search("page=3") > -1 && location.href.search("page=2") > 0)
(e.getAttribute("href").search("page=3") > -1 && location.href.search("page=2") > 0) ||
(e.getAttribute("href").search("page=4") > -1 && location.href.search("page=3") > 0)
)) {
targetElement = e
@ -432,9 +433,9 @@ function gotoNext() {
if(targetElement !== null) {
targetElement.click()
} else {
location.href = "https://naver.com"
// location.href = "https://naver.com"
}
}, 5000);
}, 15000);
}
} catch (e) {

View File

@ -582,6 +582,7 @@ internal class LauncherActivity : CommonActivity() {
@SuppressLint("NewApi", "MissingPermission")
override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen()
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
lActivity = this
mWorkManager = WorkManager.getInstance(this)
DynamicColors.applyToActivityIfAvailable(this)

View File

@ -2,6 +2,7 @@ package bums.lunatic.launcher.home
import android.app.DownloadManager
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
@ -23,12 +24,17 @@ 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.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.EditText
import android.widget.ProgressBar
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
import bums.lunatic.launcher.R
import bums.lunatic.launcher.tokiz.data.HistoryManager
import bums.lunatic.launcher.tokiz.data.model.History
import bums.lunatic.launcher.tokiz.data.model.PortMessage
@ -397,12 +403,30 @@ class GeckoWeb : BWebview {
if(it.host?.let { it1 -> lastedUrl?.contains(it1, true) } == true) {
loadUrl(uri)
} else {
context.startActivity(Intent().apply {
action = Intent.ACTION_VIEW
flags = Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS.or(FLAG_ACTIVITY_CLEAR_TOP).or(
FLAG_ACTIVITY_NEW_TASK)
data = it
})
val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder.setTitle("Move To")
val viewInflated: View = LayoutInflater.from(context)
.inflate(R.layout.text_inpu_password, null, false)
val input = viewInflated.findViewById<View>(R.id.input) as EditText
input.visibility = View.GONE
builder.setView(viewInflated)
builder.setPositiveButton(
android.R.string.ok,
DialogInterface.OnClickListener { dialog, which ->
dialog.dismiss()
context.startActivity(Intent().apply {
action = Intent.ACTION_VIEW
flags = Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS.or(FLAG_ACTIVITY_CLEAR_TOP).or(
FLAG_ACTIVITY_NEW_TASK)
data = it
})
})
builder.setNegativeButton(
android.R.string.cancel,
DialogInterface.OnClickListener { dialog, which -> dialog.cancel() })
builder.show()
}
}
return super.onNewSession(session, uri)
@ -469,16 +493,9 @@ class GeckoWeb : BWebview {
"SHOWVIEWER" -> {
}
"PRIVATES"->{
lPortMessage.privates?.forEach {
Blog.LOGE("Item screenshots >>> ${it.getScreen()}")
it.pubDate = afterDay(it.pubDate)
// WorkersDb.insertData(it)
getRealm().apply {
this.writeBlocking {
copyToRealm(it, UpdatePolicy.ALL)
}
}
context.toast("Received Msg privates form ${lPortMessage.currentPage} data => ${lPortMessage.privates?.size ?: 0}")
lPortMessage.privates?.let {
context.toast("Received Msg privates form ${lPortMessage.currentPage} data => ${it?.size ?: 0}")
WorkersDb.insertBulkData(it)
}
}
"Cookies"->{

View File

@ -24,7 +24,6 @@ import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
@ -40,7 +39,6 @@ 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
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.DividerItemDecoration
@ -65,17 +63,13 @@ import bums.lunatic.launcher.utils.SimpleFingerGestures
import bums.lunatic.launcher.utils.beforeDay
import bums.lunatic.launcher.utils.beforeOneDay
import bums.lunatic.launcher.workers.WorkersDb
import bums.lunatic.launcher.workers.WorkersDb.prvClear
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import bums.lunatic.launcher.workers.WorkersDb.getRealm
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
import io.realm.kotlin.notifications.ResultsChange
import io.realm.kotlin.notifications.UpdatedResults
import io.realm.kotlin.query.RealmQuery
import io.realm.kotlin.query.RealmResults
import io.realm.kotlin.query.Sort
@ -85,7 +79,6 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.time.TimeSource
internal class RssHome : Fragment() {
@ -233,7 +226,7 @@ internal class RssHome : Fragment() {
when (rss.category()) {
RssDataType.REDDIT_NSFW, RssDataType.PRIVATE -> {
v.findViewById<ShapeableImageView>(R.id.circle_preview)?.let {
if (RssDataType.PRIVATE.equals(rss.category()) && imageView) {
if (RssDataType.PRIVATE.equals(rss.category())) {
openGecko(rssData = rss)
} else {
if (it.visibility == View.GONE) {
@ -250,7 +243,7 @@ internal class RssHome : Fragment() {
data = Uri.parse(rss.originPage)
})
} else {
openGecko(rss.originPage())
openGecko(rss)
}
}
}
@ -262,7 +255,7 @@ internal class RssHome : Fragment() {
}
RssDataType.DOTAX -> {
openGecko(rss.originPage())
openGecko(rss)
}
RssDataType.YOUTUBE -> {
@ -270,15 +263,43 @@ internal class RssHome : Fragment() {
}
RssDataType.CLIEN -> {
openGecko(rss.originPage())
openGecko(rss)
}
else -> {
openGecko(rss.originPage())
openGecko(rss)
}
}
}
}
fun searchKeyword() {
val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
builder.setTitle("Keyword")
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.parivate_mode) as CheckBox
privateMode.setOnCheckedChangeListener { v,c->
binding.geckoWeb.privateMode = c
}
privateMode.visibility = View.GONE
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) {
queryInfos(keywords = command!!.split(" ")!!)
}
})
builder.setNegativeButton(
android.R.string.cancel,
DialogInterface.OnClickListener { dialog, which -> dialog.cancel() })
builder.show()
}
fun ask() {
@ -317,26 +338,28 @@ internal class RssHome : Fragment() {
@SuppressLint("SimpleDateFormat")
fun openGecko(originPage: String? = null, rssData: RssData? = null) {
if (!imageView) {
originPage?.let {
fun openGecko(rssData: RssData? = null) {
binding.layoutRssSummary.root.visibility = View.GONE
if (rssData?.category()?.equals(RssDataType.PRIVATE) == false && rssData?.originPage?.isNotEmpty() == true) {
rssData?.originPage?.let {
binding.geckoWeb.privateMode = false
rssId = originPage
rssId = it
targetList.clear()
var setString = hashSetOf<String>()
setString.addAll(rssList)
setString.removeAll { it.equals(rssId) }
targetList.addAll(setString)
binding.geckoWeb.loadUrl(rssId)
}
} else {
} else if (rssData?.category()?.equals(RssDataType.PRIVATE) == true){
rssData?.let {
binding.geckoWeb.privateMode = true
lasted.removeAll { target -> target.originPage.equals(it.originPage) }
appendReadCount(it, 1, false)
Blog.LOGE("removeFirst >>> ${Gson().toJson(it)}")
binding.layoutRssSummary.title.tag = it
binding.layoutRssSummary.root.visibility = View.VISIBLE
binding.layoutRssSummary.scrollView.scrollTo(0,0)
var vote = it.vote
var read = it.read
it.title?.let {
@ -345,7 +368,7 @@ internal class RssHome : Fragment() {
"O"
}else {
"X"
}} , R:${read}]")
}} , R:${read + 1}]")
}
it.pubDate()?.let {
@ -376,6 +399,10 @@ internal class RssHome : Fragment() {
loadImage(binding.layoutRssSummary.screen, it)
binding.layoutRssSummary.screenLink.text = it
}
// it.originPage().let {
// Blog.LOGE(it)
// binding.layoutRssSummary.smallg.loadUrl(it)
// }
}
}
}
@ -423,6 +450,14 @@ internal class RssHome : Fragment() {
ask()
true
}
binding.search.setOnClickListener {
if (binding.geckoWeb.isVisible) {
binding.geckoWeb.visibility = View.GONE
}
binding.geckoWeb.visibility = View.GONE
searchKeyword()
true
}
binding.privateBtn.setOnClickListener {
queryPrevate(true)
}
@ -472,6 +507,10 @@ internal class RssHome : Fragment() {
binding.layoutRssSummary.link.setOnClickListener {
(it.tag as? RssData)?.let {
appendReadCount(it, 1, true)
startActivity(Intent().apply {
action = Intent.ACTION_VIEW
data = Uri.parse(it.magnet_link)
})
}
}
binding.layoutRssSummary.title.setOnClickListener {
@ -584,6 +623,9 @@ internal class RssHome : Fragment() {
}
fun updateQuery(q: RealmQuery<RssData>) {
infosJob?.cancel()
commandHandler.removeCallbacks(infoUpdate)
mRssDataResult =
q.sort("pubDate ", Sort.DESCENDING).limit(300).distinct("originPage", "title").find()
mRssDataResult?.asFlow()?.let { flow ->
@ -646,13 +688,42 @@ internal class RssHome : Fragment() {
updateQuery(rQ)
}
fun buildMultiFieldOrQuery(
fields: List<String>,
keywords: List<String>
): Pair<String, Array<String>> {
val queryParts = mutableListOf<String>()
val args = mutableListOf<String>()
keywords.forEach { keyword ->
val fieldConditions = fields.map { field ->
"$field CONTAINS[c] \$${args.size}"
}.joinToString(" AND ")
queryParts.add("($fieldConditions)")
// 각 필드마다 같은 keyword를 넣어줘야 함
fields.forEach { _ -> args.add(keyword) }
}
val queryString = queryParts.joinToString(" OR ")
return Pair(queryString, args.toTypedArray())
}
fun queryInfos(
keyword: String,
category: ArrayList<String> = arrayListOf(),
noLimit: Boolean = false
keywords: List<String>,
) {
beforeQuery()
updateQuery(WorkersDb.getRssQuery(keyword, category, noLimit))
var rQ = getRealm().query<RssData>().sort("pubDate", Sort.DESCENDING)
// 사용 예시
val (queryStr, queryArgs) = buildMultiFieldOrQuery(
listOf("title", "description"),
keywords
)
updateQuery(rQ.query(queryStr, *queryArgs))
}
@ -777,11 +848,21 @@ internal class RssHome : Fragment() {
}
}
fun loadImage(imageView: ImageView, url: String?, retryCount: Int = 3) {
var lOnClickListener = object : View.OnClickListener{
override fun onClick(v: View) {
v.setAlpha(1f)
v.visibility = View.VISIBLE
}
}
val mainHandler = Handler(Looper.getMainLooper())
fun loadImage(imageView: ImageView, url: String?, retryCount: Int = 5) {
with(imageView) {
Picasso.get().cancelRequest(this)
// setOnTouchListener(null)
setOnTouchListener(null)
}
imageView.setImageResource(R.drawable.ic_info)
imageView.setAlpha(1f)
url?.let { url ->
if (url.length > 4) {
try {
@ -794,7 +875,7 @@ internal class RssHome : Fragment() {
override fun onSuccess() {
imageView.visibility = View.VISIBLE
imageView.setAlpha(0.05f)
imageView.setOnTouchListener(lOnTouchListener)
imageView.setOnClickListener(lOnClickListener)
Blog.LOGE("Picasso load into onSuccess URL:$url")
}
@ -802,9 +883,13 @@ internal class RssHome : Fragment() {
e?.printStackTrace()
if (retryCount > 0) {
// 메인 스레드에서 재시도
Handler(Looper.getMainLooper()).postDelayed({
loadImage(imageView, url, retryCount - 1)
}, 1500L)
if (binding.layoutRssSummary.root.isVisible) {
mainHandler.postDelayed({
if (binding.layoutRssSummary.root.isVisible && imageView.visibility == View.INVISIBLE) {
loadImage(imageView, url, retryCount - 1)
}
}, 3000L)
}
} else {
// 3회 모두 실패: 대체 이미지 표시
imageView.setImageResource(R.drawable.ic_info)
@ -823,7 +908,7 @@ internal class RssHome : Fragment() {
imageView.visibility = View.INVISIBLE
}
}
fun randomOrNull() : RssData? = lasted.sortedByDescending { it.read }.filter { it.vote == false && it.read < nomoreShowCount }.randomOrNull()
fun randomOrNull() : RssData? = lasted.filter { it.vote == false && it.read < 2 }.randomOrNull()
}
var toast: Toast? = null
fun Context.toast(string: String) {

View File

@ -32,6 +32,7 @@ import bums.lunatic.launcher.model.TelegramMessage
import bums.lunatic.launcher.model.WeatherForcast
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.utils.JamoUtils
import bums.lunatic.launcher.utils.afterDay
import bums.lunatic.launcher.utils.beforeDay
import bums.lunatic.launcher.utils.beforeOneDay
import com.google.gson.Gson
@ -108,15 +109,19 @@ object WorkersDb {
getRealm().writeBlocking {
try {
rssDatas.forEach { t ->
if (query<RssData>("originPage == $0", t.originPage).find().isEmpty()) {
// val catfillters = arrayListOf<RssDataType>(RssDataType.THEQOO,RssDataType.RULIWEB,RssDataType.ARCA,RssDataType.CLIEN,RssDataType.FMKORAE,RssDataType.DOTAX,RssDataType.DCINSIDE)
// if(catfillters.contains(it.category()) && query<RssData>("chosung == $0",it.chosung).find().size == 0) {
var results= query<RssData>("originPage == $0", t.originPage).find()
if (results.isEmpty()) {
if(it.category().equals(RssDataType.PRIVATE)) {
it.pubDate = afterDay(it.pubDate)
}
this.copyToRealm(t, UpdatePolicy.ERROR)
// } else if(!catfillters.contains(it.category())){
// this.copyToRealm(it, UpdatePolicy.ERROR)
// } else {
//
// }
} else {
if(it.category().equals(RssDataType.PRIVATE)) {
it.pubDate = afterDay(it.pubDate)
it.vote = results.first().vote
it.read = results.first().read
this.copyToRealm(t, UpdatePolicy.ALL)
}
}
}

View File

@ -62,7 +62,9 @@
<Button
android:text="hidden"
android:id="@+id/hidden"
style="@style/tabItem"
android:gravity="center"
android:layout_width="60dp"
android:layout_height="match_parent"/>
</RadioGroup>
</HorizontalScrollView>

View File

@ -13,6 +13,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/scrollView"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
@ -105,6 +106,17 @@
android:textColor="@color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<bums.lunatic.launcher.home.GeckoWeb
android:id="@+id/smallg"
android:visibility="gone"
android:layout_width="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/link"
android:layout_height="800dp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<ImageButton