...
This commit is contained in:
parent
2001be4424
commit
74c95e04fd
@ -1,40 +1,65 @@
|
|||||||
|
//const port = browser.runtime.connectNative("browser");
|
||||||
browser.webRequest.onHeadersReceived.addListener(
|
//// 모든 요청을 가로챔
|
||||||
function(details) {
|
//browser.webRequest.onCompleted.addListener(async (details) => {
|
||||||
let headers = details.responseHeaders || [];
|
// // 원래 요청 URL
|
||||||
// Cache-Control 헤더가 없거나 no-store, no-cache 등일 때 수정
|
// const url = details.url;
|
||||||
let found = false;
|
// try {
|
||||||
for (let header of headers) {
|
// // 실제 데이터 fetch (credentials, 쿠키 등 필요시 옵션 맞춤)
|
||||||
if (header.name.toLowerCase() === "cache-control") {
|
// const res = await fetch(url, {credentials: "include"});
|
||||||
header.value = "public, max-age=31536000"; // 1년 캐시
|
// const blob = await res.blob();
|
||||||
found = true;
|
// // 데이터 -> ArrayBuffer
|
||||||
}
|
// const arrayBuffer = await blob.arrayBuffer();
|
||||||
}
|
// // base64로 변환
|
||||||
if (!found) {
|
// const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
|
||||||
headers.push({name: "Cache-Control", value: "public, max-age=31536000"});
|
// // 네이티브 앱에게 전달
|
||||||
}
|
// port.postMessage(JSON.stringify({type:"CACAHE",msg:msg , url: url, data: base64}));
|
||||||
return {responseHeaders: headers};
|
//// browser.runtime.sendNativeMessage(
|
||||||
},
|
//// "browser", // 등록한 네이티브 앱 id
|
||||||
{urls: ["*://*/*.gif"], types: ["image"]},
|
//// { url: url, data: base64 }
|
||||||
["blocking", "responseHeaders"]
|
//// );
|
||||||
);
|
// } catch(e) {
|
||||||
//const originalLog = console.log;
|
// // 에러 처리
|
||||||
//console.log = function(...args) {
|
// console.error(e);
|
||||||
// // 메시지 가공 또는 네이티브로 전달
|
|
||||||
// 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' });
|
|
||||||
// }
|
// }
|
||||||
//});
|
//}, {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",
|
"nativeMessagingFromContent",
|
||||||
"geckoViewAddons",
|
"geckoViewAddons",
|
||||||
"webRequest",
|
"webRequest",
|
||||||
"webRequestBlocking",
|
"webRequestBlocking"
|
||||||
"*://*/*.gif"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,9 +21,7 @@ package bums.lunatic.launcher
|
|||||||
//import rasel.lunar.launcher.home.LauncherHome.Companion.rssSet
|
//import rasel.lunar.launcher.home.LauncherHome.Companion.rssSet
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
@ -31,10 +29,8 @@ import android.graphics.Color
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment.isExternalStorageManager
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.provider.Settings
|
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.KeyEvent.ACTION_UP
|
import android.view.KeyEvent.ACTION_UP
|
||||||
import android.view.KeyEvent.KEYCODE_BUTTON_A
|
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_DOWN
|
||||||
import android.view.KeyEvent.KEYCODE_DPAD_UP
|
import android.view.KeyEvent.KEYCODE_DPAD_UP
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
|
||||||
import android.view.WindowInsets
|
import android.view.WindowInsets
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.annotation.RequiresApi
|
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.net.toUri
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowCompat
|
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.isVisible
|
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
import androidx.work.OneTimeWorkRequest
|
import androidx.work.OneTimeWorkRequest
|
||||||
@ -70,24 +61,20 @@ import bums.lunatic.launcher.tokiz.Novels
|
|||||||
import bums.lunatic.launcher.common.CommonActivity
|
import bums.lunatic.launcher.common.CommonActivity
|
||||||
import bums.lunatic.launcher.databinding.LauncherActivityBinding
|
import bums.lunatic.launcher.databinding.LauncherActivityBinding
|
||||||
import bums.lunatic.launcher.feeds.WidgetHost
|
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.KEY_STATUS_BAR
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.widgetHostId
|
import bums.lunatic.launcher.helpers.Constants.Companion.widgetHostId
|
||||||
import bums.lunatic.launcher.helpers.HeadsetActionButtonReceiver
|
import bums.lunatic.launcher.helpers.HeadsetActionButtonReceiver
|
||||||
import bums.lunatic.launcher.helpers.PrefLong
|
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.home.RssViewBuilder
|
||||||
import bums.lunatic.launcher.model.RssData
|
import bums.lunatic.launcher.model.RssData
|
||||||
import bums.lunatic.launcher.model.RssDataType
|
import bums.lunatic.launcher.model.RssDataType
|
||||||
import bums.lunatic.launcher.receiver.NLService
|
|
||||||
import bums.lunatic.launcher.tokiz.Comics
|
import bums.lunatic.launcher.tokiz.Comics
|
||||||
import bums.lunatic.launcher.tokiz.Webtoons
|
import bums.lunatic.launcher.tokiz.Webtoons
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
import bums.lunatic.launcher.utils.FeedParseManager
|
import bums.lunatic.launcher.utils.FeedParseManager
|
||||||
import bums.lunatic.launcher.utils.getJ
|
import bums.lunatic.launcher.utils.getJ
|
||||||
import bums.lunatic.launcher.view.TableRadioGroup
|
|
||||||
import bums.lunatic.launcher.workers.AppInfoGetter
|
import bums.lunatic.launcher.workers.AppInfoGetter
|
||||||
import bums.lunatic.launcher.workers.ArcaGetter
|
import bums.lunatic.launcher.workers.ArcaGetter
|
||||||
import bums.lunatic.launcher.workers.CalendarGetter
|
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.LocationGetter
|
||||||
import bums.lunatic.launcher.workers.NewsFeedsGetter
|
import bums.lunatic.launcher.workers.NewsFeedsGetter
|
||||||
import bums.lunatic.launcher.workers.NewsFeedsGetter.Companion.FEDDS_WORK_TAG
|
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.RecentCallGetter
|
||||||
import bums.lunatic.launcher.workers.RecentSmsGetter
|
import bums.lunatic.launcher.workers.RecentSmsGetter
|
||||||
import bums.lunatic.launcher.workers.RecentSmsGetter.Companion.SMS_WORK_TAG
|
import bums.lunatic.launcher.workers.RecentSmsGetter.Companion.SMS_WORK_TAG
|
||||||
@ -627,7 +613,7 @@ internal class LauncherActivity : CommonActivity() {
|
|||||||
when(id) {
|
when(id) {
|
||||||
R.id.feeds -> {
|
R.id.feeds -> {
|
||||||
supportFragmentManager.beginTransaction()
|
supportFragmentManager.beginTransaction()
|
||||||
.replace(R.id.fragment_container, LauncherHome())
|
.replace(R.id.fragment_container, RssHome())
|
||||||
.commit()
|
.commit()
|
||||||
}
|
}
|
||||||
R.id.books ->{
|
R.id.books ->{
|
||||||
@ -743,7 +729,7 @@ internal class LauncherActivity : CommonActivity() {
|
|||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
val currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
|
val currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
|
||||||
when(currentFragment) {
|
when(currentFragment) {
|
||||||
is LauncherHome ->{
|
is RssHome ->{
|
||||||
currentFragment.doNextPage()
|
currentFragment.doNextPage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
package bums.lunatic.launcher.home
|
package bums.lunatic.launcher.home
|
||||||
|
|
||||||
|
import android.app.DownloadManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
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.net.Uri
|
||||||
|
import android.os.Environment
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.os.Message
|
import android.os.Message
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import android.util.Base64
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.KeyEvent.ACTION_UP
|
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_BUTTON_Y
|
||||||
import android.view.KeyEvent.KEYCODE_DPAD_DOWN
|
import android.view.KeyEvent.KEYCODE_DPAD_DOWN
|
||||||
import android.view.KeyEvent.KEYCODE_DPAD_UP
|
import android.view.KeyEvent.KEYCODE_DPAD_UP
|
||||||
|
import android.view.View
|
||||||
import android.widget.ProgressBar
|
import android.widget.ProgressBar
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
|
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
|
||||||
import bums.lunatic.launcher.tokiz.view.BWebview
|
import bums.lunatic.launcher.tokiz.view.BWebview
|
||||||
import bums.lunatic.launcher.tokiz.view.JxEvent
|
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.WebExtension.PortDelegate
|
||||||
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
|
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
|
||||||
import org.mozilla.geckoview.WebRequestError
|
import org.mozilla.geckoview.WebRequestError
|
||||||
|
import java.io.File
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
|
||||||
class GeckoWeb : BWebview {
|
class GeckoWeb : BWebview {
|
||||||
constructor(context: Context?) : super(context) {
|
constructor(context: Context?) : super(context) {
|
||||||
buildWeb()
|
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) {
|
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||||
buildWeb()
|
buildWeb()
|
||||||
@ -54,6 +67,7 @@ class GeckoWeb : BWebview {
|
|||||||
val mPortNam = "browser"
|
val mPortNam = "browser"
|
||||||
val extPath = "resource://android/assets/extensions/my_extension/"
|
val extPath = "resource://android/assets/extensions/my_extension/"
|
||||||
val extId = "messaging@booktoki468.com"
|
val extId = "messaging@booktoki468.com"
|
||||||
|
|
||||||
private fun buildWeb() {
|
private fun buildWeb() {
|
||||||
getRuntime()?.let {
|
getRuntime()?.let {
|
||||||
val session: GeckoSession = GeckoSession()
|
val session: GeckoSession = GeckoSession()
|
||||||
@ -87,7 +101,7 @@ class GeckoWeb : BWebview {
|
|||||||
var lastedUrl: String? = null
|
var lastedUrl: String? = null
|
||||||
var canGoBack: Boolean? = null
|
var canGoBack: Boolean? = null
|
||||||
var mPort: WebExtension.Port? = null
|
var mPort: WebExtension.Port? = null
|
||||||
|
var mCaache : WebExtension.Port? = null
|
||||||
object WebExtensionInfo {
|
object WebExtensionInfo {
|
||||||
val mPortNam = "browser"
|
val mPortNam = "browser"
|
||||||
val extPath = "resource://android/assets/extensions/my_extension/"
|
val extPath = "resource://android/assets/extensions/my_extension/"
|
||||||
@ -238,6 +252,32 @@ class GeckoWeb : BWebview {
|
|||||||
return super.onRecordMalformedConfigurationEvent(feature, part)
|
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 {
|
val contentDelegate = object : GeckoSession.ContentDelegate {
|
||||||
override fun onTitleChange(
|
override fun onTitleChange(
|
||||||
session: GeckoSession,
|
session: GeckoSession,
|
||||||
@ -260,6 +300,21 @@ class GeckoWeb : BWebview {
|
|||||||
|
|
||||||
super.onFirstContentfulPaint(session)
|
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 {
|
val progressDelegate = object : GeckoSession.ProgressDelegate {
|
||||||
override fun onSecurityChange(
|
override fun onSecurityChange(
|
||||||
@ -289,6 +344,8 @@ class GeckoWeb : BWebview {
|
|||||||
Uri.parse(url)?.let { uri ->
|
Uri.parse(url)?.let { uri ->
|
||||||
context.startActivity(Intent().apply {
|
context.startActivity(Intent().apply {
|
||||||
action = Intent.ACTION_VIEW
|
action = Intent.ACTION_VIEW
|
||||||
|
flags = Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS.or(FLAG_ACTIVITY_CLEAR_TOP).or(
|
||||||
|
FLAG_ACTIVITY_NEW_TASK)
|
||||||
data = uri
|
data = uri
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -328,7 +385,18 @@ class GeckoWeb : BWebview {
|
|||||||
): GeckoResult<GeckoSession>? {
|
): GeckoResult<GeckoSession>? {
|
||||||
Blog.LOGE("GeckoView", "onNewSession: $session from WebExtension")
|
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)
|
return super.onNewSession(session, uri)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,17 +445,85 @@ class GeckoWeb : BWebview {
|
|||||||
|
|
||||||
override fun onDisconnect(port: WebExtension.Port) {
|
override fun onDisconnect(port: WebExtension.Port) {
|
||||||
// This port is not usable anymore.
|
// This port is not usable anymore.
|
||||||
if (port === mPort) {
|
|
||||||
|
|
||||||
mPort = null
|
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 =
|
val messageDelegate: MessageDelegate =
|
||||||
object : MessageDelegate {
|
object : MessageDelegate {
|
||||||
override fun onConnect(port: WebExtension.Port) {
|
override fun onConnect(port: WebExtension.Port) {
|
||||||
mPort = port
|
Blog.LOGE("onConnect port >>> ${port.name}")
|
||||||
mPort!!.setDelegate(portDelegate)
|
// if (port.name === "browser") {
|
||||||
|
// mPort = port
|
||||||
|
// mPort!!.setDelegate(portDelegate)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMessage(
|
override fun onMessage(
|
||||||
@ -401,11 +537,8 @@ class GeckoWeb : BWebview {
|
|||||||
)
|
)
|
||||||
return super.onMessage(nativeApp, message, sender)
|
return super.onMessage(nativeApp, message, sender)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun onStart() {
|
fun onStart() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,6 @@ package bums.lunatic.launcher.home
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
@ -30,7 +29,7 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.annotation.NonNull
|
import androidx.annotation.NonNull
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
@ -38,7 +37,6 @@ import androidx.recyclerview.widget.ItemTouchHelper
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
||||||
import bums.lunatic.launcher.R
|
import bums.lunatic.launcher.R
|
||||||
import bums.lunatic.launcher.common.letTrue
|
|
||||||
import bums.lunatic.launcher.databinding.LauncherHomeBinding
|
import bums.lunatic.launcher.databinding.LauncherHomeBinding
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
||||||
import bums.lunatic.launcher.home.adapters.RssItemAdapter
|
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.RssData
|
||||||
import bums.lunatic.launcher.model.RssDataType
|
import bums.lunatic.launcher.model.RssDataType
|
||||||
import bums.lunatic.launcher.model.WeatherForcast
|
import bums.lunatic.launcher.model.WeatherForcast
|
||||||
import bums.lunatic.launcher.openClient
|
|
||||||
import bums.lunatic.launcher.openReddit
|
import bums.lunatic.launcher.openReddit
|
||||||
import bums.lunatic.launcher.openYouTube
|
import bums.lunatic.launcher.openYouTube
|
||||||
import bums.lunatic.launcher.tokiz.view.JxEvent
|
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 com.google.android.material.imageview.ShapeableImageView
|
||||||
import io.realm.kotlin.UpdatePolicy
|
import io.realm.kotlin.UpdatePolicy
|
||||||
import io.realm.kotlin.ext.query
|
import io.realm.kotlin.ext.query
|
||||||
|
import io.realm.kotlin.notifications.InitialResults
|
||||||
import io.realm.kotlin.notifications.ResultsChange
|
import io.realm.kotlin.notifications.ResultsChange
|
||||||
|
import io.realm.kotlin.notifications.UpdatedResults
|
||||||
import io.realm.kotlin.query.RealmQuery
|
import io.realm.kotlin.query.RealmQuery
|
||||||
import io.realm.kotlin.query.RealmResults
|
import io.realm.kotlin.query.RealmResults
|
||||||
import io.realm.kotlin.query.Sort
|
import io.realm.kotlin.query.Sort
|
||||||
@ -69,7 +68,7 @@ import kotlinx.coroutines.Job
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
||||||
internal class LauncherHome : Fragment() {
|
internal class RssHome : Fragment() {
|
||||||
|
|
||||||
lateinit var binding: LauncherHomeBinding
|
lateinit var binding: LauncherHomeBinding
|
||||||
private lateinit var fragManager: FragmentManager
|
private lateinit var fragManager: FragmentManager
|
||||||
@ -77,11 +76,10 @@ internal class LauncherHome : Fragment() {
|
|||||||
private var shouldResume = true
|
private var shouldResume = true
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
var home: LauncherHome? = null
|
var home: RssHome? = null
|
||||||
var lastedFinishedPageUrl: String = ""
|
var lastedFinishedPageUrl: String = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
val UPDATE_DELAY = 5L
|
|
||||||
val commandHandler = Handler(Looper.getMainLooper())
|
val commandHandler = Handler(Looper.getMainLooper())
|
||||||
|
|
||||||
val infoUpdate = Runnable { chooseAdpater() }
|
val infoUpdate = Runnable { chooseAdpater() }
|
||||||
@ -245,6 +243,7 @@ internal class LauncherHome : Fragment() {
|
|||||||
|
|
||||||
targetList.addAll(setString)
|
targetList.addAll(setString)
|
||||||
binding.geckoWeb.loadUrl(rssId)
|
binding.geckoWeb.loadUrl(rssId)
|
||||||
|
binding.vote.visibility = binding.geckoWeb.visibility
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@ -270,6 +269,42 @@ internal class LauncherHome : Fragment() {
|
|||||||
return@setOnTouchListener false
|
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()
|
queryInfos()
|
||||||
binding.geckoWeb.progress = binding.progressBar
|
binding.geckoWeb.progress = binding.progressBar
|
||||||
binding.geckoWeb.jxInteface = { jxEvent ->
|
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.root.setPointerIcon(nullCursor)
|
||||||
|
binding.geckoWeb.decoViews.add(binding.hide)
|
||||||
|
binding.geckoWeb.decoViews.add(binding.vote)
|
||||||
|
binding.geckoWeb.decoViews.add(binding.progressBar)
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,11 +389,24 @@ internal class LauncherHome : Fragment() {
|
|||||||
mRssDataResult?.asFlow()?.let { flow ->
|
mRssDataResult?.asFlow()?.let { flow ->
|
||||||
infosJob = CoroutineScope(Dispatchers.IO).launch {
|
infosJob = CoroutineScope(Dispatchers.IO).launch {
|
||||||
flow.collect { changes: ResultsChange<RssData> ->
|
flow.collect { changes: ResultsChange<RssData> ->
|
||||||
commandHandler.removeCallbacks(infoUpdate)
|
when(changes) {
|
||||||
WorkersDb.getRealm().apply {
|
is InitialResults -> {
|
||||||
lasted = copyFromRealm(changes.list)
|
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()
|
infosJob?.start()
|
||||||
@ -1166,7 +1166,6 @@ abstract class BaseToki : Fragment(), PagedTextViewInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onLoadedContents(aContents: String) {
|
fun onLoadedContents(aContents: String) {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package bums.lunatic.launcher.utils
|
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.MostItem
|
||||||
import bums.lunatic.launcher.model.RssData
|
import bums.lunatic.launcher.model.RssData
|
||||||
import bums.lunatic.launcher.model.RssDataType
|
import bums.lunatic.launcher.model.RssDataType
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp" android:height="24dp"
|
android:width="24dp" android:height="24dp"
|
||||||
android:viewportWidth="24" android:viewportHeight="24"
|
android:viewportWidth="24" android:viewportHeight="24"
|
||||||
android:tint="?attr/colorControlNormal">
|
android:tint="@color/white">
|
||||||
<path
|
<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"/>
|
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>
|
</vector>
|
||||||
|
|||||||
@ -1,45 +1,105 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<layout xmlns:tools="http://schemas.android.com/tools">
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:background="@android:color/transparent"
|
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"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:overScrollMode="never"
|
|
||||||
android:padding="@dimen/default_padding"
|
<ImageButton
|
||||||
android:scrollbars="none"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
android:visibility="visible"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
android:id="@+id/vote"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
android:scaleType="fitCenter"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
android:adjustViewBounds="true"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
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
|
<bums.lunatic.launcher.home.GeckoWeb
|
||||||
android:id="@+id/geckoWeb"
|
android:id="@+id/geckoWeb"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
/>
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
<ProgressBar
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@id/geckoWeb"
|
app:layout_constraintTop_toBottomOf="@id/bookmark"
|
||||||
app:layout_constraintLeft_toLeftOf="@id/geckoWeb"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintRight_toRightOf="@id/geckoWeb"
|
/>
|
||||||
android:id="@+id/progressBar"
|
<ProgressBar
|
||||||
style="?android:attr/progressBarStyleHorizontal"
|
app:layout_constraintTop_toTopOf="@id/geckoWeb"
|
||||||
android:layout_width="0dp"
|
app:layout_constraintLeft_toLeftOf="@id/geckoWeb"
|
||||||
android:layout_height="4dp"
|
app:layout_constraintRight_toRightOf="@id/geckoWeb"
|
||||||
android:max="100"
|
android:id="@+id/progressBar"
|
||||||
android:progress="0"
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
android:visibility="visible"
|
android:layout_width="0dp"
|
||||||
android:indeterminate="false"/>
|
android:layout_height="4dp"
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
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