...
This commit is contained in:
parent
2001be4424
commit
74c95e04fd
@ -1,40 +1,65 @@
|
||||
|
||||
browser.webRequest.onHeadersReceived.addListener(
|
||||
function(details) {
|
||||
let headers = details.responseHeaders || [];
|
||||
// Cache-Control 헤더가 없거나 no-store, no-cache 등일 때 수정
|
||||
let found = false;
|
||||
for (let header of headers) {
|
||||
if (header.name.toLowerCase() === "cache-control") {
|
||||
header.value = "public, max-age=31536000"; // 1년 캐시
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
headers.push({name: "Cache-Control", value: "public, max-age=31536000"});
|
||||
}
|
||||
return {responseHeaders: headers};
|
||||
},
|
||||
{urls: ["*://*/*.gif"], types: ["image"]},
|
||||
["blocking", "responseHeaders"]
|
||||
);
|
||||
//const originalLog = console.log;
|
||||
//console.log = function(...args) {
|
||||
// // 메시지 가공 또는 네이티브로 전달
|
||||
// originalLog.apply(console, args);
|
||||
// browser.runtime.sendNativeMessage("browser", args);
|
||||
//};
|
||||
|
||||
browser.webRequest.onBeforeRequest.addListener(
|
||||
function(details) {
|
||||
return { cancel: true };
|
||||
},
|
||||
{ urls: ["*://*/*.gif"], types: ["image"] },
|
||||
["blocking"]
|
||||
);
|
||||
//window.addEventListener('error', function(event) {
|
||||
// if (event.message && event.message.includes('No impl for message: MozAfterPaint')) {
|
||||
// // 앱으로 오류 신호 전달
|
||||
// browser.runtime.sendMessage({ type: 'RELOAD_REQUEST' });
|
||||
//const port = browser.runtime.connectNative("browser");
|
||||
//// 모든 요청을 가로챔
|
||||
//browser.webRequest.onCompleted.addListener(async (details) => {
|
||||
// // 원래 요청 URL
|
||||
// const url = details.url;
|
||||
// try {
|
||||
// // 실제 데이터 fetch (credentials, 쿠키 등 필요시 옵션 맞춤)
|
||||
// const res = await fetch(url, {credentials: "include"});
|
||||
// const blob = await res.blob();
|
||||
// // 데이터 -> ArrayBuffer
|
||||
// const arrayBuffer = await blob.arrayBuffer();
|
||||
// // base64로 변환
|
||||
// const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
|
||||
// // 네이티브 앱에게 전달
|
||||
// port.postMessage(JSON.stringify({type:"CACAHE",msg:msg , url: url, data: base64}));
|
||||
//// browser.runtime.sendNativeMessage(
|
||||
//// "browser", // 등록한 네이티브 앱 id
|
||||
//// { url: url, data: base64 }
|
||||
//// );
|
||||
// } catch(e) {
|
||||
// // 에러 처리
|
||||
// console.error(e);
|
||||
// }
|
||||
//});
|
||||
//}, {urls: ["<all_urls>"]});
|
||||
//
|
||||
////
|
||||
////browser.webRequest.onHeadersReceived.addListener(
|
||||
//// function(details) {
|
||||
//// let headers = details.responseHeaders || [];
|
||||
//// // Cache-Control 헤더가 없거나 no-store, no-cache 등일 때 수정
|
||||
//// let found = false;
|
||||
//// for (let header of headers) {
|
||||
//// if (header.name.toLowerCase() === "cache-control") {
|
||||
//// header.value = "public, max-age=31536000"; // 1년 캐시
|
||||
//// found = true;
|
||||
//// }
|
||||
//// }
|
||||
//// if (!found) {
|
||||
//// headers.push({name: "Cache-Control", value: "public, max-age=31536000"});
|
||||
//// }
|
||||
//// return {responseHeaders: headers};
|
||||
//// },
|
||||
//// {urls: ["*://*/*.gif"], types: ["image"]},
|
||||
//// ["blocking", "responseHeaders"]
|
||||
////);
|
||||
//////const originalLog = console.log;
|
||||
//////console.log = function(...args) {
|
||||
////// // 메시지 가공 또는 네이티브로 전달
|
||||
////// originalLog.apply(console, args);
|
||||
////// browser.runtime.sendNativeMessage("browser", args);
|
||||
//////};
|
||||
////
|
||||
////browser.webRequest.onBeforeRequest.addListener(
|
||||
//// function(details) {
|
||||
//// return { cancel: true };
|
||||
//// },
|
||||
//// { urls: ["*://*/*.gif"], types: ["image"] },
|
||||
//// ["blocking"]
|
||||
////);
|
||||
////window.addEventListener('error', function(event) {
|
||||
//// if (event.message && event.message.includes('No impl for message: MozAfterPaint')) {
|
||||
//// // 앱으로 오류 신호 전달
|
||||
//// browser.runtime.sendMessage({ type: 'RELOAD_REQUEST' });
|
||||
//// }
|
||||
////});
|
||||
@ -22,7 +22,6 @@
|
||||
"nativeMessagingFromContent",
|
||||
"geckoViewAddons",
|
||||
"webRequest",
|
||||
"webRequestBlocking",
|
||||
"*://*/*.gif"
|
||||
"webRequestBlocking"
|
||||
]
|
||||
}
|
||||
|
||||
@ -21,9 +21,7 @@ package bums.lunatic.launcher
|
||||
//import rasel.lunar.launcher.home.LauncherHome.Companion.rssSet
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.NotificationManager
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.Configuration
|
||||
@ -31,10 +29,8 @@ import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Environment.isExternalStorageManager
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.provider.Settings
|
||||
import android.view.KeyEvent
|
||||
import android.view.KeyEvent.ACTION_UP
|
||||
import android.view.KeyEvent.KEYCODE_BUTTON_A
|
||||
@ -46,19 +42,14 @@ import android.view.KeyEvent.KEYCODE_BUTTON_Y
|
||||
import android.view.KeyEvent.KEYCODE_DPAD_DOWN
|
||||
import android.view.KeyEvent.KEYCODE_DPAD_UP
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.work.ExistingPeriodicWorkPolicy
|
||||
import androidx.work.OneTimeWorkRequest
|
||||
@ -70,24 +61,20 @@ import bums.lunatic.launcher.tokiz.Novels
|
||||
import bums.lunatic.launcher.common.CommonActivity
|
||||
import bums.lunatic.launcher.databinding.LauncherActivityBinding
|
||||
import bums.lunatic.launcher.feeds.WidgetHost
|
||||
import bums.lunatic.launcher.helpers.BluetoothManager
|
||||
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_APPLICATION_THEME
|
||||
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_STATUS_BAR
|
||||
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
||||
import bums.lunatic.launcher.helpers.Constants.Companion.widgetHostId
|
||||
import bums.lunatic.launcher.helpers.HeadsetActionButtonReceiver
|
||||
import bums.lunatic.launcher.helpers.PrefLong
|
||||
import bums.lunatic.launcher.home.LauncherHome
|
||||
import bums.lunatic.launcher.home.RssHome
|
||||
import bums.lunatic.launcher.home.RssViewBuilder
|
||||
import bums.lunatic.launcher.model.RssData
|
||||
import bums.lunatic.launcher.model.RssDataType
|
||||
import bums.lunatic.launcher.receiver.NLService
|
||||
import bums.lunatic.launcher.tokiz.Comics
|
||||
import bums.lunatic.launcher.tokiz.Webtoons
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
import bums.lunatic.launcher.utils.FeedParseManager
|
||||
import bums.lunatic.launcher.utils.getJ
|
||||
import bums.lunatic.launcher.view.TableRadioGroup
|
||||
import bums.lunatic.launcher.workers.AppInfoGetter
|
||||
import bums.lunatic.launcher.workers.ArcaGetter
|
||||
import bums.lunatic.launcher.workers.CalendarGetter
|
||||
@ -101,7 +88,6 @@ import bums.lunatic.launcher.workers.FmKoreaGetter.Companion.COMIC_WORK_TAG
|
||||
import bums.lunatic.launcher.workers.LocationGetter
|
||||
import bums.lunatic.launcher.workers.NewsFeedsGetter
|
||||
import bums.lunatic.launcher.workers.NewsFeedsGetter.Companion.FEDDS_WORK_TAG
|
||||
import bums.lunatic.launcher.workers.OpenWeatherGetter
|
||||
import bums.lunatic.launcher.workers.RecentCallGetter
|
||||
import bums.lunatic.launcher.workers.RecentSmsGetter
|
||||
import bums.lunatic.launcher.workers.RecentSmsGetter.Companion.SMS_WORK_TAG
|
||||
@ -627,7 +613,7 @@ internal class LauncherActivity : CommonActivity() {
|
||||
when(id) {
|
||||
R.id.feeds -> {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragment_container, LauncherHome())
|
||||
.replace(R.id.fragment_container, RssHome())
|
||||
.commit()
|
||||
}
|
||||
R.id.books ->{
|
||||
@ -743,7 +729,7 @@ internal class LauncherActivity : CommonActivity() {
|
||||
override fun handleOnBackPressed() {
|
||||
val currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
|
||||
when(currentFragment) {
|
||||
is LauncherHome ->{
|
||||
is RssHome ->{
|
||||
currentFragment.doNextPage()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,17 @@
|
||||
package bums.lunatic.launcher.home
|
||||
|
||||
import android.app.DownloadManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
import android.net.Uri
|
||||
import android.os.Environment
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.util.AttributeSet
|
||||
import android.util.Base64
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
import android.view.KeyEvent.ACTION_UP
|
||||
@ -18,7 +23,10 @@ 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.View
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
|
||||
import bums.lunatic.launcher.tokiz.view.BWebview
|
||||
import bums.lunatic.launcher.tokiz.view.JxEvent
|
||||
@ -39,13 +47,18 @@ 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.io.File
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
class GeckoWeb : BWebview {
|
||||
constructor(context: Context?) : super(context) {
|
||||
buildWeb()
|
||||
}
|
||||
|
||||
|
||||
var decoViews = arrayListOf<View>()
|
||||
override fun setVisibility(visibility: Int) {
|
||||
super.setVisibility(visibility)
|
||||
decoViews.forEach { it.visibility = visibility }
|
||||
}
|
||||
|
||||
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||
buildWeb()
|
||||
@ -54,6 +67,7 @@ class GeckoWeb : BWebview {
|
||||
val mPortNam = "browser"
|
||||
val extPath = "resource://android/assets/extensions/my_extension/"
|
||||
val extId = "messaging@booktoki468.com"
|
||||
|
||||
private fun buildWeb() {
|
||||
getRuntime()?.let {
|
||||
val session: GeckoSession = GeckoSession()
|
||||
@ -87,7 +101,7 @@ class GeckoWeb : BWebview {
|
||||
var lastedUrl: String? = null
|
||||
var canGoBack: Boolean? = null
|
||||
var mPort: WebExtension.Port? = null
|
||||
|
||||
var mCaache : WebExtension.Port? = null
|
||||
object WebExtensionInfo {
|
||||
val mPortNam = "browser"
|
||||
val extPath = "resource://android/assets/extensions/my_extension/"
|
||||
@ -238,6 +252,32 @@ class GeckoWeb : BWebview {
|
||||
return super.onRecordMalformedConfigurationEvent(feature, part)
|
||||
}
|
||||
}
|
||||
|
||||
fun showImageDownloadDialog(context: Context, imageUrl: Uri) {
|
||||
AlertDialog.Builder(context)
|
||||
.setTitle("이미지 다운로드")
|
||||
.setMessage("이미지를 저장하시겠습니까?")
|
||||
.setPositiveButton("저장") { _, _ ->
|
||||
downloadImage(context, imageUrl)
|
||||
}
|
||||
.setNegativeButton("취소", null)
|
||||
.show()
|
||||
}
|
||||
|
||||
fun downloadImage(context: Context, url: Uri) {
|
||||
val fileName = url.lastPathSegment ?: "${SimpleDateFormat("yyyyMMddHHmmsss")}.jpg"
|
||||
val request = DownloadManager.Request(url)
|
||||
request.setTitle(fileName)
|
||||
request.setDescription("이미지 다운로드 중...")
|
||||
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
|
||||
// 네트워크타입, 알림설정 등 옵션 추가 가능
|
||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
|
||||
|
||||
val dm = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
|
||||
dm.enqueue(request)
|
||||
Toast.makeText(context, "다운로드 시작: $fileName", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
val contentDelegate = object : GeckoSession.ContentDelegate {
|
||||
override fun onTitleChange(
|
||||
session: GeckoSession,
|
||||
@ -260,6 +300,21 @@ class GeckoWeb : BWebview {
|
||||
|
||||
super.onFirstContentfulPaint(session)
|
||||
}
|
||||
|
||||
override fun onContextMenu(
|
||||
session: GeckoSession,
|
||||
screenX: Int,
|
||||
screenY: Int,
|
||||
element: GeckoSession.ContentDelegate.ContextElement
|
||||
) {
|
||||
if (element.type == GeckoSession.ContentDelegate.ContextElement.TYPE_IMAGE) {
|
||||
Uri.parse(element.srcUri)?.let {
|
||||
showImageDownloadDialog(context,it)
|
||||
}
|
||||
}
|
||||
|
||||
super.onContextMenu(session, screenX, screenY, element)
|
||||
}
|
||||
}
|
||||
val progressDelegate = object : GeckoSession.ProgressDelegate {
|
||||
override fun onSecurityChange(
|
||||
@ -289,6 +344,8 @@ class GeckoWeb : BWebview {
|
||||
Uri.parse(url)?.let { uri ->
|
||||
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 = uri
|
||||
})
|
||||
}
|
||||
@ -328,7 +385,18 @@ class GeckoWeb : BWebview {
|
||||
): GeckoResult<GeckoSession>? {
|
||||
Blog.LOGE("GeckoView", "onNewSession: $session from WebExtension")
|
||||
|
||||
|
||||
Uri.parse(uri)?.let {
|
||||
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
|
||||
})
|
||||
}
|
||||
}
|
||||
return super.onNewSession(session, uri)
|
||||
}
|
||||
|
||||
@ -377,17 +445,85 @@ class GeckoWeb : BWebview {
|
||||
|
||||
override fun onDisconnect(port: WebExtension.Port) {
|
||||
// This port is not usable anymore.
|
||||
if (port === mPort) {
|
||||
|
||||
|
||||
mPort = null
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
val cacheDelegate: PortDelegate =
|
||||
object : PortDelegate {
|
||||
override fun onPortMessage(
|
||||
message: Any, port: WebExtension.Port
|
||||
) {
|
||||
Blog.LOGE("cacheDelegate", "cacheDelegate message : $message")
|
||||
|
||||
}
|
||||
|
||||
|
||||
override fun onDisconnect(port: WebExtension.Port) {
|
||||
// This port is not usable anymore.
|
||||
if (port === mCaache) {
|
||||
mCaache = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onReceiveFromExtension(message: JSONObject) {
|
||||
val url = message.getString("url")
|
||||
val dataBase64 = message.getString("data")
|
||||
val host = Uri.parse(url).host!!
|
||||
val cacheDir = File(context.filesDir, "webcache/$host")
|
||||
if (!cacheDir.exists()) cacheDir.mkdirs()
|
||||
|
||||
// 파일명 생성 (중복처리 필요)
|
||||
val fileName = filenameFromUrl(url)
|
||||
val resourceFile = File(cacheDir, fileName)
|
||||
val rawData = Base64.decode(dataBase64, Base64.DEFAULT)
|
||||
resourceFile.writeBytes(rawData)
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun filenameFromUrl(url: String): String {
|
||||
// URL을 파싱
|
||||
val uri = Uri.parse(url)
|
||||
// 경로 마지막 세그먼트 (예시: /images/logo.png → logo.png)
|
||||
var filename = uri.lastPathSegment ?: "index.html"
|
||||
|
||||
// 쿼리 파라미터 등 URL이 붙은 경우 처리 (예: index.html?version=2)
|
||||
if (filename.contains("?")) {
|
||||
filename = filename.substringBefore("?")
|
||||
}
|
||||
if (filename.isEmpty() || filename.endsWith("/")) {
|
||||
filename = "index.html"
|
||||
}
|
||||
|
||||
// 파일명에 사용할 수 없는 문자 제거(윈도우, 리눅스, 맥 등 호환)
|
||||
filename = filename.replace(Regex("[\\\\/:*?\"<>|]"), "_")
|
||||
|
||||
// 너무 긴 파일명은 자르기
|
||||
val maxLength = 100
|
||||
if (filename.length > maxLength) {
|
||||
val ext = filename.substringAfterLast('.', "")
|
||||
filename = filename.take(maxLength - ext.length - 1) +
|
||||
if (ext.isNotBlank()) ".$ext" else ""
|
||||
}
|
||||
|
||||
return filename
|
||||
}
|
||||
|
||||
|
||||
val messageDelegate: MessageDelegate =
|
||||
object : MessageDelegate {
|
||||
override fun onConnect(port: WebExtension.Port) {
|
||||
mPort = port
|
||||
mPort!!.setDelegate(portDelegate)
|
||||
Blog.LOGE("onConnect port >>> ${port.name}")
|
||||
// if (port.name === "browser") {
|
||||
// mPort = port
|
||||
// mPort!!.setDelegate(portDelegate)
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onMessage(
|
||||
@ -401,11 +537,8 @@ class GeckoWeb : BWebview {
|
||||
)
|
||||
return super.onMessage(nativeApp, message, sender)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun onStart() {
|
||||
|
||||
}
|
||||
|
||||
@ -20,7 +20,6 @@ package bums.lunatic.launcher.home
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
@ -30,7 +29,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.NonNull
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
@ -38,7 +37,6 @@ import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
||||
import bums.lunatic.launcher.R
|
||||
import bums.lunatic.launcher.common.letTrue
|
||||
import bums.lunatic.launcher.databinding.LauncherHomeBinding
|
||||
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
||||
import bums.lunatic.launcher.home.adapters.RssItemAdapter
|
||||
@ -47,7 +45,6 @@ import bums.lunatic.launcher.home.adapters.SwipeToDeleteCallback
|
||||
import bums.lunatic.launcher.model.RssData
|
||||
import bums.lunatic.launcher.model.RssDataType
|
||||
import bums.lunatic.launcher.model.WeatherForcast
|
||||
import bums.lunatic.launcher.openClient
|
||||
import bums.lunatic.launcher.openReddit
|
||||
import bums.lunatic.launcher.openYouTube
|
||||
import bums.lunatic.launcher.tokiz.view.JxEvent
|
||||
@ -59,7 +56,9 @@ import bums.lunatic.launcher.workers.WorkersDb
|
||||
import com.google.android.material.imageview.ShapeableImageView
|
||||
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
|
||||
@ -69,7 +68,7 @@ import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
internal class LauncherHome : Fragment() {
|
||||
internal class RssHome : Fragment() {
|
||||
|
||||
lateinit var binding: LauncherHomeBinding
|
||||
private lateinit var fragManager: FragmentManager
|
||||
@ -77,11 +76,10 @@ internal class LauncherHome : Fragment() {
|
||||
private var shouldResume = true
|
||||
|
||||
companion object {
|
||||
var home: LauncherHome? = null
|
||||
var home: RssHome? = null
|
||||
var lastedFinishedPageUrl: String = ""
|
||||
}
|
||||
|
||||
val UPDATE_DELAY = 5L
|
||||
val commandHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
val infoUpdate = Runnable { chooseAdpater() }
|
||||
@ -245,6 +243,7 @@ internal class LauncherHome : Fragment() {
|
||||
|
||||
targetList.addAll(setString)
|
||||
binding.geckoWeb.loadUrl(rssId)
|
||||
binding.vote.visibility = binding.geckoWeb.visibility
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@ -270,6 +269,42 @@ internal class LauncherHome : Fragment() {
|
||||
return@setOnTouchListener false
|
||||
}
|
||||
}
|
||||
binding.vote.setOnClickListener {
|
||||
if (binding.geckoWeb.isVisible) {
|
||||
vote()
|
||||
}
|
||||
}
|
||||
|
||||
binding.hide.setOnClickListener {
|
||||
if (binding.geckoWeb.isVisible) {
|
||||
WorkersDb.getRealm().apply {
|
||||
writeBlocking {
|
||||
val result = query<RssData>().query("originPage == $0", rssId).find()
|
||||
if (result.size > 0) {
|
||||
result.forEach {
|
||||
if(it.vote) {
|
||||
it.vote = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doNextPage()
|
||||
}
|
||||
}
|
||||
|
||||
binding.home.setOnClickListener {
|
||||
if (binding.geckoWeb.isVisible) {
|
||||
binding.geckoWeb.visibility = View.GONE
|
||||
}
|
||||
queryInfos()
|
||||
}
|
||||
|
||||
|
||||
binding.bookmark.setOnClickListener {
|
||||
queryVotes()
|
||||
}
|
||||
|
||||
queryInfos()
|
||||
binding.geckoWeb.progress = binding.progressBar
|
||||
binding.geckoWeb.jxInteface = { jxEvent ->
|
||||
@ -287,9 +322,11 @@ internal class LauncherHome : Fragment() {
|
||||
}
|
||||
}
|
||||
}
|
||||
val nullCursor = PointerIcon.getSystemIcon(context!!, PointerIcon.TYPE_NULL)
|
||||
val nullCursor = PointerIcon.getSystemIcon(requireContext(), PointerIcon.TYPE_NULL)
|
||||
binding.root.setPointerIcon(nullCursor)
|
||||
|
||||
binding.geckoWeb.decoViews.add(binding.hide)
|
||||
binding.geckoWeb.decoViews.add(binding.vote)
|
||||
binding.geckoWeb.decoViews.add(binding.progressBar)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@ -352,11 +389,24 @@ internal class LauncherHome : Fragment() {
|
||||
mRssDataResult?.asFlow()?.let { flow ->
|
||||
infosJob = CoroutineScope(Dispatchers.IO).launch {
|
||||
flow.collect { changes: ResultsChange<RssData> ->
|
||||
commandHandler.removeCallbacks(infoUpdate)
|
||||
WorkersDb.getRealm().apply {
|
||||
lasted = copyFromRealm(changes.list)
|
||||
when(changes) {
|
||||
is InitialResults -> {
|
||||
commandHandler.removeCallbacks(infoUpdate)
|
||||
WorkersDb.getRealm().apply {
|
||||
lasted = copyFromRealm(changes.list)
|
||||
}
|
||||
commandHandler.post(infoUpdate)
|
||||
}
|
||||
is UpdatedResults -> {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
changes.changeRanges.forEach {
|
||||
|
||||
mRssAdapter.notifyItemRangeChanged(it.startIndex, it.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
commandHandler.postDelayed(infoUpdate, UPDATE_DELAY)
|
||||
}
|
||||
}
|
||||
infosJob?.start()
|
||||
@ -1166,7 +1166,6 @@ abstract class BaseToki : Fragment(), PagedTextViewInterface {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun onLoadedContents(aContents: String) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package bums.lunatic.launcher.utils
|
||||
|
||||
import bums.lunatic.launcher.home.LauncherHome.Companion.lastedFinishedPageUrl
|
||||
import bums.lunatic.launcher.home.RssHome.Companion.lastedFinishedPageUrl
|
||||
import bums.lunatic.launcher.model.MostItem
|
||||
import bums.lunatic.launcher.model.RssData
|
||||
import bums.lunatic.launcher.model.RssDataType
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp" android:height="24dp"
|
||||
android:viewportWidth="24" android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
android:tint="@color/white">
|
||||
<path
|
||||
android:fillColor="?android:attr/textColorPrimary"
|
||||
android:fillColor="@color/white"
|
||||
android:pathData="M7.7,20.5Q6.775,20.5 6.163,19.887Q5.55,19.275 5.55,18.35V5.9H4.55V4.55H8.95V3.65H15.1V4.55H19.5V5.9H18.5V18.35Q18.5,19.275 17.888,19.887Q17.275,20.5 16.35,20.5ZM17.15,5.9H6.9V18.35Q6.9,18.7 7.125,18.925Q7.35,19.15 7.7,19.15H16.35Q16.65,19.15 16.9,18.9Q17.15,18.65 17.15,18.35ZM9.525,17.125H10.875V7.925H9.525ZM13.175,17.125H14.525V7.925H13.175ZM6.9,5.9V18.35Q6.9,18.7 6.9,18.925Q6.9,19.15 6.9,19.15Q6.9,19.15 6.9,18.925Q6.9,18.7 6.9,18.35Z"/>
|
||||
</vector>
|
||||
|
||||
@ -1,45 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:background="@android:color/transparent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
android:layout_margin="@dimen/default_layout_margin"
|
||||
android:id="@+id/infoList"
|
||||
<layout xmlns:tools="http://schemas.android.com/tools">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:background="@android:color/transparent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:overScrollMode="never"
|
||||
android:padding="@dimen/default_padding"
|
||||
android:scrollbars="none"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
/>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageButton
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:id="@+id/vote"
|
||||
android:scaleType="fitCenter"
|
||||
android:adjustViewBounds="true"
|
||||
android:visibility="visible"
|
||||
android:background="@null"
|
||||
android:src="@drawable/saved"
|
||||
android:layout_width="40dp"
|
||||
tools:ignore="ContentDescription"
|
||||
android:layout_height="40dp" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/hide"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@id/vote"
|
||||
android:src="@drawable/ic_delete"
|
||||
android:tintMode="multiply"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:background="@null"
|
||||
android:layout_width="40dp"
|
||||
android:visibility="visible"
|
||||
android:adjustViewBounds="true"
|
||||
tools:ignore="ContentDescription"
|
||||
android:layout_height="40dp"
|
||||
/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/home"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:src="@drawable/home"
|
||||
android:tintMode="multiply"
|
||||
android:scaleType="fitCenter"
|
||||
android:background="@null"
|
||||
android:layout_width="40dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:layout_height="40dp"
|
||||
app:tint="@color/white"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/bookmark"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@id/home"
|
||||
android:src="@drawable/bookmark"
|
||||
android:scaleType="fitCenter"
|
||||
android:background="@null"
|
||||
android:layout_width="40dp"
|
||||
android:adjustViewBounds="true"
|
||||
tools:ignore="ContentDescription"
|
||||
android:layout_height="40dp"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
android:layout_margin="@dimen/default_layout_margin"
|
||||
android:id="@+id/infoList"
|
||||
android:layout_width="match_parent"
|
||||
android:overScrollMode="never"
|
||||
android:padding="@dimen/default_padding"
|
||||
android:scrollbars="none"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/bookmark"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
/>
|
||||
|
||||
|
||||
<bums.lunatic.launcher.home.GeckoWeb
|
||||
android:id="@+id/geckoWeb"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
||||
<ProgressBar
|
||||
app:layout_constraintTop_toTopOf="@id/geckoWeb"
|
||||
app:layout_constraintLeft_toLeftOf="@id/geckoWeb"
|
||||
app:layout_constraintRight_toRightOf="@id/geckoWeb"
|
||||
android:id="@+id/progressBar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="4dp"
|
||||
android:max="100"
|
||||
android:progress="0"
|
||||
android:visibility="visible"
|
||||
android:indeterminate="false"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<bums.lunatic.launcher.home.GeckoWeb
|
||||
android:id="@+id/geckoWeb"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/bookmark"
|
||||
android:layout_height="0dp"
|
||||
/>
|
||||
<ProgressBar
|
||||
app:layout_constraintTop_toTopOf="@id/geckoWeb"
|
||||
app:layout_constraintLeft_toLeftOf="@id/geckoWeb"
|
||||
app:layout_constraintRight_toRightOf="@id/geckoWeb"
|
||||
android:id="@+id/progressBar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="4dp"
|
||||
android:max="100"
|
||||
android:progress="0"
|
||||
android:visibility="visible"
|
||||
android:indeterminate="false"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
Loading…
x
Reference in New Issue
Block a user