This commit is contained in:
lunaticbum 2025-09-07 23:14:03 +09:00
parent 520350f9d1
commit b5bbf299bd
81 changed files with 2467 additions and 3021 deletions

View File

@ -103,44 +103,50 @@ android {
jvmTarget = "1.8"
}
ndkVersion = "29.0.13846066 rc3"
buildToolsVersion = "35.0.1"
// buildToolsVersion = "35.0.1"
packaging {
doNotStrip("**/libaria2c.zip.so")
doNotStrip("**/libffmpeg.zip.so")
doNotStrip("**/libpython.zip.so")
}
}
dependencies {
val kotlinVersion: String? by extra
implementation ("androidx.appcompat:appcompat:1.7.0")
val realmVersion = "2.0.0"
implementation ("androidx.appcompat:appcompat:1.7.1")
implementation ("androidx.biometric:biometric-ktx:1.2.0-alpha05")
implementation ("androidx.browser:browser:1.8.0")
implementation ("androidx.core:core-ktx:1.15.0")
implementation ("androidx.core:core-splashscreen:1.0.1")
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7")
implementation ("com.google.android.material:material:1.12.0")
implementation ("com.ibm.icu:icu4j:68.1")
implementation (kotlin("stdlib", version = kotlinVersion))
implementation ("com.ibm.icu:icu4j:77.1")
implementation (kotlin("stdlib", version = "2.0.10"))
implementation ("com.github.cachapa:ExpandableLayout:2.9.2")
implementation ("androidx.work:work-runtime:2.10.0")
implementation ("com.google.code.gson:gson:2.11.0")
implementation ("io.realm.kotlin:library-base:2.1.0")
implementation ("org.jsoup:jsoup:1.18.1")
implementation ("org.apache.commons:commons-text:1.12.0")
implementation ("com.google.code.gson:gson:2.13.1")
implementation ("io.realm.kotlin:library-base:${realmVersion}")
implementation ("org.jsoup:jsoup:1.21.2")
implementation ("org.apache.commons:commons-text:1.14.0")
implementation("com.squareup.okhttp:okhttp:2.7.5")
implementation("com.google.android.gms:play-services-location:21.3.0")
implementation("com.google.android.gms:play-services-tasks:18.2.0")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.retrofit2:converter-scalars:2.6.4")
implementation("com.google.android.gms:play-services-tasks:18.3.2")
implementation("com.squareup.retrofit2:retrofit:3.0.0")
implementation("com.squareup.retrofit2:converter-gson:3.0.0")
implementation("com.squareup.retrofit2:converter-scalars:3.0.0")
implementation("androidx.viewpager2:viewpager2:1.1.0")
implementation("com.squareup.picasso:picasso:2.71828")
implementation("com.github.delight-im:Android-AdvancedWebView:v3.2.1")
implementation(project(":library"))
implementation(project(":utils"))
// implementation(project(":library"))
// implementation(project(":utils"))
implementation( "com.github.bumptech.glide:glide:4.11.0")
implementation ("com.github.bumptech.glide:okhttp3-integration:4.11.0")
// implementation("org.mozilla.geckoview:geckoview:139.0.20250523173407")
// https://mvnrepository.com/artifact/org.mozilla.geckoview/geckoview
implementation("org.mozilla.geckoview:geckoview:139.0.20250523173407")
implementation("com.vladsch.flexmark:flexmark-all:0.64.0")
implementation("com.vladsch.flexmark:flexmark-all:0.64.8")
// implementation 'com.vladsch.flexmark:flexmark-all:0.64.8'
// implementation("org.opencv:opencv-android:4.11.0")
// build.gradle에 추가
@ -162,5 +168,22 @@ dependencies {
// implementation ("me.everything:providers-core:1.0.1")
// implementation ("androidx.window:window:1.0.0")
// implementation("io.github.vaneproject:hanguleditor:1.0.0")
constraints {
// ⚠️ 이 버전을 프로젝트 루트의 build.gradle.kts에 정의된 kotlinVersion 값과 정확히 일치시키세요.
val targetKotlinVersion = "2.0.20"
implementation("org.jetbrains.kotlin:kotlin-stdlib") {
version { strictly(targetKotlinVersion) }
// reason = "Align all Kotlin stdlib versions with the compiler plugin version"
}
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") {
version { strictly(targetKotlinVersion) }
// reason = "Align all Kotlin stdlib versions with the compiler plugin version"
}
implementation("org.jetbrains.kotlin:kotlin-stdlib-common") {
version { strictly(targetKotlinVersion) }
// reason = "Align all Kotlin stdlib versions with the compiler plugin version"
}
}
}
fun getDateTime() = SimpleDateFormat("yyyyMMddHHmm").format(Date()).toLong()

View File

@ -55,7 +55,7 @@
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- <queries>-->
<!-- <intent>-->

View File

@ -62,4 +62,14 @@
//// // 앱으로 오류 신호 전달
//// browser.runtime.sendMessage({ type: 'RELOAD_REQUEST' });
//// }
////});
////});
browser.webRequest.onBeforeRequest.addListener(
function(details) {
console.log("Request intercepted for URL:", details.url);
// 이 예시는 단순히 로그를 남기므로 요청을 변경하거나 차단하지 않음
return {};
},
{urls: ["<all_urls>"]}, // 모든 URL에 대해 요청 듣기
[]
);

View File

@ -316,7 +316,9 @@ if (keywords.every(keyword => !url.includes(keyword))) {
document.addEventListener('touchend', function(e) {
setTimeout(() => {
autoScrollAndSave();
if(location.href.search("ijavtorrent") < 0) {
autoScrollAndSave();
}
}, 5);
});
}
@ -468,9 +470,9 @@ function ytDown() {
}
function handleCommon() {
async function handleCommon() {
// 공통 광고 제거
alert(JSON.stringify({COOKIES : document.cookie}))
alert(JSON.stringify({COOKIES: document.cookie}))
if (document.querySelector(".top_google_ad_space")) document.querySelector(".top_google_ad_space").remove();
document.querySelectorAll(".adv-group, [id^='div-gpt-ad'], [id^='div_adnmore_area'], [class^='adv-groupno'], [class^='code-block'], .ad-template").forEach(e => e.remove());
if (document.querySelector('#xpromo-bottom-sheet')) document.querySelector('#xpromo-bottom-sheet').remove();
@ -495,8 +497,11 @@ function handleCommon() {
}
if (location.href.search("javt") > -1 &&document.querySelectorAll('[class^="col-md-4 mb-4 video-item"]').length > 1) {
if (location.href.search("javt") > -1 && document.querySelectorAll('[class^="col-md-4 mb-4 video-item"]').length > 1) {
var datas = []
document.querySelectorAll('[class^="col-md-4 mb-4 video-item"]').forEach(function (e) {
var date = 0
try {
@ -609,11 +614,39 @@ function handleCommon() {
}
);
gotoNext()
// gotoNext()
}
else if(location.href.search("javt")) {
console.log(`Found TEST`);
const imageSelector = 'img[class*="mw-100"][src*="images"]';
const images = Array.from(document.querySelectorAll(imageSelector));
console.log(`Found ${images}`);
if (images.length > 0) {
const validImageUrls = images.map(img => img.src)
.filter(src => src && src.startsWith('http'));
const uniqueUrls = [...new Set(validImageUrls)];
console.log(`Found ${'$'}{uniqueUrls.length} unique images to cache.`);
// 3. 각 URL을 순회하며 Base64로 변환하고 즉시 네이티브로 전송
// (모든 작업을 병렬로 처리하지 않고 순차적(또는 하나씩)으로 보내 메모리 부담을 줄임)
for (const url of uniqueUrls) {
const base64Data = await getBase64FromUrl(url);
if (base64Data) {
// 이미지 하나를 성공할 때마다 네이티브로 즉시 전송
sendMessage({
type: "SINGLE_IMAGE_DATA",
imgSrc: url,
base64Data: base64Data
});
}
}
}
}
if (window.scrollY < 5) {
console.log("window.scrollY >>> " + window.scrollY)
window.scrollTo({ top: 5, behavior: 'smooth' });
window.scrollTo({top: 5, behavior: 'smooth'});
}
}
@ -642,7 +675,7 @@ function handleToreentZota() {
}
})
var description = e.querySelector('.flex-none w-16 text-center').textContent + e.querySelector('.badge badge-third w-auto px-1 flex-none mr-2 float-left').textContent
var md = e.querySelector(".flex-none w-14 text-center hidden md:block").textContent
var md = e.querySelector(".flex-none w-14 text-center hidden md").textContent
let todayYear = new Date().getFullYear();
let now = new Date();
@ -906,4 +939,23 @@ function autoScrollAndHandleDotax() {
// // 시작
// scrollAndSend();
}
}
}
async function getBase64FromUrl(url) {
try {
const response = await fetch(url);
const blob = await response.blob();
// FileReader를 사용해 Blob을 Data URL (Base64)로 변환
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result); // 결과 예: "data:image/png;base64,iVBORw0..."
reader.onerror = reject;
reader.readAsDataURL(blob);
});
} catch (e) {
console.error("Base64 conversion error for:", url, e);
return null;
}
}

View File

@ -15,16 +15,13 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package bums.lunatic.launcher
//import rasel.lunar.launcher.home.LauncherHome.Companion.rssSet
//import kr.lunaticbum.utils.ui.DisplayUtil
import android.annotation.SuppressLint
import android.app.SearchManager
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.res.Configuration
import android.net.Uri
import android.os.Build
@ -44,7 +41,6 @@ import android.view.KeyEvent.KEYCODE_DPAD_UP
import android.view.MotionEvent
import android.view.PointerIcon
import android.view.View
import android.view.WindowInsets
import android.view.WindowManager
import androidx.activity.OnBackPressedCallback
import androidx.annotation.RequiresApi
@ -55,16 +51,12 @@ import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
import bums.lunatic.launcher.apps.AppDrawer
import bums.lunatic.launcher.common.CommonActivity
import bums.lunatic.launcher.databinding.LauncherActivityBinding
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_STATUS_BAR
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
import bums.lunatic.launcher.helpers.ForeGroundService
import bums.lunatic.launcher.helpers.HeadsetActionButtonReceiver
import bums.lunatic.launcher.home.GeckoWeb
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
@ -78,11 +70,8 @@ import bums.lunatic.launcher.tokiz.Webtoons
import bums.lunatic.launcher.tokiz.YouTube
import bums.lunatic.launcher.tokiz.Zota
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.utils.KakaoPublicTransfer
import bums.lunatic.launcher.workers.WorkersDb
import com.google.android.gms.common.util.DataUtils
import com.google.android.material.color.DynamicColors
import com.google.gson.Gson
import com.yausername.ffmpeg.FFmpeg
import com.yausername.youtubedl_android.YoutubeDL
import com.yausername.youtubedl_android.YoutubeDLException
@ -90,9 +79,7 @@ import io.realm.kotlin.ext.query
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kr.lunaticbum.utils.ui.DisplayUtil
import org.json.JSONObject
import org.jsoup.helper.DataUtil
import org.mozilla.geckoview.ExperimentDelegate
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoRuntime
@ -122,7 +109,7 @@ open class LauncherActivity : CommonActivity() {
var hiddenLoader : HashMap<String,GeckoWeb> = hashMapOf()
fun contentsLoad(url : String){
if (isDestroyed == false && isFinishing == false) {
Uri.parse(url).host?.let { host ->
url.toUri()?.host?.let { host ->
if (!hiddenLoader.contains(host)) {
GeckoWeb(this).apply {
LunaticLauncher.mHourlyLogWriter?.writeLog("contentsLoad FIRST_LOAD$host")
@ -168,13 +155,13 @@ open class LauncherActivity : CommonActivity() {
KEYCODE_BUTTON_A->{
WorkersDb.getRealm().apply {
writeBlocking {
var ddd = copyFromRealm(WorkersDb.getRssQuery("", arrayListOf(),false).limit(100).query("read == $0", 0).query("vote != $0", true).find()).map { it.originPage() }
var origin = ddd.first()
RssViewBuilder(lActivity!!)
.setRssList(arrayListOf<String>().apply { this.addAll(ddd) })
.setRssId(origin)
.showIconClose(true).showIconBack(false).showProgressBar(true).backPressToClose(false).webViewMixedContentMode(1)
.show(origin)
// var ddd = copyFromRealm(WorkersDb.getRssQuery("", arrayListOf(),false).limit(100).query("read == $0", 0).query("vote != $0", true).find()).map { it.originPage() }
// var origin = ddd.first()
// RssViewBuilder(lActivity!!)
// .setRssList(arrayListOf<String>().apply { this.addAll(ddd) })
// .setRssId(origin)
// .showIconClose(true).showIconBack(false).showProgressBar(true).backPressToClose(false).webViewMixedContentMode(1)
// .show(origin)
}
}
}
@ -195,15 +182,15 @@ open class LauncherActivity : CommonActivity() {
writeBlocking {
var ddd = copyFromRealm(WorkersDb.getVotedRss().limit(100).find()).map { it.originPage() }
var origin = ddd.first()
RssViewBuilder(lActivity!!)
.setRssList(arrayListOf<String>().apply {
var jjjj = hashSetOf<String>()
jjjj.addAll(ddd)
this.addAll(jjjj)}
)
.setRssId(origin)
.showIconClose(true).showIconBack(false).showProgressBar(true).backPressToClose(false).webViewMixedContentMode(1)
.show(origin)
// RssViewBuilder(lActivity!!)
// .setRssList(arrayListOf<String>().apply {
// var jjjj = hashSetOf<String>()
// jjjj.addAll(ddd)
// this.addAll(jjjj)}
// )
// .setRssId(origin)
// .showIconClose(true).showIconBack(false).showProgressBar(true).backPressToClose(false).webViewMixedContentMode(1)
// .show(origin)
}
}
}
@ -279,12 +266,12 @@ open class LauncherActivity : CommonActivity() {
var origin = ddd.first()
var jjjj = hashSetOf<String>()
jjjj.addAll(ddd)
RssViewBuilder(lActivity!!)
.setRssList(arrayListOf<String>().apply {
this.addAll(jjjj)})
.setRssId(origin)
.showIconClose(true).showIconBack(false).showProgressBar(true).backPressToClose(false).webViewMixedContentMode(1)
.show(origin)
// RssViewBuilder(lActivity!!)
// .setRssList(arrayListOf<String>().apply {
// this.addAll(jjjj)})
// .setRssId(origin)
// .showIconClose(true).showIconBack(false).showProgressBar(true).backPressToClose(false).webViewMixedContentMode(1)
// .show(origin)
}
}
}
@ -312,8 +299,8 @@ open class LauncherActivity : CommonActivity() {
}
MotionEvent.ACTION_BUTTON_RELEASE -> {
if (actionButtonPressX == ev.x && actionButtonPressY == ev.y) {
Blog.LOGE("DisplayUtil.width >>> ${DisplayUtil.width} ${actionButtonPressX}")
Blog.LOGE("DisplayUtil.width >>> ${DisplayUtil.height} ${actionButtonPressY}")
// Blog.LOGE("DisplayUtil.width >>> ${DisplayUtil.width} ${actionButtonPressX}")
// Blog.LOGE("DisplayUtil.width >>> ${DisplayUtil.height} ${actionButtonPressY}")
if(actionButtonPressX.toInt() == 480 && actionButtonPressY < 2000) {
Blog.LOGE("Arrow Center Click")
onClickCenterButton()
@ -356,7 +343,7 @@ open class LauncherActivity : CommonActivity() {
showContents(v.id)
}
override fun onNewIntent(intent: Intent?) {
override fun onNewIntent(intent: Intent) {
Blog.LOGE("onNewIntent intent >> ${intent}")
if(intent?.action?.equals(Intent.ACTION_SEND) == true &&
intent?.hasExtra(Intent.EXTRA_TEXT) == true) {

View File

@ -21,20 +21,16 @@ package bums.lunatic.launcher
import android.app.Application
import android.content.ComponentCallbacks2
import android.database.sqlite.SQLiteDatabase
import android.net.Uri
import android.view.PixelCopy.request
import bums.lunatic.launcher.helpers.HourlyLogWriter
import bums.lunatic.launcher.helpers.PrefHelper
import bums.lunatic.launcher.home.Base64RequestHandler
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 okhttp3.logging.HttpLoggingInterceptor
import java.io.File
import java.io.IOException
import java.net.HttpURLConnection
import java.util.concurrent.TimeUnit
@ -47,7 +43,7 @@ internal class LunaticLauncher : Application() {
override fun onCreate() {
super.onCreate()
appContext = this
Base.initialize(this)
// Base.initialize(this)
PrefHelper.initialize(this)
val dir = File("/storage/emulated/0/bums_ob/BUM'S PACED /scraped/logs")
///BUM'S PACED/pdfs
@ -64,33 +60,40 @@ internal class LunaticLauncher : Application() {
val cache = Cache(File(this.filesDir, "picasso-cache"), cacheSize)
val okHttpClient = OkHttpClient.Builder()
.cache(cache)
.addInterceptor(logging)
.addInterceptor { chain ->
var request = chain.request()
val cacheControl = request.header("Cache-Control")
if (cacheControl?.contains("only-if-cached") == true) {
val newCacheControl = cacheControl.replace("only-if-cached", "")
.trim()
.ifEmpty { "max-stale=2419200" }
request = request.newBuilder()
.header("Cache-Control", newCacheControl)
.build()
val isA = request.url.host.contains("ijavtorrent")
val host = if (request.url.host.contains("ijavtorrent")) {
"ijavtorrent.com"
} else {
chain.request().url.host
}
val host = chain.request().url.host
val newRequest = chain.request().newBuilder().addHeader("authority",host)
val newRequestBuilder = request.newBuilder().addHeader("authority",host)
.addHeader("Host",host)
.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("User-Agent","Mozilla/5.0 (Android 15; Mobile; rv:139.0) Gecko/139.0 Firefox/139.0")
.addHeader("Accept",if (isA == false) {
"image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5"
} else {
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"
})
.addHeader("Accept-Language","ko-KR,en-US;q=0.5")
.addHeader("Accept-Encoding","gzip, deflate, br, zstd")
.addHeader("Referer",host)
.build()
// .removeHeader("Cache-Control")
// if (isA) {
//// newRequestBuilder.addHeader("sec-ch-ua-platform","macOS")
// newRequestBuilder.addHeader("sec-fetch-dest","document")
// newRequestBuilder.addHeader("sec-fetch-mode","navigate")
//
// }
Blog.LOGE("chain.request().url() >>> ${chain.request().url} : host : $host")
val response = chain.proceed(newRequest)
// Blog.LOGE("chain.request().url() >>> ${chain.request().url} : host : $host")
val response = chain.proceed(newRequestBuilder.build())
Blog.LOGE("응답 코드: ${response.code}:${response.message}")
response
}
.addInterceptor(logging)
.callTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS) // 연결 타임아웃
.readTimeout(60, TimeUnit.SECONDS) // 읽기 타임아웃
@ -98,6 +101,7 @@ internal class LunaticLauncher : Application() {
.build()
val picasso = Picasso.Builder(this)
.addRequestHandler(Base64RequestHandler())
.downloader(OkHttp3Downloader(okHttpClient))
.build()

View File

@ -1,22 +1,14 @@
package bums.lunatic.launcher.behavior
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.recyclerview.widget.RecyclerView
import bums.lunatic.launcher.R
import bums.lunatic.launcher.behavior.calendar.CalendarBean
import bums.lunatic.launcher.behavior.calendar.CalendarFactory.getMonthOfDayList
import bums.lunatic.launcher.behavior.calendar.CalendarUtil
import bums.lunatic.launcher.databinding.ItemCalendarBinding
import com.google.android.material.appbar.AppBarLayout
import java.util.Date
import kotlin.math.abs
class Behavior: AppCompatActivity() {
@ -32,7 +24,7 @@ class Behavior: AppCompatActivity() {
private val fadeIn by lazy { AnimationUtils.loadAnimation(this, R.anim.fade_in) }
private val fadeOut by lazy { AnimationUtils.loadAnimation(this, R.anim.fade_out) }
val dateArr: IntArray = CalendarUtil.getYMD(Date())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
@ -41,7 +33,7 @@ class Behavior: AppCompatActivity() {
initTopBarAnimation()
initRecyclerView()
loadSample()
}
@ -86,53 +78,8 @@ class Behavior: AppCompatActivity() {
)
}
private fun initRecyclerView() {
with(findViewById<RecyclerView>(R.id.rv_main)) {
adapter = sampleAdapter
}
with(findViewById<RecyclerView>(R.id.calendarDateView)) {
adapter = CalAdapter().apply {
items.clear()
items.addAll(getMonthOfDayList(
dateArr[0],
dateArr[1]
))
}
}
}
private fun loadSample() {
sampleAdapter.notifySample()
}
}
class CalAdapter : RecyclerView.Adapter<CalAdapter.CalViewHolder>() {
val items = mutableListOf<CalendarBean>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = CalViewHolder(ItemCalendarBinding.inflate(LayoutInflater.from(parent.context)))
override fun onBindViewHolder(holder: CalViewHolder, position: Int) {
holder.bind.day.apply {
val bean = items[position]
this.text = bean?.day.toString()
if (bean?.monthFlag != 0) {
this.setTextColor(Color.WHITE)
} else {
this.setTextColor(Color.BLACK)
}
}
}
override fun getItemCount() = items.size
// fun notifySample() {
// items.clear()
// (1..10).forEach {
// items.add(it)
// }
// notifyDataSetChanged()
// }
class CalViewHolder(val bind: ItemCalendarBinding) : RecyclerView.ViewHolder(bind.root)
}

View File

@ -1,10 +0,0 @@
package bums.lunatic.launcher.behavior.calendar
import android.view.View
import android.view.ViewGroup
interface CalendarAdapter {
fun getView(convertView: View?, parentView: ViewGroup?, bean: CalendarBean?): View
// fun hasChildView() : Boolean
}

View File

@ -1,54 +0,0 @@
//package bums.lunatic.launcher.behavior.calendar;
//
//public class CalendarBean {
// public int year;
// public int month;
// public int day;
// public int week;
//
// //-1,0,1
// public int monthFlag;
//
// //显示
//
// public CalendarBean(int year, int month, int day) {
// this.year = year;
// this.month = month;
// this.day = day;
// }
//
// public String getDisplayWeek(){
// String s="";
// switch(week){
// case 1:
// s="星期日";
// break;
// case 2:
// s="星期一";
// break;
// case 3:
// s="星期二";
// break;
// case 4:
// s="星期三";
// break;
// case 5:
// s="星期四";
// break;
// case 6:
// s="星期五";
// break;
// case 7:
// s="星期六";
// break;
//
// }
// return s ;
// }
//
// @Override
// public String toString() {
// String s=year+"/"+month+"/"+day;
// return s;
// }
//}

View File

@ -1,29 +0,0 @@
package bums.lunatic.launcher.behavior.calendar
class CalendarBean //显示
(var year: Int, var month: Int, var day: Int) {
var week: Int = 0
//-1,0,1
var monthFlag: Int = 0
val displayWeek: String
get() {
var s = ""
when (week) {
1 -> s = "星期日"
2 -> s = "星期一"
3 -> s = "星期二"
4 -> s = "星期三"
5 -> s = "星期四"
6 -> s = "星期五"
7 -> s = "星期六"
}
return s
}
override fun toString(): String {
val s = "$year/$month/$day"
return s
}
}

View File

@ -1,152 +0,0 @@
package bums.lunatic.launcher.behavior.calendar
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import bums.lunatic.launcher.R
import bums.lunatic.launcher.behavior.calendar.CalendarFactory.getMonthOfDayList
import com.example.accountbook.calendar.CalendarTopView
import com.example.accountbook.calendar.CalendarTopViewChangeListener
import java.util.Date
import java.util.LinkedList
class CalendarDateView(context: Context, attrs: AttributeSet?):
ViewPager(context, attrs), CalendarTopView {
var views = HashMap<Int, CalendarView>()
private var mCaledarLayoutChangeListener: CalendarTopViewChangeListener? = null
private var onItemClickListener: CalendarView.OnItemClickListener? = null
private val cache: LinkedList<CalendarView?> = LinkedList<CalendarView?>()
private val MAXCOUNT = 6
private var row = 6
fun setCalrow(row : Int) {
this.row = row
}
private var mAdapter: CalendarAdapter? = null
override var itemHeight = 0
private set
fun setAdapter(adapter: CalendarAdapter?) {
mAdapter = adapter
initialize()
initData()
}
fun reload() {
Log.i(this@CalendarDateView.javaClass.simpleName , "reload()")
sss.notifyDataSetChanged()
}
fun setOnItemClickListener(onItemClickListener: CalendarView.OnItemClickListener?) {
this.onItemClickListener = onItemClickListener
}
init {
val a = context.obtainStyledAttributes(attrs, R.styleable.CalendarDateView)
row = a.getInteger(R.styleable.CalendarDateView_cbd_calendar_row, 6)
a.recycle()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
// var calendarHeight = 0
if (adapter != null) {
(getChildAt(0) as CalendarView)?.let {
// calendarHeight = it.measuredHeight
itemHeight = it.itemHeight
}
}
setMeasuredDimension(
widthMeasureSpec,
MeasureSpec.makeMeasureSpec(heightMeasureSpec, MeasureSpec.EXACTLY)
)
}
val dateArr: IntArray = CalendarUtil.getYMD(Date())
var sss = object : PagerAdapter() {
override fun getCount(): Int {
// Log.i(this@CalendarDateView::class.java.simpleName, "container >>> setAdapter getCount")
return Int.MAX_VALUE
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view === `object`
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
Log.i(this@CalendarDateView::class.java.simpleName, "container >>> ${container} position >> ${position}")
val view: CalendarView = if (!cache.isEmpty()) {
cache.removeFirst()!!
} else {
CalendarView(container.context, row)
}
view.setOnItemClickListener(onItemClickListener)
view.setAdapter(mAdapter)
container.addView(view)
views[position] = view
view.apply {
setData(
getMonthOfDayList(
dateArr[0],
dateArr[1] + position - Int.MAX_VALUE / 2
), position == Int.MAX_VALUE / 2
)
}
return view
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
Log.i(this@CalendarDateView.javaClass.simpleName , "destroyItem >>> position ${position}")
container.removeView(`object` as View)
cache.addLast(`object` as CalendarView)
views.remove(position)
}
}
private fun initialize() {
setAdapter(sss)
addOnPageChangeListener(object: SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
onItemClickListener?.let{
views[position]?.let {v ->
val obs: Array<Any> = v.select
it.onItemClick(
obs[0] as View,
obs[1] as Int,
obs[2] as CalendarBean
)
}
}
mCaledarLayoutChangeListener?.onLayoutChange(this@CalendarDateView)
}
})
}
private fun initData() {
setCurrentItem(Int.MAX_VALUE / 2, false)
adapter!!.notifyDataSetChanged()
}
override val currentSelectPositon: IntArray
get() {
var view = views[currentItem]
if (view == null) {
view = getChildAt(0) as? CalendarView
}
return view?.getSelectPosition() ?: IntArray(4)
}
override fun setCalendarTopViewChangeListener(listener: CalendarTopViewChangeListener?) {
mCaledarLayoutChangeListener = listener
}
}

View File

@ -1,66 +0,0 @@
package bums.lunatic.launcher.behavior.calendar
import android.util.Log
import bums.lunatic.launcher.behavior.calendar.CalendarUtil.getDayOfWeek
import java.util.Calendar
object CalendarFactory {
private val cache = HashMap<String, List<CalendarBean>>()
fun getMonthOfDayList(y: Int, m: Int): List<CalendarBean> {
Log.e("TIME CHECK" , "fun getMonthOfDayList Start")
val key = y.toString() + "" + m
if (cache.containsKey(key)) {
val list = cache[key]
if (list == null) {
cache.remove(key)
} else {
return list
}
}
val list: MutableList<CalendarBean> = ArrayList()
cache[key] = list
val fweek: Int = getDayOfWeek(y, m, 1)
val total: Int = CalendarUtil.getDayOfMaonth(y, m)
for (i in fweek - 1 downTo 1) {
val bean = getCalendarBean(y, m, 1 - i)
bean.monthFlag = -1
list.add(bean)
}
for (i in 0 until total) {
val bean = getCalendarBean(y, m, i + 1)
list.add(bean)
}
for (i in 0 until 42 - (fweek - 1) - total) {
val bean = getCalendarBean(y, m, total + i + 1)
bean.monthFlag = 1
list.add(bean)
}
Log.e("TIME CHECK" , "fun getMonthOfDayList END")
return list
}
fun getCalendarBean(year: Int, month: Int, day: Int): CalendarBean {
val calendar: Calendar = Calendar.getInstance()
.apply { this.set(year, month - 1, day) }
val year = calendar.get(Calendar.YEAR)
val month = calendar.get(Calendar.MONTH) + 1
val day = calendar.get(Calendar.DATE)
val bean = CalendarBean(year, month, day)
bean.week = CalendarUtil.getDayOfWeek(year, month, day)
// val chinaDate: Array<String> = ChinaDate.getChinaDate(year, month, day)
// bean.chinaMonth = chinaDate[0]
// bean.chinaDay = chinaDate[1]
return bean
}
@JvmStatic
fun main(args: Array<String>) {
}
}

View File

@ -1,9 +0,0 @@
package com.example.accountbook.calendar
interface CalendarTopView {
val currentSelectPositon: IntArray?
val itemHeight: Int
fun setCalendarTopViewChangeListener(listener: CalendarTopViewChangeListener?)
}

View File

@ -1,7 +0,0 @@
package com.example.accountbook.calendar
interface CalendarTopViewChangeListener {
fun onLayoutChange(topView: CalendarTopView) {
}
}

View File

@ -1,37 +0,0 @@
package bums.lunatic.launcher.behavior.calendar
import java.util.Calendar
import java.util.Date
object CalendarUtil {
fun getDayOfWeek(y: Int, m: Int, day: Int): Int {
val calendar: Calendar = Calendar.getInstance()
calendar.set(y, m - 1, day)
return calendar.get(Calendar.DAY_OF_WEEK)
}
//获取一月最大天数
fun getDayOfMaonth(y: Int, m: Int): Int {
val cal: Calendar = Calendar.getInstance()
cal.set(y, m - 1, 1)
return cal.getActualMaximum(Calendar.DATE)
}
fun getMothOfMonth(y: Int, m: Int): Int {
val cal: Calendar = Calendar.getInstance()
cal.set(y, m - 1, 1)
val dateOfMonth: Int = cal.get(Calendar.MONTH)
return dateOfMonth + 1
}
fun getYMD(date: Date?): IntArray {
val cal: Calendar = Calendar.getInstance()
date?.let { cal.setTime(it) }
return intArrayOf(
cal.get(Calendar.YEAR),
cal.get(Calendar.MONTH) + 1,
cal.get(Calendar.DATE)
)
}
}

View File

@ -1,201 +0,0 @@
package bums.lunatic.launcher.behavior.calendar
import android.content.Context
import android.graphics.Rect
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import bums.lunatic.launcher.behavior.calendar.CalendarUtil.getYMD
import java.util.Date
class CalendarView : ViewGroup {
private var selectPosition = -1
private var adapter: CalendarAdapter? = null
private var data: List<CalendarBean>? = null
private var onItemClickListener: OnItemClickListener? = null
private var row = 6
private val column = 7
private var itemWidth = 0
var itemHeight = 0
private set
private var isToday = false
interface OnItemClickListener {
fun onItemClick(view: View?, position: Int, bean: CalendarBean?)
}
constructor(context: Context?, row: Int) : super(context) {
this.row = row
}
fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) {
this.onItemClickListener = onItemClickListener
}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
setWillNotDraw(false)
}
fun setAdapter(adapter: CalendarAdapter?) {
this.adapter = adapter
}
fun setCalrow(row : Int) {
if (this.row != row) {
this.row = row
removeAllViews()
}
}
fun setData(data: List<CalendarBean>?, isToday: Boolean) {
this.data = data
this.isToday = isToday
setItem()
requestLayout()
}
private fun setItem() {
selectPosition = -1
if (adapter == null) {
throw RuntimeException("adapter is null,please setadapter")
}
Log.i("data >>> ","data ${data}")
for (i in data!!.indices) {
val bean = data!![i]
val chidView: View? = adapter?.getView(
getChildAt(i).also { v -> Log.i("data >>> ", "view $v") },
this,
bean
).also { v -> Log.i("data >>> ", "chidView $v") }
if (chidView != null && chidView != getChildAt(i)) {
addViewInLayout(chidView, i, chidView.layoutParams, true)
}
if (isToday && selectPosition == -1) {
val date = getYMD(Date())
if (bean.year == date[0] && bean.month == date[1] && bean.day == date[2]) {
selectPosition = i
}
} else {
if (selectPosition == -1 && bean.day == 1) {
selectPosition = i
}
}
chidView?.isSelected = selectPosition == i
setItemClick(chidView, i, bean)
}
}
val select: Array<Any>
get() = arrayOf(
getChildAt(selectPosition), selectPosition,
data!![selectPosition]
)
fun setItemClick(view: View?, potsion: Int, bean: CalendarBean?) {
view?.setOnClickListener {
if (selectPosition != -1) {
getChildAt(selectPosition).isSelected = false
getChildAt(potsion).isSelected = true
}
selectPosition = potsion
if (onItemClickListener != null) {
onItemClickListener!!.onItemClick(view, potsion, bean)
}
}
}
fun getSelectPosition(): IntArray {
val rect = Rect()
try {
getChildAt(selectPosition).getHitRect(rect)
} catch (e: Exception) {
e.printStackTrace()
}
return intArrayOf(rect.left, rect.top, rect.right, rect.top)
}
var lastwidthMeasureSpec = 0
var lastheightMeasureSpec = 0
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
Log.e(this.javaClass::class.java.simpleName , "this count check ${this}")
if (widthMeasureSpec != lastwidthMeasureSpec || heightMeasureSpec != lastheightMeasureSpec) {
val parentWidth =
MeasureSpec.getSize(
MeasureSpec.makeMeasureSpec(
widthMeasureSpec,
MeasureSpec.EXACTLY
)
)
val parentH =
MeasureSpec.getSize(
MeasureSpec.makeMeasureSpec(
heightMeasureSpec,
MeasureSpec.EXACTLY
)
)
itemWidth = parentWidth / column
itemHeight = parentH / row
// itemWidth
val view = getChildAt(0) ?: return
val params = view.layoutParams
if (params != null && params.height > 0) {
itemHeight = params.height
}
setMeasuredDimension(parentWidth, itemHeight * row)
if (childCount.equals(row*column))
for (i in 0 until childCount) {
val childView = getChildAt(i)
childView.measure(
MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY)
)
}
}
Log.i(
TAG,
"onMeasure() called with: itemHeight = [$itemHeight], itemWidth = [$itemWidth]"
)
lastwidthMeasureSpec = widthMeasureSpec
lastheightMeasureSpec = heightMeasureSpec
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
if (changed && childCount.equals(row*column))
for (i in 0 until childCount) {
layoutChild(getChildAt(i), i, l, t, r, b)
}
}
override fun addViewInLayout(
child: View?,
index: Int,
params: LayoutParams?,
preventRequestLayout: Boolean
): Boolean {
Log.d("CalendarView, time","time")
return super.addViewInLayout(child, index, params, preventRequestLayout)
}
private fun layoutChild(view: View, position: Int, l: Int, t: Int, r: Int, b: Int) {
var l = l
var t = t
var r = r
var b = b
val cc = position % column
val cr = position / column
val itemWidth = view.measuredWidth
val itemHeight = view.measuredHeight
l = cc * itemWidth
t = cr * itemHeight
r = l + itemWidth
b = t + itemHeight
view.layout(l, t, r, b)
}
companion object {
private const val TAG = "CalendarView"
}
}

View File

@ -7,9 +7,7 @@ import android.os.Bundle
import android.os.Environment
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import bums.lunatic.launcher.apps.SearchMenu
import bums.lunatic.launcher.helpers.PrefBoolean

View File

@ -35,8 +35,6 @@ import bums.lunatic.launcher.model.RssDataInterface
import bums.lunatic.launcher.model.RssDataType
import com.squareup.picasso.NetworkPolicy
import com.squareup.picasso.Picasso
import java.net.URLEncoder
import java.nio.charset.Charset
import java.text.SimpleDateFormat
import java.util.Date

View File

@ -1,43 +1,42 @@
/*
* Lunar Launcher
* Copyright (C) 2022 Md Rasel Hossain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package bums.lunatic.launcher.helpers
import android.app.admin.DeviceAdminReceiver
import android.content.Context
import android.content.Intent
import androidx.localbroadcastmanager.content.LocalBroadcastManager
internal class AdminReceiver : DeviceAdminReceiver() {
override fun onDisabled(context: Context, intent: Intent) {
super.onDisabled(context, intent)
LocalBroadcastManager.getInstance(context).sendBroadcast(
Intent("device_admin_action_disabled")
)
}
override fun onEnabled(context: Context, intent: Intent) {
super.onEnabled(context, intent)
LocalBroadcastManager.getInstance(context).sendBroadcast(
Intent("device_admin_action_enabled")
)
}
}
///*
// * Lunar Launcher
// * Copyright (C) 2022 Md Rasel Hossain
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
// */
//
//package bums.lunatic.launcher.helpers
//
//import android.app.admin.DeviceAdminReceiver
//import android.content.Context
//import android.content.Intent
//
//
//internal class AdminReceiver : DeviceAdminReceiver() {
//
// override fun onDisabled(context: Context, intent: Intent) {
// super.onDisabled(context, intent)
// LocalBroadcastManager.getInstance(context).sendBroadcast(
// Intent("device_admin_action_disabled")
// )
// }
//
// override fun onEnabled(context: Context, intent: Intent) {
// super.onEnabled(context, intent)
// LocalBroadcastManager.getInstance(context).sendBroadcast(
// Intent("device_admin_action_enabled")
// )
// }
//
//}

View File

@ -1,11 +1,13 @@
package bums.lunatic.launcher.helpers
import android.content.Context
import bums.lunatic.launcher.utils.Blog
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
import java.util.Date
import java.util.Locale
import java.util.concurrent.atomic.AtomicReference
class HourlyLogWriter(private val logDir: File) {

View File

@ -1,8 +1,8 @@
package bums.lunatic.launcher.helpers
import bums.lunatic.launcher.model.RssDataType
import kr.lunaticbum.utils.preferences.PrefKey
import kr.lunaticbum.utils.preferences.PreferencesHelper
import bums.lunatic.launcher.utils.PrefKey
import bums.lunatic.launcher.utils.PreferencesHelper
import java.math.BigDecimal

View File

@ -0,0 +1,77 @@
package bums.lunatic.launcher.home
import android.graphics.BitmapFactory
import android.util.Base64
import androidx.collection.LruCache
import com.squareup.picasso.Picasso
import com.squareup.picasso.Request
import com.squareup.picasso.RequestHandler
import java.io.IOException
/**
* Base64 데이터를 URL 키와 함께 저장하는 메모리 캐시 (Singleton 또는 DI로 관리)
* OOM(메모리 부족) 피하기 위해 비트맵 자체가 아닌 Base64 문자열을 저장합니다.
*/
object Base64ImageCache {
// 앱 최대 메모리의 1/8을 LruCache 크기로 할당 (조정 가능)
private val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
private val cacheSize = maxMemory / 8
// Key: Image URL, Value: Base64 Data String
private val lru: LruCache<String, String> = LruCache(cacheSize)
fun put(url: String, base64Data: String) {
if (lru.get(url) == null) {
lru.put(url, base64Data)
}
}
fun get(url: String): String? {
return lru.get(url)
}
}
/**
* Picasso가 요청한 URL이 Base64ImageCache에 있는지 확인하는 커스텀 핸들러
*/
class Base64RequestHandler : RequestHandler() {
private val DATA_SCHEME = "data:"
/**
* 핸들러가 처리할 있는 요청인지 확인
* (캐시에 URL이 존재하고, data: 스킴이 아닌 경우)
*/
override fun canHandleRequest(data: Request): Boolean {
val url = data.uri.toString()
// data: 스킴이 아니고, 우리 캐시에 URL 키가 존재할 때만 true 반환
return !url.startsWith(DATA_SCHEME) && Base64ImageCache.get(url) != null
}
/**
* 실제 이미지를 로드(디코딩)하여 Picasso에 반환
*/
@Throws(IOException::class)
override fun load(request: Request, networkPolicy: Int): Result? {
val url = request.uri.toString()
val base64String = Base64ImageCache.get(url) ?: return null
try {
// "data:image/png;base64," 접두사 분리
val pureBase64 = base64String.substring(base64String.indexOf(",") + 1)
// Base64 문자열을 바이트 배열로 디코딩
val decodedBytes = Base64.decode(pureBase64, Base64.DEFAULT)
// 바이트 배열을 비트맵으로 변환
val bitmap = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size)
?: throw IOException("Failed to decode Base64 string")
// Picasso에 비트맵 결과와 출처(DISK)를 반환 (DISK로 해야 메모리 캐싱을 다시 수행함)
return Result(bitmap, Picasso.LoadedFrom.DISK)
} catch (e: Exception) {
throw IOException("Error decoding base64 data for $url", e)
}
}
}

View File

@ -1,4 +1,5 @@
import com.vladsch.flexmark.html2md.converter.*
import com.vladsch.flexmark.html2md.converter.HtmlNodeRenderer
import com.vladsch.flexmark.html2md.converter.HtmlNodeRendererHandler
import com.vladsch.flexmark.util.data.DataHolder
import org.jsoup.nodes.Element

View File

@ -2,7 +2,6 @@ package bums.lunatic.launcher.home
import CustomVideoNodeRenderer
import android.app.Dialog
import android.app.DownloadManager
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
@ -11,8 +10,6 @@ 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.Build
import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.util.AttributeSet
@ -37,20 +34,14 @@ import android.widget.ProgressBar
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat.getSystemService
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.work.Worker
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
import bums.lunatic.launcher.R
import bums.lunatic.launcher.helpers.ForeGroundService
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.ACTION_SENDMSG
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.ACTION_VIDEO_DOWNLOAD
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.EXTRA_MSGKEY
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.EXTRA_TARGET_URL
import bums.lunatic.launcher.model.Dotax
import bums.lunatic.launcher.model.DotaxArticles
import bums.lunatic.launcher.model.getRssData
import bums.lunatic.launcher.model.others.Button
import bums.lunatic.launcher.tokiz.data.model.PortMessage
import bums.lunatic.launcher.tokiz.view.BWebview
import bums.lunatic.launcher.utils.Blog
@ -60,16 +51,8 @@ import com.google.gson.Gson
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter
import com.yausername.youtubedl_android.YoutubeDL
import com.yausername.youtubedl_android.YoutubeDLRequest
import com.yausername.youtubedl_android.YoutubeDLResponse
import io.realm.kotlin.ext.isValid
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kr.lunaticbum.utils.service.ServiceUtil.getSystemService
import kr.lunaticbum.utils.service.ServiceUtil.layoutInflater
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONException
@ -77,7 +60,6 @@ import org.json.JSONObject
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.mozilla.gecko.util.ThreadUtils
import org.mozilla.gecko.util.ThreadUtils.runOnUiThread
import org.mozilla.geckoview.ExperimentDelegate
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoSession
@ -93,7 +75,6 @@ import java.io.FileOutputStream
import java.io.InputStream
import java.text.SimpleDateFormat
import java.util.Date
import java.util.UUID
class GeckoWeb : BWebview {
constructor(context: Context?) : super(context) {
@ -402,13 +383,13 @@ class GeckoWeb : BWebview {
return result
}
fun copyToClipboard(text: String?) {
if (text == null) return
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("Media URL", text)
clipboard.setPrimaryClip(clip)
Toast.makeText(context, "주소가 복사되었습니다.", Toast.LENGTH_SHORT).show()
}
// fun copyToClipboard(text: String?) {
// if (text == null) return
// val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
// val clip = ClipData.newPlainText("Media URL", text)
// clipboard.setPrimaryClip(clip)
// Toast.makeText(context, "주소가 복사되었습니다.", Toast.LENGTH_SHORT).show()
// }
suspend fun getFormatList(url: String): List<String> = withContext(Dispatchers.IO) {
@ -737,12 +718,20 @@ class GeckoWeb : BWebview {
override fun onPortMessage(
message: Any, port: WebExtension.Port
) {
Blog.LOGE("PortDelegate", "Received message from extension: $message")
if (message is String && message.contains("type")) {
try {
var lPortMessage =
Gson().fromJson<PortMessage>(message, PortMessage::class.java)
when(lPortMessage.type) {
"SINGLE_IMAGE_DATA"-> {
if (lPortMessage.imgSrc != null && lPortMessage.base64Data != null) {
// *** 핵심: 수신한 Base64 데이터를 커스텀 캐시에 저장 ***
Log.d("GeckoImageCache", "캐싱 저장 시도: ${lPortMessage.imgSrc}")
Base64ImageCache.put(lPortMessage.imgSrc!!, lPortMessage.base64Data!!)
}
}
"getListResult" -> {
}
"BookContents"->{

View File

@ -1,250 +1,250 @@
package bums.lunatic.launcher.home
import android.content.Context
import android.content.Intent
import android.os.Environment
import android.webkit.CookieManager
import androidx.core.content.FileProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kr.lunaticbum.awesomewebview.helpers.DownPicUtil
import kr.lunaticbum.awesomewebview.helpers.DownPicUtil.DownFinishListener
import kr.lunaticbum.utils.log.LogUtil
import org.jsoup.Jsoup
import org.jsoup.UnsupportedMimeTypeException
import java.io.BufferedWriter
import java.io.File
import java.io.FileWriter
import java.net.URL
import java.text.SimpleDateFormat
import java.util.Date
val defaultTime = 200L
class OfflineContents(val context: Context, val host : String, val cookie: String, val agent: String, val current: String, val newPath: String, val value: String, val autoCheck : Boolean, val mediaUrls : ArrayList<String>) {
val targetFile : File
val filePath = "index.html"
val path = File(
Environment.getExternalStorageDirectory(),
"bums"
)
val newFolder = File(path, newPath).apply { mkdirs() }
val newFile : File
var htmlString : StringBuffer
val urlPathMap : HashMap<String,String> = hashMapOf()
var reqCount = 0
var endOfLooPCheck = false
val lDownFinishListener = object : DownFinishListener {
override fun onDownFinish(url: String, path: String) {
LogUtil.e("Url >> ${url} path >> ${path}")
urlPathMap.put(url, path)
reqCount -= 1
if (reqCount == 0 && endOfLooPCheck) {
enofLoop()
}
}
override fun onError() {
reqCount -= 1
if (reqCount == 0 && endOfLooPCheck) {
enofLoop()
}
}
}
init {
targetFile = File(newFolder, filePath)
newFile = File(
path,
newPath.plus(SimpleDateFormat("yyyMMdd").format(Date())).plus(".html")
)
htmlString= trimHtnl(value, host)
}
var onItEndof = false
fun enofLoop() {
if (onItEndof) return
onItEndof = true
LogUtil.e("on it enofLoop")
urlPathMap.forEach { t, u ->
val file = File(u)
var contentsUriString = FileProvider.getUriForFile(
context,
"${context.packageName}.fileprovider",
file
).toString()
var targetString = t
var targetIdx = htmlString.indexOf(targetString)
if (targetIdx > 0) {
htmlString?.replace(
targetIdx,
targetIdx.plus(targetString.length),
contentsUriString
)
}
targetString = t.replace("&", "&amp;")
targetIdx = htmlString.indexOf(targetString)
if (targetIdx > 0) {
htmlString?.replace(
targetIdx,
targetIdx.plus(targetString.length),
contentsUriString
)
}
}
if (autoCheck) {
LogUtil.e("on it enofLoop autoCheck ${autoCheck}")
moveFile()
context.startActivity(Intent(context,RssViewerActivity::class.java).apply {
action = Intent.ACTION_VIEW
data = FileProvider.getUriForFile(
context,
"${context.packageName}.fileprovider",
newFile
)
})
} else {
moveFile()
}
}
fun moveFile() {
indexSave(htmlString, targetFile, host)
targetFile.copyTo(newFile)
if (targetFile.parentFile.isDirectory) {
targetFile.parentFile.listFiles().forEach {
it.delete()
}
targetFile.parentFile.delete()
}
targetFile.delete()
}
fun excute() {
CoroutineScope(Dispatchers.IO).launch {
LogUtil.e("onHtml value >> ${value}")
mediaUrls.forEach { url ->
var downPic = false
try {
LogUtil.e("try Jsoup.parse ${url}")
Jsoup.parse(URL(url), defaultTime.times(4).toInt()).let {
try {
LogUtil.e("onit Jsoup.parse ${it.title()}")
if (it.select("svg").size > 0) {
try {
downPic(url, agent, current!!, cookie!!, lDownFinishListener)
reqCount += 1
} catch (e : Exception) {
e.printStackTrace()
}
} else {
it.getElementsByTag("video")?.forEach {
it.attribute("src").value?.let {
var url = if (it.startsWith("http")) {
it
} else {
"https:".plus(it)
}
try {
downMp4(url, agent, current!!, cookie!!, lDownFinishListener)
reqCount += 1
} catch (e : Exception) {
e.printStackTrace()
}
}
}
}
} catch (e: UnsupportedMimeTypeException) {
LogUtil.e("e.message3 ${e.message}")
} catch (e: Exception) {
LogUtil.e("e.message4 ${e.message}")
}
}
} catch (e: UnsupportedMimeTypeException) {
LogUtil.e("e.message ${e.message}")
LogUtil.e("e.message ${e.localizedMessage}")
if (e.message?.contains("Must be text") == true) {
downPic = true
}
} catch (e: Exception) {
if (url.contains("dcimg") == true) {
downPic = true
}
LogUtil.e("e.message2 ${e.message}")
} finally {
if (downPic) {
try {
downPic(url, agent, current!!, cookie!!, lDownFinishListener)
reqCount += 1
} catch (e : Exception) {
e.printStackTrace()
}
}
}
delay(defaultTime)
}
LogUtil.e("END OF LOOP ${reqCount}")
endOfLooPCheck = true
delay(defaultTime.times(4))
if (reqCount <= 0) {
enofLoop()
}
}
}
fun indexSave(htmlString:StringBuffer, targetFile :File, host: String) {
BufferedWriter(FileWriter(targetFile)).use { writer ->
trimHtnl(htmlString.toString(), host)?.let { result ->
writer.write(result.toString())
}
}
}
fun trimHtnl(target : String, host : String) : StringBuffer {
var result = target.replace("\\\"","\"").replace("\\n\\t\\t\\t","").replace("\\n\\t\\t","").replace("\\n\\t","").replace("\\t", "").replace("\\n", "").replace("\"\"\"","").replace("href=\"//","href=\"https://").replace("src=\"//","src=\"https://").replace("url(\"//","url(\"https://").replace("url(&quot;//","url(&quot;https://")
if (host?.contains("clien") == true) {
result = result.replace("href=\"/service","href=\"https://m.clien.net/service").replace("href=\"\\&quot;/service","href=\"\\&quot;https://m.clien.net/service")
}
return StringBuffer(result)
}
fun downMp4(url : String, agent : String, current : String,cookie : String, listner :DownFinishListener) {
LogUtil.e("try imageFile down ${url}")
val path = File(
Environment.getExternalStorageDirectory(),
"bums"
)
DownPicUtil.downMp4(
File(
path,"private_mp4"
).path,
url,
agent,
current,
cookie,
listner
)
}
fun downPic( url : String, agent : String, current : String,cookie : String, listner :DownFinishListener) {
LogUtil.e("try imageFile down ${url}")
val cookieManager =
CookieManager.getInstance()
val cookie =
cookieManager.getCookie(current)
val path = File(
Environment.getExternalStorageDirectory(),
"bums"
)
DownPicUtil.downPic(
File(path, "private_img").path,
url,
agent,
current,
cookie,
listner)
}
}
//package bums.lunatic.launcher.home
//
//import android.content.Context
//import android.content.Intent
//import android.os.Environment
//import android.webkit.CookieManager
//import androidx.core.content.FileProvider
//import kotlinx.coroutines.CoroutineScope
//import kotlinx.coroutines.Dispatchers
//import kotlinx.coroutines.delay
//import kotlinx.coroutines.launch
//import kr.lunaticbum.awesomewebview.helpers.DownPicUtil
//import kr.lunaticbum.awesomewebview.helpers.DownPicUtil.DownFinishListener
//import kr.lunaticbum.utils.log.LogUtil
//import org.jsoup.Jsoup
//import org.jsoup.UnsupportedMimeTypeException
//import java.io.BufferedWriter
//import java.io.File
//import java.io.FileWriter
//import java.net.URL
//import java.text.SimpleDateFormat
//import java.util.Date
//
//val defaultTime = 200L
//class OfflineContents(val context: Context, val host : String, val cookie: String, val agent: String, val current: String, val newPath: String, val value: String, val autoCheck : Boolean, val mediaUrls : ArrayList<String>) {
// val targetFile : File
// val filePath = "index.html"
// val path = File(
// Environment.getExternalStorageDirectory(),
// "bums"
// )
// val newFolder = File(path, newPath).apply { mkdirs() }
// val newFile : File
// var htmlString : StringBuffer
// val urlPathMap : HashMap<String,String> = hashMapOf()
// var reqCount = 0
// var endOfLooPCheck = false
// val lDownFinishListener = object : DownFinishListener {
// override fun onDownFinish(url: String, path: String) {
// LogUtil.e("Url >> ${url} path >> ${path}")
// urlPathMap.put(url, path)
// reqCount -= 1
// if (reqCount == 0 && endOfLooPCheck) {
// enofLoop()
// }
// }
//
// override fun onError() {
// reqCount -= 1
// if (reqCount == 0 && endOfLooPCheck) {
// enofLoop()
// }
// }
// }
//
// init {
// targetFile = File(newFolder, filePath)
// newFile = File(
// path,
// newPath.plus(SimpleDateFormat("yyyMMdd").format(Date())).plus(".html")
// )
// htmlString= trimHtnl(value, host)
// }
//
// var onItEndof = false
// fun enofLoop() {
// if (onItEndof) return
// onItEndof = true
// LogUtil.e("on it enofLoop")
// urlPathMap.forEach { t, u ->
// val file = File(u)
// var contentsUriString = FileProvider.getUriForFile(
// context,
// "${context.packageName}.fileprovider",
// file
// ).toString()
//
// var targetString = t
// var targetIdx = htmlString.indexOf(targetString)
// if (targetIdx > 0) {
// htmlString?.replace(
// targetIdx,
// targetIdx.plus(targetString.length),
// contentsUriString
// )
// }
// targetString = t.replace("&", "&amp;")
// targetIdx = htmlString.indexOf(targetString)
// if (targetIdx > 0) {
// htmlString?.replace(
// targetIdx,
// targetIdx.plus(targetString.length),
// contentsUriString
// )
// }
// }
//
// if (autoCheck) {
// LogUtil.e("on it enofLoop autoCheck ${autoCheck}")
// moveFile()
// context.startActivity(Intent(context,RssViewerActivity::class.java).apply {
// action = Intent.ACTION_VIEW
// data = FileProvider.getUriForFile(
// context,
// "${context.packageName}.fileprovider",
// newFile
// )
// })
// } else {
// moveFile()
// }
// }
//
// fun moveFile() {
// indexSave(htmlString, targetFile, host)
// targetFile.copyTo(newFile)
// if (targetFile.parentFile.isDirectory) {
// targetFile.parentFile.listFiles().forEach {
// it.delete()
// }
// targetFile.parentFile.delete()
// }
// targetFile.delete()
// }
// fun excute() {
// CoroutineScope(Dispatchers.IO).launch {
// LogUtil.e("onHtml value >> ${value}")
// mediaUrls.forEach { url ->
// var downPic = false
// try {
// LogUtil.e("try Jsoup.parse ${url}")
// Jsoup.parse(URL(url), defaultTime.times(4).toInt()).let {
// try {
// LogUtil.e("onit Jsoup.parse ${it.title()}")
// if (it.select("svg").size > 0) {
// try {
// downPic(url, agent, current!!, cookie!!, lDownFinishListener)
// reqCount += 1
// } catch (e : Exception) {
// e.printStackTrace()
// }
// } else {
// it.getElementsByTag("video")?.forEach {
// it.attribute("src").value?.let {
// var url = if (it.startsWith("http")) {
// it
// } else {
// "https:".plus(it)
// }
// try {
// downMp4(url, agent, current!!, cookie!!, lDownFinishListener)
// reqCount += 1
// } catch (e : Exception) {
// e.printStackTrace()
// }
//
// }
// }
// }
// } catch (e: UnsupportedMimeTypeException) {
// LogUtil.e("e.message3 ${e.message}")
// } catch (e: Exception) {
// LogUtil.e("e.message4 ${e.message}")
// }
// }
// } catch (e: UnsupportedMimeTypeException) {
// LogUtil.e("e.message ${e.message}")
// LogUtil.e("e.message ${e.localizedMessage}")
// if (e.message?.contains("Must be text") == true) {
// downPic = true
// }
// } catch (e: Exception) {
// if (url.contains("dcimg") == true) {
// downPic = true
// }
// LogUtil.e("e.message2 ${e.message}")
// } finally {
// if (downPic) {
// try {
// downPic(url, agent, current!!, cookie!!, lDownFinishListener)
// reqCount += 1
// } catch (e : Exception) {
// e.printStackTrace()
// }
//
// }
// }
// delay(defaultTime)
// }
// LogUtil.e("END OF LOOP ${reqCount}")
// endOfLooPCheck = true
// delay(defaultTime.times(4))
// if (reqCount <= 0) {
// enofLoop()
// }
// }
// }
//
// fun indexSave(htmlString:StringBuffer, targetFile :File, host: String) {
// BufferedWriter(FileWriter(targetFile)).use { writer ->
// trimHtnl(htmlString.toString(), host)?.let { result ->
// writer.write(result.toString())
// }
// }
// }
//
// fun trimHtnl(target : String, host : String) : StringBuffer {
// var result = target.replace("\\\"","\"").replace("\\n\\t\\t\\t","").replace("\\n\\t\\t","").replace("\\n\\t","").replace("\\t", "").replace("\\n", "").replace("\"\"\"","").replace("href=\"//","href=\"https://").replace("src=\"//","src=\"https://").replace("url(\"//","url(\"https://").replace("url(&quot;//","url(&quot;https://")
// if (host?.contains("clien") == true) {
// result = result.replace("href=\"/service","href=\"https://m.clien.net/service").replace("href=\"\\&quot;/service","href=\"\\&quot;https://m.clien.net/service")
// }
// return StringBuffer(result)
// }
// fun downMp4(url : String, agent : String, current : String,cookie : String, listner :DownFinishListener) {
// LogUtil.e("try imageFile down ${url}")
// val path = File(
// Environment.getExternalStorageDirectory(),
// "bums"
// )
// DownPicUtil.downMp4(
// File(
// path,"private_mp4"
// ).path,
// url,
// agent,
// current,
// cookie,
// listner
// )
// }
// fun downPic( url : String, agent : String, current : String,cookie : String, listner :DownFinishListener) {
// LogUtil.e("try imageFile down ${url}")
// val cookieManager =
// CookieManager.getInstance()
// val cookie =
// cookieManager.getCookie(current)
// val path = File(
// Environment.getExternalStorageDirectory(),
// "bums"
// )
//
// DownPicUtil.downPic(
// File(path, "private_img").path,
// url,
// agent,
// current,
// cookie,
// listner)
// }
//}

View File

@ -20,7 +20,6 @@ package bums.lunatic.launcher.home
import android.annotation.SuppressLint
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.BitmapFactory
@ -28,30 +27,24 @@ import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.PointerIcon
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.EditText
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.NonNull
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.work.NetworkType
import bums.lunatic.launcher.LauncherActivity
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
import bums.lunatic.launcher.LunaticLauncher
import bums.lunatic.launcher.R
import bums.lunatic.launcher.common.letTrue
import bums.lunatic.launcher.databinding.LauncherHomeBinding
@ -63,7 +56,6 @@ import bums.lunatic.launcher.model.RssData
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.model.WeatherForcast
import bums.lunatic.launcher.openReddit
import bums.lunatic.launcher.openYouTube
import bums.lunatic.launcher.tokiz.view.JxEvent
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.utils.SimpleFingerGestures
@ -72,8 +64,6 @@ import bums.lunatic.launcher.utils.beforeOneDay
import bums.lunatic.launcher.workers.WorkersDb
import bums.lunatic.launcher.workers.WorkersDb.getRealm
import com.google.android.material.imageview.ShapeableImageView
import com.google.gson.Gson
import com.squareup.picasso.NetworkPolicy
import com.squareup.picasso.Picasso
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
@ -422,22 +412,9 @@ internal class RssHome : Fragment() {
fun openGecko(rssData: RssData? = null) {
Blog.LOGE("rssData >>> ${rssData}")
binding.layoutRssSummary.root.visibility = View.GONE
if (rssData?.category()?.equals(RssDataType.PRIVATE) == false && rssData?.originPage?.isNotEmpty() == true) {
rssData?.let { rss ->
currentRss = rss
binding.geckoWeb.privateMode = false
appendReadCount(rss, 1, false)
rss?.originPage?.let { rssId->
synchronized(lasted) {
if (lasted.isNotEmpty()) {
lasted.removeAll { target -> target.originPage.equals(rssId) }
}
}
binding.geckoWeb.loadUrl(rssId)
}
}
} else if (rssData?.category()?.equals(RssDataType.PRIVATE) == true){
rssData?.let {
fun openSummary(rssData : RssData) {
rssData.let {
currentRss = it
synchronized(lasted) {
@ -496,7 +473,7 @@ internal class RssHome : Fragment() {
binding.layoutRssSummary.cover.tag = it
it.thumbnailUrl().let {
Blog.LOGE(it)
loadImage(binding.layoutRssSummary.cover, it, retryCount = 3, isMain = true)
loadImage(binding.layoutRssSummary.cover, it, isMain = true)
}
@ -504,7 +481,7 @@ internal class RssHome : Fragment() {
binding.layoutRssSummary.screen.tag = it
it.getScreen().let {
Blog.LOGE(it)
loadImage(binding.layoutRssSummary.screen, it, retryCount = 2, isMain = false)
loadImage(binding.layoutRssSummary.screen, it, isMain = false)
binding.layoutRssSummary.screenLink.text = it
}
if (it.getMagnet().length < 10) {
@ -514,6 +491,27 @@ internal class RssHome : Fragment() {
}
}
}
if (rssData?.category()?.equals(RssDataType.PRIVATE) == true && rssData?.getMagnet().isNullOrEmpty()) {
openSummary(rssData)
} else if (rssData?.originPage?.isNotEmpty() == true) {
rssData?.let { rss ->
currentRss = rss
binding.geckoWeb.privateMode = false
appendReadCount(rss, 1, false)
rss?.originPage?.let { rssId->
synchronized(lasted) {
if (lasted.isNotEmpty()) {
lasted.removeAll { target -> target.originPage.equals(rssId) }
}
}
binding.geckoWeb.loadUrl(rssId)
}
}
} else {
rssData?.let { openSummary(it) }
}
}
@ -872,8 +870,9 @@ internal class RssHome : Fragment() {
direction: Int
) {
Blog.LOGE("onSwiped direction >>>> $direction")
(viewHolder.itemView.tag as? RssData)?.let { rss ->
(viewHolder.itemView.tag as? RssData)?.let { rssD : RssData ->
CoroutineScope(Dispatchers.IO).launch {
val rss : RssData = rssD
WorkersDb.getRealm().apply {
writeBlocking {
when (direction) {
@ -887,7 +886,7 @@ internal class RssHome : Fragment() {
query<RssData>(
"originPage == $0",
rss.originPage
).find().forEach { it ->
).find().forEach { it : RssData ->
it.read += nomoreShowCount
}
}
@ -952,10 +951,9 @@ internal class RssHome : Fragment() {
}
}
val mainHandler = Handler(Looper.getMainLooper())
fun loadImage(imageView: ImageView, url: String?, retryCount: Int = 2, isMain : Boolean = false) {
fun loadImage(imageView: ImageView, url: String?, retryCount: Int = 4, isMain : Boolean = false) {
with(imageView) {
Picasso.get().cancelRequest(this)
// setOnTouchListener(null)
setOnTouchListener(null)
}
imageView.setImageResource(R.drawable.ic_info)
@ -968,46 +966,35 @@ internal class RssHome : Fragment() {
Blog.LOGE("loadImage >>> $url")
Picasso.get()
.load(url)
.networkPolicy(NetworkPolicy.NO_CACHE)
.into(imageView, object : com.squareup.picasso.Callback {
override fun onSuccess() {
imageView.visibility = View.VISIBLE
imageView.setAlpha(0.05f)
imageView.setOnClickListener(lOnClickListener)
Blog.LOGE("Picasso load into onSuccess URL:$url")
// Picasso.get().cancelRequest(this)
}
override fun onError(e: Exception?) {
e?.printStackTrace()
// Picasso.get().cancelRequest(imageView)
if (retryCount > 0) {
// 메인 스레드에서 재시도
if (binding.layoutRssSummary.root.isVisible) {
mainHandler.postDelayed({
if (binding.layoutRssSummary.root.isVisible && imageView.visibility == View.INVISIBLE) {
if (binding.layoutRssSummary.root.isVisible) {
loadImage(imageView, url, retryCount - 1, isMain)
}
}, 6000L)
}, 3000L)
}
} else {
// // 3회 모두 실패: 대체 이미지 표시
// imageView.setImageResource(R.drawable.ic_info)
// imageView.setAlpha(1f)
if (isMain) {
mainHandler.postDelayed({
binding.layoutRssSummary.root.visibility = View.GONE
currentRss?.originPage?.let {
binding.geckoWeb.loadUrl(
it
)
}
}, 6000L)
}
// Picasso.get().cancelRequest(imageView)
// rett(imageView,url)
}
}
})
imageView.contentDescription = url
} catch (e: Exception) {
Picasso.get().cancelRequest(imageView)
}
} else {
imageView.visibility = View.INVISIBLE
@ -1025,9 +1012,7 @@ internal class RssHome : Fragment() {
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
// 실패 시 기본 이미지 처리 or 로깅
mainHandler.post({
// imageView.setImageResource(R.drawable.error_image)
})
}
override fun onResponse(call: Call, response: Response) {

View File

@ -17,9 +17,6 @@ import android.widget.Button
import android.widget.CheckBox
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.Toast
import androidx.core.view.forEach
import bums.lunatic.launcher.R
import bums.lunatic.launcher.model.RssDataType

View File

@ -14,15 +14,10 @@ import android.view.ViewGroup
import android.view.WindowManager
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.Button
import android.widget.CheckBox
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.Toast
import androidx.core.view.children
import androidx.core.view.forEach
import bums.lunatic.launcher.R
import bums.lunatic.launcher.model.RssDataType
import com.google.android.material.bottomsheet.BottomSheetDialogFragment

View File

@ -29,28 +29,18 @@ import androidx.core.net.toUri
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
import bums.lunatic.launcher.R
import bums.lunatic.launcher.databinding.ListItemWithBinding
import bums.lunatic.launcher.home.RssViewBuilder
import bums.lunatic.launcher.model.RssData
import bums.lunatic.launcher.model.RssDataInterface
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.openClient
import bums.lunatic.launcher.openReddit
import bums.lunatic.launcher.openYouTube
import bums.lunatic.launcher.tokiz.view.JxEvent
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.utils.SimpleFingerGestures
import bums.lunatic.launcher.workers.WorkersDb
import com.google.android.material.imageview.ShapeableImageView
import com.squareup.picasso.NetworkPolicy
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.squareup.picasso.Callback
import com.squareup.picasso.Picasso
import io.realm.kotlin.UpdatePolicy
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kr.lunaticbum.awesomewebview.listeners.WebViewListener
import java.text.SimpleDateFormat
import java.util.Date
@ -62,15 +52,8 @@ internal class RssItemAdapter (
@SuppressLint("SimpleDateFormat")
val dateFormat = SimpleDateFormat("a HH:mm / yy - MM - dd")
val emptyDate = " - "
// var rssList: ArrayList<String> = ArrayList()
val webViewListener = object : WebViewListener() {
override fun onCustomMenuClick(menuCode: String?) {
super.onCustomMenuClick(menuCode)
if ("PDF".equals(menuCode)) {
// var rssList: ArrayList<String> = ArrayList()
}
}
}
private var rssDataItemLis: ArrayList<RssData> = arrayListOf()
val mLongClickListener = View.OnLongClickListener { v ->
@ -214,16 +197,27 @@ internal class RssItemAdapter (
holder.view.circlePreview.setImageResource(rssData.category().getResId())
}
if(rssData.category().equals(RssDataType.PRIVATE) == false) {
if (rssData.thumbnailUrl()?.length ?: 0 > 6) {
Blog.LOGE("rssData.thumbnailUrl() >>> ${rssData.thumbnailUrl()}")
Picasso.get().load(rssData.thumbnailUrl().replace("&amp;", "&").toUri()).networkPolicy(
NetworkPolicy.NO_CACHE)
.into(holder.view.circlePreview)
}
if (rssData.thumbnailUrl()?.length ?: 0 > 6) {
Blog.LOGE("rssData.thumbnailUrl() >>> ${rssData.thumbnailUrl()}")
val requestOptions = RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.timeout(3000) // 3초
Picasso.get().load(rssData.thumbnailUrl().replace("&amp;", "&").toUri())
.error(rssData.category().getResId())
.into(holder.view.circlePreview,object : Callback {
override fun onSuccess() {
// 캐시에서 이미지 성공적으로 로드됨
}
override fun onError(e: Exception?) {
Glide.with(holder.view.circlePreview).load(rssData.thumbnailUrl().replace("&amp;", "&")).apply(requestOptions).error(rssData.category().getResId()).into(holder.view.circlePreview)
}
})
}
holder.itemView.tag = rssData
holder.itemView.setOnClickListener(dateViewClick)
holder.itemView.setOnTouchListener(object : View.OnTouchListener {

View File

@ -1,52 +1,52 @@
/*
* Lunar Launcher
* Copyright (C) 2022 Md Rasel Hossain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package bums.lunatic.launcher.home.weather
import org.json.JSONException
import org.json.JSONObject
internal class JsonParser {
fun getMyWeather(jsonStr: String): Weather {
val weather = Weather()
try {
val jsonObject = JSONObject(jsonStr)
/* Get weather condition */
val weatherArray = jsonObject.getJSONArray("weather")
val weatherObject = weatherArray.getJSONObject(0)
weather.weatherCondition = weatherObject.getString("main")
weather.weatherDescription = weatherObject.getString("description")
weather.weatherIconId = weatherObject.getString("icon")
/* Get temperature */
val mainObject = jsonObject.getJSONObject("main")
weather.temperature = mainObject.getDouble("temp").toFloat()
weather.cityName = jsonObject.getString("name")
} catch (jsonException: JSONException) {
jsonException.printStackTrace()
}
return weather
}
}
///*
// * Lunar Launcher
// * Copyright (C) 2022 Md Rasel Hossain
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
// */
//
//package bums.lunatic.launcher.home.weather
//
//import org.json.JSONException
//import org.json.JSONObject
//
//
//internal class JsonParser {
//
// fun getMyWeather(jsonStr: String): Weather {
// val weather = Weather()
//
// try {
// val jsonObject = JSONObject(jsonStr)
//
// /* Get weather condition */
// val weatherArray = jsonObject.getJSONArray("weather")
// val weatherObject = weatherArray.getJSONObject(0)
// weather.weatherCondition = weatherObject.getString("main")
// weather.weatherDescription = weatherObject.getString("description")
// weather.weatherIconId = weatherObject.getString("icon")
//
// /* Get temperature */
// val mainObject = jsonObject.getJSONObject("main")
// weather.temperature = mainObject.getDouble("temp").toFloat()
//
// weather.cityName = jsonObject.getString("name")
// } catch (jsonException: JSONException) {
// jsonException.printStackTrace()
// }
//
// return weather
// }
//
//}

View File

@ -1,28 +1,28 @@
/*
* Lunar Launcher
* Copyright (C) 2022 Md Rasel Hossain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package bums.lunatic.launcher.home.weather
internal class Weather {
var weatherCondition: String? = null
var weatherDescription: String? = null
var weatherIconId: String? = null
var temperature = 0f
var cityName: String? = null
}
///*
// * Lunar Launcher
// * Copyright (C) 2022 Md Rasel Hossain
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
// */
//
//package bums.lunatic.launcher.home.weather
//
//
//internal class Weather {
// var weatherCondition: String? = null
// var weatherDescription: String? = null
// var weatherIconId: String? = null
// var temperature = 0f
// var cityName: String? = null
//}

View File

@ -1,61 +1,61 @@
/*
* Lunar Launcher
* Copyright (C) 2022 Md Rasel Hossain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package bums.lunatic.launcher.home.weather
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
internal class WeatherClient {
fun fetchWeather(wUrl: String?): String? {
var httpURLConnection: HttpURLConnection? = null
var bufferedReader: BufferedReader? = null
try {
httpURLConnection = URL(wUrl).openConnection() as HttpURLConnection
httpURLConnection.connect()
bufferedReader = BufferedReader(InputStreamReader(httpURLConnection.inputStream))
val stringBuilder = StringBuilder()
var line: String?
while (bufferedReader.readLine().also { line = it } != null) {
stringBuilder.append("$line\n")
}
if (stringBuilder.isNotEmpty()) return stringBuilder.toString()
} catch (exception: Exception) {
exception.printStackTrace()
} finally {
httpURLConnection?.disconnect()
if (bufferedReader != null) {
try {
bufferedReader.close()
} catch (exception: Exception) {
exception.printStackTrace()
}
}
}
return null
}
}
///*
// * Lunar Launcher
// * Copyright (C) 2022 Md Rasel Hossain
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
// */
//
//package bums.lunatic.launcher.home.weather
//
//import java.io.BufferedReader
//import java.io.InputStreamReader
//import java.net.HttpURLConnection
//import java.net.URL
//
//
//internal class WeatherClient {
//
// fun fetchWeather(wUrl: String?): String? {
// var httpURLConnection: HttpURLConnection? = null
// var bufferedReader: BufferedReader? = null
//
// try {
// httpURLConnection = URL(wUrl).openConnection() as HttpURLConnection
// httpURLConnection.connect()
// bufferedReader = BufferedReader(InputStreamReader(httpURLConnection.inputStream))
//
// val stringBuilder = StringBuilder()
// var line: String?
// while (bufferedReader.readLine().also { line = it } != null) {
// stringBuilder.append("$line\n")
// }
//
// if (stringBuilder.isNotEmpty()) return stringBuilder.toString()
// } catch (exception: Exception) {
// exception.printStackTrace()
// } finally {
// httpURLConnection?.disconnect()
// if (bufferedReader != null) {
// try {
// bufferedReader.close()
// } catch (exception: Exception) {
// exception.printStackTrace()
// }
// }
// }
//
// return null
// }
//
//}

View File

@ -1,97 +1,97 @@
/*
* Lunar Launcher
* Copyright (C) 2022 Md Rasel Hossain
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package bums.lunatic.launcher.home.weather
import android.annotation.SuppressLint
import android.content.SharedPreferences
import android.os.Handler
import android.os.Looper
import android.view.View
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_CITY_NAME
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_OWM_API
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_SHOW_CITY
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_TEMP_UNIT
import bums.lunatic.launcher.helpers.UniUtils.Companion.isNetworkAvailable
import com.google.android.material.textview.MaterialTextView
import java.util.concurrent.Executors
internal class WeatherExecutor(sharedPreferences: SharedPreferences) {
companion object {
var lastedCheckTime = 0L
var weather: Weather? = null
}
private val cityName: String
private val owmApi: String
private val weatherUrl: String
private val tempUnit: Int
private val showCity: Boolean
@SuppressLint("SetTextI18n")
fun generateWeatherString(materialTextView: MaterialTextView) {
materialTextView.visibility = View.GONE
/* run the executor if network is available,
and city name and owm api values are not empty */
if (System.currentTimeMillis() - lastedCheckTime > (1000 * 60 * 15) && isNetworkAvailable && cityName.isNotEmpty() && owmApi.isNotEmpty()) {
try {
Executors.newSingleThreadExecutor().execute {
WeatherClient().fetchWeather(weatherUrl).let {
if (!it.isNullOrEmpty()) weather = JsonParser().getMyWeather(it)
}
Handler(Looper.getMainLooper()).post {
if (weather != null) {
materialTextView.apply {
visibility = View.VISIBLE
text = weather!!.temperature.toString().substringBefore(".") +
(if (tempUnit == 0) "ºC" else "ºF") +
(if (showCity) " at ${weather!!.cityName}" else "")
}
}
}
}
} catch (exception: Exception) {
exception.printStackTrace()
}
} else {
Handler(Looper.getMainLooper()).post {
if (weather != null) {
materialTextView.apply {
visibility = View.VISIBLE
text = weather!!.temperature.toString().substringBefore(".") +
(if (tempUnit == 0) "ºC" else "ºF") +
(if (showCity) " at ${weather!!.cityName}" else "")
}
}
}
}
lastedCheckTime = System.currentTimeMillis()
}
init {
cityName = sharedPreferences.getString(KEY_CITY_NAME, "").toString()
owmApi = sharedPreferences.getString(KEY_OWM_API, "").toString()
tempUnit = sharedPreferences.getInt(KEY_TEMP_UNIT, 0)
showCity = sharedPreferences.getBoolean(KEY_SHOW_CITY, false)
weatherUrl = "https://api.openweathermap.org/data/2.5/weather?q=$cityName&APPID=$owmApi&units=" + if (tempUnit == 0) "metric" else "imperial"
}
}
///*
// * Lunar Launcher
// * Copyright (C) 2022 Md Rasel Hossain
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
// */
//
//package bums.lunatic.launcher.home.weather
//
//import android.annotation.SuppressLint
//import android.content.SharedPreferences
//import android.os.Handler
//import android.os.Looper
//import android.view.View
//import bums.lunatic.launcher.helpers.Constants.Companion.KEY_CITY_NAME
//import bums.lunatic.launcher.helpers.Constants.Companion.KEY_OWM_API
//import bums.lunatic.launcher.helpers.Constants.Companion.KEY_SHOW_CITY
//import bums.lunatic.launcher.helpers.Constants.Companion.KEY_TEMP_UNIT
//import bums.lunatic.launcher.helpers.UniUtils.Companion.isNetworkAvailable
//import com.google.android.material.textview.MaterialTextView
//import java.util.concurrent.Executors
//
//
//internal class WeatherExecutor(sharedPreferences: SharedPreferences) {
//
// companion object {
// var lastedCheckTime = 0L
// var weather: Weather? = null
// }
//
// private val cityName: String
// private val owmApi: String
// private val weatherUrl: String
// private val tempUnit: Int
// private val showCity: Boolean
//
// @SuppressLint("SetTextI18n")
// fun generateWeatherString(materialTextView: MaterialTextView) {
// materialTextView.visibility = View.GONE
// /* run the executor if network is available,
// and city name and owm api values are not empty */
// if (System.currentTimeMillis() - lastedCheckTime > (1000 * 60 * 15) && isNetworkAvailable && cityName.isNotEmpty() && owmApi.isNotEmpty()) {
// try {
// Executors.newSingleThreadExecutor().execute {
// WeatherClient().fetchWeather(weatherUrl).let {
// if (!it.isNullOrEmpty()) weather = JsonParser().getMyWeather(it)
// }
//
// Handler(Looper.getMainLooper()).post {
// if (weather != null) {
// materialTextView.apply {
// visibility = View.VISIBLE
// text = weather!!.temperature.toString().substringBefore(".") +
// (if (tempUnit == 0) "ºC" else "ºF") +
// (if (showCity) " at ${weather!!.cityName}" else "")
// }
// }
// }
// }
// } catch (exception: Exception) {
// exception.printStackTrace()
// }
// } else {
// Handler(Looper.getMainLooper()).post {
// if (weather != null) {
// materialTextView.apply {
// visibility = View.VISIBLE
// text = weather!!.temperature.toString().substringBefore(".") +
// (if (tempUnit == 0) "ºC" else "ºF") +
// (if (showCity) " at ${weather!!.cityName}" else "")
// }
// }
// }
// }
// lastedCheckTime = System.currentTimeMillis()
// }
//
// init {
// cityName = sharedPreferences.getString(KEY_CITY_NAME, "").toString()
// owmApi = sharedPreferences.getString(KEY_OWM_API, "").toString()
// tempUnit = sharedPreferences.getInt(KEY_TEMP_UNIT, 0)
// showCity = sharedPreferences.getBoolean(KEY_SHOW_CITY, false)
// weatherUrl = "https://api.openweathermap.org/data/2.5/weather?q=$cityName&APPID=$owmApi&units=" + if (tempUnit == 0) "metric" else "imperial"
// }
//
//}

View File

@ -1,6 +1,5 @@
package bums.lunatic.launcher.model
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.utils.JamoUtils
import bums.lunatic.launcher.utils.afterDay
import bums.lunatic.launcher.utils.beforeDayBy

View File

@ -2,7 +2,6 @@ package bums.lunatic.launcher.model
import android.view.View
import bums.lunatic.launcher.R
import bums.lunatic.launcher.helpers.PrefHelper
enum class RssDataType {
NO_DATA,

View File

@ -4,55 +4,26 @@ import android.Manifest
import android.annotation.SuppressLint
import android.app.Notification
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.location.Geocoder
import android.location.Location
import android.media.MediaMetadata
import android.media.session.MediaSessionManager
import android.media.session.PlaybackState.STATE_PLAYING
import android.os.Build
import android.service.notification.NotificationListenerService
import android.service.notification.StatusBarNotification
import androidx.annotation.RequiresApi
import androidx.annotation.RequiresPermission
import androidx.core.content.getSystemService
import bums.lunatic.launcher.LunaticLauncher.Companion.mHourlyLogWriter
import bums.lunatic.launcher.common.letTrue
import bums.lunatic.launcher.helpers.ForeGroundService
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.ACTION_SENDMSG
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.EXTRA_MSGKEY
import bums.lunatic.launcher.helpers.PrefBoolean
import bums.lunatic.launcher.helpers.PrefString
import bums.lunatic.launcher.model.CurrentPlayItem
import bums.lunatic.launcher.model.LocationLog
import bums.lunatic.launcher.model.NotificationItem
import bums.lunatic.launcher.utils.BitmapConverter
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.utils.KakaoPublicTransfer
import bums.lunatic.launcher.workers.LocationUpdateService.Companion.inRangeLocation
import bums.lunatic.launcher.workers.WorkersDb
import com.google.android.gms.location.LocationServices
import com.google.gson.Gson
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
import io.realm.kotlin.query.Sort
import okhttp3.ConnectionPool
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
import okhttp3.ResponseBody
import java.io.File
import java.io.IOException
import java.lang.Exception
import java.util.Base64
import java.util.Locale
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
class NLService : NotificationListenerService() {

View File

@ -34,13 +34,9 @@ import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
import bums.lunatic.launcher.helpers.PrefBoolean
import bums.lunatic.launcher.helpers.PrefHelper
import bums.lunatic.launcher.model.AppInfo
import bums.lunatic.launcher.settings.childs.Advance
import bums.lunatic.launcher.settings.childs.Appearances
import bums.lunatic.launcher.settings.childs.Apps
import bums.lunatic.launcher.settings.childs.HomeSettings
import bums.lunatic.launcher.settings.childs.Misc
import bums.lunatic.launcher.settings.childs.TopInfos
import bums.lunatic.launcher.settings.childs.WeatherSettings
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.workers.WorkersDb
import com.google.android.material.bottomsheet.BottomSheetDialog

View File

@ -27,7 +27,6 @@ import android.view.View
import android.view.ViewGroup
import bums.lunatic.launcher.R
import bums.lunatic.launcher.databinding.SettingsAppsBinding
import bums.lunatic.launcher.helpers.PrefBoolean
import bums.lunatic.launcher.helpers.PrefLong
import bums.lunatic.launcher.utils.Blog
import com.google.android.material.bottomsheet.BottomSheetBehavior

View File

@ -24,14 +24,9 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.doOnTextChanged
import bums.lunatic.launcher.R
import bums.lunatic.launcher.databinding.SettingsWeatherBinding
import bums.lunatic.launcher.helpers.PrefBoolean
import bums.lunatic.launcher.helpers.PrefString
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlin.system.exitProcess
internal class WeatherSettings : SettingChild() {

View File

@ -1,9 +1,7 @@
package bums.lunatic.launcher.tokiz
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Bitmap
import android.net.Uri
@ -38,28 +36,27 @@ import androidx.fragment.app.Fragment
import bums.lunatic.launcher.LauncherActivity
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
import bums.lunatic.launcher.R
import bums.lunatic.launcher.databinding.BooktokiBinding
import bums.lunatic.launcher.home.toast
import bums.lunatic.launcher.tokiz.common.PairArray
import bums.lunatic.launcher.tokiz.common.TouchArea
import bums.lunatic.launcher.tokiz.common.colorz
import bums.lunatic.launcher.tokiz.common.getIndex
import bums.lunatic.launcher.tokiz.common.typesfacez
import bums.lunatic.launcher.tokiz.data.HistoryManager
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
import bums.lunatic.launcher.tokiz.data.model.PageInfosJ
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.FakeSessions
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
import bums.lunatic.launcher.tokiz.data.model.LastInfo
import bums.lunatic.launcher.tokiz.data.model.PageInfosJ
import bums.lunatic.launcher.tokiz.data.model.PortMessage
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
import bums.lunatic.launcher.tokiz.dialog.DefaultList
import bums.lunatic.launcher.tokiz.view.BWebview
import bums.lunatic.launcher.tokiz.view.JxEvent
import bums.lunatic.launcher.tokiz.view.PagedTextLayout
import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface
import bums.lunatic.launcher.databinding.BooktokiBinding
import bums.lunatic.launcher.home.toast
import bums.lunatic.launcher.tokiz.data.model.FakeSession
import bums.lunatic.launcher.tokiz.data.model.FakeSessions
import bums.lunatic.launcher.tokiz.view.BWebview
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.workers.WorkersDb
import com.google.gson.Gson
@ -83,25 +80,7 @@ import java.lang.System.currentTimeMillis
import java.net.URL
import java.text.SimpleDateFormat
import java.util.Date
import java.util.UUID
import kotlin.collections.ArrayList
import kotlin.collections.List
import kotlin.collections.MutableList
import kotlin.collections.arrayListOf
import kotlin.collections.first
import kotlin.collections.isNotEmpty
import kotlin.collections.last
import kotlin.collections.sortBy
import kotlin.random.Random
import kotlin.text.contains
import kotlin.text.endsWith
import kotlin.text.equals
import kotlin.text.replace
import kotlin.text.split
import kotlin.text.startsWith
import kotlin.text.toInt
import kotlin.text.toRegex
import kotlin.text.trim
abstract class BaseToki : Fragment(), PagedTextViewInterface {

View File

@ -1,97 +1,14 @@
package bums.lunatic.launcher.tokiz
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.InputType
import android.text.SpannableStringBuilder
import android.text.style.RelativeSizeSpan
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.View.GONE
import android.view.View.OnTouchListener
import android.view.View.VISIBLE
import android.view.View.inflate
import android.view.ViewGroup
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
import bums.lunatic.launcher.R
import bums.lunatic.launcher.tokiz.common.PairArray
import bums.lunatic.launcher.tokiz.common.TouchArea
import bums.lunatic.launcher.tokiz.common.colorz
import bums.lunatic.launcher.tokiz.common.getIndex
import bums.lunatic.launcher.tokiz.common.typesfacez
import bums.lunatic.launcher.tokiz.data.HistoryManager
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
import bums.lunatic.launcher.tokiz.data.model.PageInfosJ
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
import bums.lunatic.launcher.tokiz.data.model.LastInfo
import bums.lunatic.launcher.tokiz.data.model.PortMessage
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
import bums.lunatic.launcher.tokiz.dialog.DefaultList
import bums.lunatic.launcher.tokiz.view.JxEvent
import bums.lunatic.launcher.tokiz.view.PagedTextLayout
import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface
import bums.lunatic.launcher.databinding.BooktokiBinding
import bums.lunatic.launcher.utils.Blog
import com.google.gson.Gson
import io.realm.kotlin.Realm
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.copyFromRealm
import io.realm.kotlin.ext.query
import org.json.JSONException
import org.json.JSONObject
import org.mozilla.gecko.util.ThreadUtils
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.MediaSession
import org.mozilla.geckoview.WebExtension
import org.mozilla.geckoview.WebExtension.MessageDelegate
import org.mozilla.geckoview.WebExtension.PortDelegate
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
import org.mozilla.geckoview.WebRequestError
import java.lang.System.currentTimeMillis
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.collections.ArrayList
import kotlin.collections.List
import kotlin.collections.MutableList
import kotlin.collections.arrayListOf
import kotlin.collections.first
import kotlin.collections.isNotEmpty
import kotlin.collections.last
import kotlin.collections.sortBy
import kotlin.random.Random
import kotlin.text.contains
import kotlin.text.endsWith
import kotlin.text.equals
import kotlin.text.replace
import kotlin.text.split
import kotlin.text.startsWith
import kotlin.text.toInt
import kotlin.text.toRegex
import kotlin.text.trim
class Comics : BaseToki(), PagedTextViewInterface {

View File

@ -1,97 +1,14 @@
package bums.lunatic.launcher.tokiz
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.InputType
import android.text.SpannableStringBuilder
import android.text.style.RelativeSizeSpan
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.View.GONE
import android.view.View.OnTouchListener
import android.view.View.VISIBLE
import android.view.View.inflate
import android.view.ViewGroup
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
import bums.lunatic.launcher.R
import bums.lunatic.launcher.tokiz.common.PairArray
import bums.lunatic.launcher.tokiz.common.TouchArea
import bums.lunatic.launcher.tokiz.common.colorz
import bums.lunatic.launcher.tokiz.common.getIndex
import bums.lunatic.launcher.tokiz.common.typesfacez
import bums.lunatic.launcher.tokiz.data.HistoryManager
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
import bums.lunatic.launcher.tokiz.data.model.PageInfosJ
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
import bums.lunatic.launcher.tokiz.data.model.LastInfo
import bums.lunatic.launcher.tokiz.data.model.PortMessage
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
import bums.lunatic.launcher.tokiz.dialog.DefaultList
import bums.lunatic.launcher.tokiz.view.JxEvent
import bums.lunatic.launcher.tokiz.view.PagedTextLayout
import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface
import bums.lunatic.launcher.databinding.BooktokiBinding
import bums.lunatic.launcher.utils.Blog
import com.google.gson.Gson
import io.realm.kotlin.Realm
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.copyFromRealm
import io.realm.kotlin.ext.query
import org.json.JSONException
import org.json.JSONObject
import org.mozilla.gecko.util.ThreadUtils
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.MediaSession
import org.mozilla.geckoview.WebExtension
import org.mozilla.geckoview.WebExtension.MessageDelegate
import org.mozilla.geckoview.WebExtension.PortDelegate
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
import org.mozilla.geckoview.WebRequestError
import java.lang.System.currentTimeMillis
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.collections.ArrayList
import kotlin.collections.List
import kotlin.collections.MutableList
import kotlin.collections.arrayListOf
import kotlin.collections.first
import kotlin.collections.isNotEmpty
import kotlin.collections.last
import kotlin.collections.sortBy
import kotlin.random.Random
import kotlin.text.contains
import kotlin.text.endsWith
import kotlin.text.equals
import kotlin.text.replace
import kotlin.text.split
import kotlin.text.startsWith
import kotlin.text.toInt
import kotlin.text.toRegex
import kotlin.text.trim
class Magnet : BaseToki(), PagedTextViewInterface {

View File

@ -1,95 +1,14 @@
package bums.lunatic.launcher.tokiz
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.InputType
import android.text.SpannableStringBuilder
import android.text.style.RelativeSizeSpan
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.View.GONE
import android.view.View.OnTouchListener
import android.view.View.VISIBLE
import android.view.View.inflate
import android.view.ViewGroup
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
import bums.lunatic.launcher.R
import bums.lunatic.launcher.tokiz.common.PairArray
import bums.lunatic.launcher.tokiz.common.TouchArea
import bums.lunatic.launcher.tokiz.common.colorz
import bums.lunatic.launcher.tokiz.common.getIndex
import bums.lunatic.launcher.tokiz.common.typesfacez
import bums.lunatic.launcher.tokiz.data.HistoryManager
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
import bums.lunatic.launcher.tokiz.data.model.PageInfosJ
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
import bums.lunatic.launcher.tokiz.data.model.LastInfo
import bums.lunatic.launcher.tokiz.data.model.PortMessage
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
import bums.lunatic.launcher.tokiz.dialog.DefaultList
import bums.lunatic.launcher.tokiz.view.JxEvent
import bums.lunatic.launcher.tokiz.view.PagedTextLayout
import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface
import bums.lunatic.launcher.databinding.BooktokiBinding
import bums.lunatic.launcher.utils.Blog
import com.google.gson.Gson
import io.realm.kotlin.Realm
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.copyFromRealm
import io.realm.kotlin.ext.query
import org.json.JSONException
import org.json.JSONObject
import org.mozilla.gecko.util.ThreadUtils
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.MediaSession
import org.mozilla.geckoview.WebExtension
import org.mozilla.geckoview.WebExtension.MessageDelegate
import org.mozilla.geckoview.WebExtension.PortDelegate
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
import org.mozilla.geckoview.WebRequestError
import java.lang.System.currentTimeMillis
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.collections.ArrayList
import kotlin.collections.List
import kotlin.collections.MutableList
import kotlin.collections.arrayListOf
import kotlin.collections.first
import kotlin.collections.isNotEmpty
import kotlin.collections.last
import kotlin.collections.sortBy
import kotlin.random.Random
import kotlin.text.contains
import kotlin.text.endsWith
import kotlin.text.equals
import kotlin.text.replace
import kotlin.text.split
import kotlin.text.startsWith
import kotlin.text.toInt
import kotlin.text.toRegex
import kotlin.text.trim
class Novels : BaseToki(), PagedTextViewInterface {

View File

@ -1,97 +1,14 @@
package bums.lunatic.launcher.tokiz
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.InputType
import android.text.SpannableStringBuilder
import android.text.style.RelativeSizeSpan
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.View.GONE
import android.view.View.OnTouchListener
import android.view.View.VISIBLE
import android.view.View.inflate
import android.view.ViewGroup
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
import bums.lunatic.launcher.R
import bums.lunatic.launcher.tokiz.common.PairArray
import bums.lunatic.launcher.tokiz.common.TouchArea
import bums.lunatic.launcher.tokiz.common.colorz
import bums.lunatic.launcher.tokiz.common.getIndex
import bums.lunatic.launcher.tokiz.common.typesfacez
import bums.lunatic.launcher.tokiz.data.HistoryManager
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
import bums.lunatic.launcher.tokiz.data.model.PageInfosJ
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
import bums.lunatic.launcher.tokiz.data.model.LastInfo
import bums.lunatic.launcher.tokiz.data.model.PortMessage
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
import bums.lunatic.launcher.tokiz.dialog.DefaultList
import bums.lunatic.launcher.tokiz.view.JxEvent
import bums.lunatic.launcher.tokiz.view.PagedTextLayout
import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface
import bums.lunatic.launcher.databinding.BooktokiBinding
import bums.lunatic.launcher.utils.Blog
import com.google.gson.Gson
import io.realm.kotlin.Realm
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.copyFromRealm
import io.realm.kotlin.ext.query
import org.json.JSONException
import org.json.JSONObject
import org.mozilla.gecko.util.ThreadUtils
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.MediaSession
import org.mozilla.geckoview.WebExtension
import org.mozilla.geckoview.WebExtension.MessageDelegate
import org.mozilla.geckoview.WebExtension.PortDelegate
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
import org.mozilla.geckoview.WebRequestError
import java.lang.System.currentTimeMillis
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.collections.ArrayList
import kotlin.collections.List
import kotlin.collections.MutableList
import kotlin.collections.arrayListOf
import kotlin.collections.first
import kotlin.collections.isNotEmpty
import kotlin.collections.last
import kotlin.collections.sortBy
import kotlin.random.Random
import kotlin.text.contains
import kotlin.text.endsWith
import kotlin.text.equals
import kotlin.text.replace
import kotlin.text.split
import kotlin.text.startsWith
import kotlin.text.toInt
import kotlin.text.toRegex
import kotlin.text.trim
class Perplexity : BaseToki(), PagedTextViewInterface {

View File

@ -6,21 +6,16 @@ import android.os.Bundle
import androidx.annotation.RequiresApi
import androidx.databinding.DataBindingUtil
import bums.lunatic.launcher.R
import bums.lunatic.launcher.common.CommonActivity
import bums.lunatic.launcher.databinding.SettingsBinding
import bums.lunatic.launcher.tokiz.common.PairArray
import bums.lunatic.launcher.tokiz.common.colorz
import bums.lunatic.launcher.tokiz.common.getIndex
import bums.lunatic.launcher.tokiz.common.typesfacez
import bums.lunatic.launcher.tokiz.data.HistoryManager
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
import bums.lunatic.launcher.common.CommonActivity
import bums.lunatic.launcher.databinding.SettingsBinding
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.query
import kotlin.collections.first
import kotlin.collections.last
import kotlin.collections.map
import kotlin.collections.toTypedArray
import kotlin.let
class Settings : CommonActivity() {

View File

@ -1,97 +1,14 @@
package bums.lunatic.launcher.tokiz
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.InputType
import android.text.SpannableStringBuilder
import android.text.style.RelativeSizeSpan
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.View.GONE
import android.view.View.OnTouchListener
import android.view.View.VISIBLE
import android.view.View.inflate
import android.view.ViewGroup
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
import bums.lunatic.launcher.R
import bums.lunatic.launcher.tokiz.common.PairArray
import bums.lunatic.launcher.tokiz.common.TouchArea
import bums.lunatic.launcher.tokiz.common.colorz
import bums.lunatic.launcher.tokiz.common.getIndex
import bums.lunatic.launcher.tokiz.common.typesfacez
import bums.lunatic.launcher.tokiz.data.HistoryManager
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
import bums.lunatic.launcher.tokiz.data.model.PageInfosJ
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
import bums.lunatic.launcher.tokiz.data.model.LastInfo
import bums.lunatic.launcher.tokiz.data.model.PortMessage
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
import bums.lunatic.launcher.tokiz.dialog.DefaultList
import bums.lunatic.launcher.tokiz.view.JxEvent
import bums.lunatic.launcher.tokiz.view.PagedTextLayout
import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface
import bums.lunatic.launcher.databinding.BooktokiBinding
import bums.lunatic.launcher.utils.Blog
import com.google.gson.Gson
import io.realm.kotlin.Realm
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.copyFromRealm
import io.realm.kotlin.ext.query
import org.json.JSONException
import org.json.JSONObject
import org.mozilla.gecko.util.ThreadUtils
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.MediaSession
import org.mozilla.geckoview.WebExtension
import org.mozilla.geckoview.WebExtension.MessageDelegate
import org.mozilla.geckoview.WebExtension.PortDelegate
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
import org.mozilla.geckoview.WebRequestError
import java.lang.System.currentTimeMillis
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.collections.ArrayList
import kotlin.collections.List
import kotlin.collections.MutableList
import kotlin.collections.arrayListOf
import kotlin.collections.first
import kotlin.collections.isNotEmpty
import kotlin.collections.last
import kotlin.collections.sortBy
import kotlin.random.Random
import kotlin.text.contains
import kotlin.text.endsWith
import kotlin.text.equals
import kotlin.text.replace
import kotlin.text.split
import kotlin.text.startsWith
import kotlin.text.toInt
import kotlin.text.toRegex
import kotlin.text.trim
class Twitter : BaseToki(), PagedTextViewInterface {

View File

@ -1,96 +1,14 @@
package bums.lunatic.launcher.tokiz
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.InputType
import android.text.SpannableStringBuilder
import android.text.style.RelativeSizeSpan
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.View.GONE
import android.view.View.OnTouchListener
import android.view.View.VISIBLE
import android.view.View.inflate
import android.view.ViewGroup
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
import bums.lunatic.launcher.R
import bums.lunatic.launcher.tokiz.common.PairArray
import bums.lunatic.launcher.tokiz.common.TouchArea
import bums.lunatic.launcher.tokiz.common.colorz
import bums.lunatic.launcher.tokiz.common.getIndex
import bums.lunatic.launcher.tokiz.common.typesfacez
import bums.lunatic.launcher.tokiz.data.HistoryManager
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
import bums.lunatic.launcher.tokiz.data.model.PageInfosJ
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
import bums.lunatic.launcher.tokiz.data.model.LastInfo
import bums.lunatic.launcher.tokiz.data.model.PortMessage
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
import bums.lunatic.launcher.tokiz.dialog.DefaultList
import bums.lunatic.launcher.tokiz.view.JxEvent
import bums.lunatic.launcher.tokiz.view.PagedTextLayout
import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface
import bums.lunatic.launcher.databinding.BooktokiBinding
import bums.lunatic.launcher.utils.Blog
import com.google.gson.Gson
import io.realm.kotlin.Realm
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.copyFromRealm
import io.realm.kotlin.ext.query
import org.json.JSONException
import org.json.JSONObject
import org.mozilla.gecko.util.ThreadUtils
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.MediaSession
import org.mozilla.geckoview.WebExtension
import org.mozilla.geckoview.WebExtension.MessageDelegate
import org.mozilla.geckoview.WebExtension.PortDelegate
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
import org.mozilla.geckoview.WebRequestError
import java.lang.System.currentTimeMillis
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.collections.ArrayList
import kotlin.collections.List
import kotlin.collections.MutableList
import kotlin.collections.arrayListOf
import kotlin.collections.first
import kotlin.collections.isNotEmpty
import kotlin.collections.last
import kotlin.collections.sortBy
import kotlin.random.Random
import kotlin.text.contains
import kotlin.text.endsWith
import kotlin.text.equals
import kotlin.text.replace
import kotlin.text.split
import kotlin.text.startsWith
import kotlin.text.toInt
import kotlin.text.toRegex
import kotlin.text.trim
class Webtoons : BaseToki(), PagedTextViewInterface {

View File

@ -5,7 +5,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import bums.lunatic.launcher.tokiz.common.TouchArea
import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface
class YouTube : BaseToki(){
override val contentsType = "youtube"

View File

@ -1,97 +1,14 @@
package bums.lunatic.launcher.tokiz
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.InputType
import android.text.SpannableStringBuilder
import android.text.style.RelativeSizeSpan
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.View.GONE
import android.view.View.OnTouchListener
import android.view.View.VISIBLE
import android.view.View.inflate
import android.view.ViewGroup
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
import bums.lunatic.launcher.R
import bums.lunatic.launcher.tokiz.common.PairArray
import bums.lunatic.launcher.tokiz.common.TouchArea
import bums.lunatic.launcher.tokiz.common.colorz
import bums.lunatic.launcher.tokiz.common.getIndex
import bums.lunatic.launcher.tokiz.common.typesfacez
import bums.lunatic.launcher.tokiz.data.HistoryManager
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
import bums.lunatic.launcher.tokiz.data.model.PageInfosJ
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
import bums.lunatic.launcher.tokiz.data.model.LastInfo
import bums.lunatic.launcher.tokiz.data.model.PortMessage
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
import bums.lunatic.launcher.tokiz.dialog.DefaultList
import bums.lunatic.launcher.tokiz.view.JxEvent
import bums.lunatic.launcher.tokiz.view.PagedTextLayout
import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface
import bums.lunatic.launcher.databinding.BooktokiBinding
import bums.lunatic.launcher.utils.Blog
import com.google.gson.Gson
import io.realm.kotlin.Realm
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.copyFromRealm
import io.realm.kotlin.ext.query
import org.json.JSONException
import org.json.JSONObject
import org.mozilla.gecko.util.ThreadUtils
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.MediaSession
import org.mozilla.geckoview.WebExtension
import org.mozilla.geckoview.WebExtension.MessageDelegate
import org.mozilla.geckoview.WebExtension.PortDelegate
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
import org.mozilla.geckoview.WebRequestError
import java.lang.System.currentTimeMillis
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.collections.ArrayList
import kotlin.collections.List
import kotlin.collections.MutableList
import kotlin.collections.arrayListOf
import kotlin.collections.first
import kotlin.collections.isNotEmpty
import kotlin.collections.last
import kotlin.collections.sortBy
import kotlin.random.Random
import kotlin.text.contains
import kotlin.text.endsWith
import kotlin.text.equals
import kotlin.text.replace
import kotlin.text.split
import kotlin.text.startsWith
import kotlin.text.toInt
import kotlin.text.toRegex
import kotlin.text.trim
class Zota : BaseToki(), PagedTextViewInterface {

View File

@ -1,7 +1,7 @@
package bums.lunatic.launcher.tokiz.data
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
import bums.lunatic.launcher.tokiz.data.model.LastInfo
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig

View File

@ -15,6 +15,9 @@ class PortMessage {
var privates : ArrayList<RssData>? = null
var currentPage : String? = null
var cookies : String? = null
var imgSrc: String? = null
var base64Data: String? = null
}
class BookContents {
var chapterTitle : String? = null

View File

@ -1,7 +1,6 @@
package bums.lunatic.launcher.tokiz.data.model
import android.content.pm.ActivityInfo
import bums.lunatic.launcher.tokiz.data.model.LastInfo
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.PrimaryKey
import java.text.SimpleDateFormat

View File

@ -3,7 +3,6 @@ package bums.lunatic.launcher.tokiz.view
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.util.AttributeSet
import android.view.MotionEvent
@ -15,7 +14,6 @@ import bums.lunatic.launcher.R
import bums.lunatic.launcher.helpers.ForeGroundService
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.ACTION_VIDEO_DOWNLOAD
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.EXTRA_TARGET_URL
import bums.lunatic.launcher.tokiz.common.TouchArea
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.utils.SimpleFingerGestures
import com.yausername.youtubedl_android.YoutubeDL

View File

@ -9,17 +9,12 @@ import android.text.StaticLayout
import android.util.AttributeSet
import android.util.TypedValue
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.view.marginBottom
import androidx.core.view.marginLeft
import androidx.core.view.marginRight
import androidx.core.view.marginTop
import bums.lunatic.launcher.utils.Blog
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlin.math.min
class PagedTextView : AppCompatTextView {
private var needPaginate = false

View File

@ -0,0 +1,237 @@
package bums.lunatic.launcher.utils
import android.os.Build
/**
* APILevel helps to check device API [Build.VERSION] conveniently.
*
* @author Marcos Trujillo, Leonardo Taehwan Kim
*/
object APILevel {
/**
* @param level minimum API level version that has to support the device
* @return true when the caller API version is at least level
*/
fun require(level: Int): Boolean {
return Build.VERSION.SDK_INT >= level
}
/**
* @return true when the caller API version is at least Cupcake 3
*/
fun requireCupcake(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE
}
/**
* @return true when the caller API version is at least Donut 4
*/
fun requireDonut(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT
}
/**
* @return true when the caller API version is at least Eclair 5
*/
fun requireEclair(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR
}
/**
* @return true when the caller API version is at least Froyo 8
*/
fun requireFroyo(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO
}
/**
* @return true when the caller API version is at least GingerBread 9
*/
fun requireGingerbread(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD
}
/**
* @return true when the caller API version is at least Honeycomb 11
*/
fun requireHoneycomb(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
}
/**
* @return true when the caller API version is at least Honeycomb 3.2, 13
*/
fun requireHoneycombMR2(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2
}
/**
* @return true when the caller API version is at least ICS 14
*/
fun requireIceCreamSandwich(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH
}
/**
* @return true when the caller API version is at least JellyBean 16
*/
fun requireJellyBean(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
}
/**
* @return true when the caller API version is at least JellyBean MR1 17
*/
fun requireJellyBeanMR1(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1
}
/**
* @return true when the caller API version is at least JellyBean MR2 18
*/
fun requireJellyBeanMR2(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2
}
/**
* @return true when the caller API version is at least Kitkat 19
*/
fun requireKitkat(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
}
/**
* @return true when the caller API version is at least Lollipop 21
*/
fun requireLollipop(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
}
/**
* @return true when the caller API version is at least Lollipop MR1 22
*/
fun requireLollipopMR1(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1
}
/**
* @return true when the caller API version is at least Marshmallow 23
*/
fun requireMarshmallow(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
}
/**
* @param level API level version that specific method or variable has been deprecated
* @return true when the caller API version is less than level
*/
fun deprecatedAt(level: Int): Boolean {
return Build.VERSION.SDK_INT < level
}
/**
* @return true when the caller API version is less than Cupcake 3
*/
fun deprecatedAtCupcake(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.CUPCAKE
}
/**
* @return true when the caller API version is less than Donut 4
*/
fun deprecatedAtDonut(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.DONUT
}
/**
* @return true when the caller API version is less than Eclair 5
*/
fun deprecatedAtEclair(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.ECLAIR
}
/**
* @return true when the caller API version is less than Froyo 8
*/
fun deprecatedAtFroyo(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO
}
/**
* @return true when the caller API version is less than GingerBread 9
*/
fun deprecatedAtGingerbread(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD
}
/**
* @return true when the caller API version is less than Honeycomb 11
*/
fun deprecatedAtHoneycomb(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB
}
/**
* @return true when the caller API version is less than Honeycomb 3.2, 13
*/
fun deprecatedAtHoneycombMR2(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2
}
/**
* @return true when the caller API version is less than ICS 14
*/
fun deprecatedAtIceCreamSandwich(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH
}
/**
* @return true when the caller API version is less than JellyBean 16
*/
fun deprecatedAtJellyBean(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN
}
/**
* @return true when the caller API version is less than JellyBean MR1 17
*/
fun deprecatedAtJellyBeanMR1(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1
}
/**
* @return true when the caller API version is less than JellyBean MR2 18
*/
fun deprecatedAtJellyBeanMR2(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2
}
/**
* @return true when the caller API version is less than Kitkat 19
*/
fun deprecatedAtKitkat(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT
}
/**
* @return true when the caller API version is less than Lollipop 21
*/
fun deprecatedAtLollipop(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP
}
/**
* @return true when the caller API version is less than Lollipop MR1 22
*/
fun deprecatedAtLollipopMR1(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1
}
/**
* @return true when the caller API version is less than Marshmallow 23
*/
fun deprecatedAtMarshmallow(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M
}
}

View File

@ -3,7 +3,6 @@ package bums.lunatic.launcher.utils
import android.content.Context
import android.net.Uri
import android.os.Build
import java.io.FileOutputStream
import android.webkit.MimeTypeMap
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -12,6 +11,7 @@ import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.File
import java.io.FileOutputStream
import java.net.URLConnection
import java.util.regex.Pattern

View File

@ -0,0 +1,71 @@
package bums.lunatic.launcher.utils
import android.content.Context
import com.bumptech.glide.Glide
import com.bumptech.glide.Registry
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.module.AppGlideModule
import okhttp3.Cache
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import java.io.File
import java.io.InputStream
import java.util.concurrent.TimeUnit
@GlideModule
class CustomOkHttpGlideModule : AppGlideModule() {
override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
val logging = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.HEADERS
}
val cacheSize = 1024L * 1024 * 1024 * 6 // 60MB
val cache = Cache(File(context.filesDir, "clide-cache"), cacheSize)
val okHttpClient = OkHttpClient.Builder()
.cache(cache)
.addInterceptor { chain ->
var request = chain.request()
val isA = request.url.host.contains("ijavtorrent")
val host = if (request.url.host.contains("ijavtorrent")) {
"ijavtorrent.com"
} else {
chain.request().url.host
}
val newRequestBuilder = request.newBuilder().addHeader("authority",host)
.addHeader("Host",host)
// .addHeader("User-Agent","Mozilla/5.0 (Android 15; Mobile; rv:139.0) Gecko/139.0 Firefox/139.0")
.addHeader("Accept",if (isA == false) {
"image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5"
} else {
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"
})
.addHeader("Accept-Language","ko-KR,en-US;q=0.5")
.addHeader("Accept-Encoding","gzip, deflate, br, zstd")
.addHeader("Referer",host)
// .removeHeader("Cache-Control")
// if (isA) {
//// newRequestBuilder.addHeader("sec-ch-ua-platform","macOS")
// newRequestBuilder.addHeader("sec-fetch-dest","document")
// newRequestBuilder.addHeader("sec-fetch-mode","navigate")
//
// }
Blog.LOGE("chain.request().url() >>> ${chain.request().url} : host : $host")
val response = chain.proceed(newRequestBuilder.build())
Blog.LOGE("응답 코드: ${response.code}:${response.message}")
response
}
.addInterceptor(logging)
.callTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS) // 연결 타임아웃
.readTimeout(60, TimeUnit.SECONDS) // 읽기 타임아웃
.writeTimeout(60, TimeUnit.SECONDS) // 쓰기 타임아웃
.build()
registry.replace(
GlideUrl::class.java, InputStream::class.java,
OkHttpUrlLoader.Factory(okHttpClient)
)
}
}

View File

@ -1,17 +1,9 @@
package bums.lunatic.launcher.utils
import bums.lunatic.launcher.home.RssHome.Companion.lastedFinishedPageUrl
import bums.lunatic.launcher.model.RssData
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.model.dateFormat
import bums.lunatic.launcher.model.getRssData
import bums.lunatic.launcher.workers.WorkersDb
import io.realm.kotlin.ext.query
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import java.text.SimpleDateFormat
import java.util.Base64
import java.util.Date
val USAGT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15"
fun String.getJ() : Document {

View File

@ -1,6 +1,5 @@
package bums.lunatic.launcher.utils
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.media.MediaMetadataRetriever

View File

@ -0,0 +1,256 @@
package bums.lunatic.launcher.utils
import android.annotation.TargetApi
import android.content.Context
import android.content.SharedPreferences
import android.os.Build
import android.util.Base64
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.io.Serializable
interface PrefKey<T> {
fun getKey() : String
fun set(value : T)
fun get(def : T? = null) : T
}
interface PrefJsonConvert {
fun initialize(context: Context)
fun inject(SharedPreferences : SharedPreferences)
fun getSettings() : Map<String,Any>
fun putSetting(json : Map<String,Any>)
}
abstract class PreferencesHelper : PrefJsonConvert {
var sharedPreferences : SharedPreferences? = null
open fun allPrefKeys() : ArrayList<String> =arrayListOf()
open fun getBooleanPrefix() : String = getDefaultPrefix().plus(".BOOL.")
open fun getStringPrefix() : String = getDefaultPrefix().plus(".STRING.")
open fun getLongPrefix() : String = getDefaultPrefix().plus(".LONG.")
open fun getDefaultPrefix() : String = PreferencesHelper::class.java.canonicalName
abstract override fun getSettings() : Map<String,Any>
abstract override fun putSetting(json : Map<String,Any>)
override fun initialize(context: Context) {
inject(context.getSharedPreferences(getDefaultPrefix(), Context.MODE_PRIVATE))
}
override fun inject(sharedPreferences : SharedPreferences) {
this.sharedPreferences = sharedPreferences
}
fun get(key: String?, defValue: Boolean): Boolean {
return get(getDefaultPrefix(), key, defValue)
}
fun get(key: String?, defValue: Int): Int {
return get(getDefaultPrefix(), key, defValue)
}
fun get(key: String?, defValue: Float): Float {
return get(getDefaultPrefix(), key, defValue)
}
fun get(key: String?, defValue: Long): Long {
return get(getDefaultPrefix(), key, defValue)
}
fun get(key: String?, defValue: String?): String? {
return get(getDefaultPrefix(), key, defValue)
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
fun get(key: String?, defValue: Set<String?>?): Set<String>? {
return get(getDefaultPrefix(), key, defValue)
}
@TargetApi(Build.VERSION_CODES.FROYO)
fun <C : Serializable?> get(key: String?, defValue: C): C {
return get(getDefaultPrefix(), key, defValue)
}
fun get(name: String, key: String?, defValue: Boolean): Boolean {
return getPreferences()?.getBoolean(key, defValue) ?: false
}
fun getPreferences(): SharedPreferences? {
return this.sharedPreferences
}
fun get(name: String, key: String?, defValue: Int): Int {
return getPreferences()?.getInt(key, defValue) ?: 0
}
fun get(name: String, key: String?, defValue: Float): Float {
return getPreferences()?.getFloat(key, defValue) ?: 0f
}
fun get(name: String, key: String?, defValue: Long): Long {
return getPreferences()?.getLong(key, defValue) ?: 0L
}
fun get(name: String, key: String?, defValue: String?): String? {
return getPreferences()?.getString(key, defValue)
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
fun get(name: String, key: String?, defValue: Set<String?>?): Set<String>? {
return getPreferences()?.getStringSet(key, defValue)
}
@TargetApi(Build.VERSION_CODES.FROYO)
fun <C : Serializable?> get(name: String, key: String?, defValue: C): C {
var bais: ByteArrayInputStream? = null
var ois: ObjectInputStream? = null
var result = defValue
val value = getPreferences()?.getString(key, null)
if (value != null) {
try {
val decoded = Base64.decode(value.toByteArray(), Base64.DEFAULT)
bais = ByteArrayInputStream(decoded)
ois = ObjectInputStream(bais)
result = ois.readObject() as C
} catch (e: Exception) {
// Blog.LOGE(e.printStackTrace())
} finally {
if (ois != null) {
try {
ois.close()
} catch (e: IOException) {
// LogHelper.e(e)
}
}
if (bais != null) {
try {
bais.close()
} catch (e: IOException) {
// LogHelper.e(e)
}
}
}
}
return result
}
fun put(key: String?, value: Boolean) {
put(getDefaultPrefix(), key, value)
}
fun put(key: String?, value: Int) {
put(getDefaultPrefix(), key, value)
}
fun put(key: String?, value: Float) {
put(getDefaultPrefix(), key, value)
}
fun put(key: String?, value: Long) {
put(getDefaultPrefix(), key, value)
}
fun put(key: String?, value: String?) {
put(getDefaultPrefix(), key, value)
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
fun put(key: String?, value: Set<String?>?) {
put(getDefaultPrefix(), key, value)
}
@TargetApi(Build.VERSION_CODES.FROYO)
fun <C : Serializable?> put(key: String?, value: C) {
put(getDefaultPrefix(), key, value)
}
fun put(name: String, key: String?, value: Boolean) {
if (APILevel.require(9)) getPreferences()?.edit()?.putBoolean(key, value)?.apply()
else getPreferences()?.edit()?.putBoolean(key, value)?.commit()
}
fun put(name: String, key: String?, value: Int) {
if (APILevel.require(9)) getPreferences()?.edit()?.putInt(key, value)?.apply()
else getPreferences()?.edit()?.putInt(key, value)?.commit()
}
fun put(name: String, key: String?, value: Float) {
if (APILevel.require(9)) getPreferences()?.edit()?.putFloat(key, value)?.apply()
else getPreferences()?.edit()?.putFloat(key, value)?.commit()
}
fun put(name: String, key: String?, value: Long) {
if (APILevel.require(9)) getPreferences()?.edit()?.putLong(key, value)?.apply()
else getPreferences()?.edit()?.putLong(key, value)?.commit()
}
fun put(name: String, key: String?, value: String?) {
if (APILevel.require(9)) getPreferences()?.edit()?.putString(key, value)?.apply()
else getPreferences()?.edit()?.putString(key, value)?.commit()
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
fun put(name: String, key: String?, value: Set<String?>?) {
if (APILevel.require(9)) getPreferences()?.edit()?.putStringSet(key, value)?.apply()
else getPreferences()?.edit()?.putStringSet(key, value)?.commit()
}
@TargetApi(Build.VERSION_CODES.FROYO)
fun <C : Serializable?> put(name: String, key: String?, value: C) {
var baos: ByteArrayOutputStream? = null
var oos: ObjectOutputStream? = null
try {
baos = ByteArrayOutputStream()
oos = ObjectOutputStream(baos)
oos.writeObject(value)
val encoded = Base64.encode(baos.toByteArray(), Base64.DEFAULT)
if (APILevel.require(9)) getPreferences()?.edit()?.putString(key, String(encoded))?.apply()
else getPreferences()?.edit()?.putString(key, String(encoded))?.commit()
} catch (e: IOException) {
// LogHelper.e(e)
throw RuntimeException(e)
} finally {
if (oos != null) {
try {
oos.close()
} catch (e: IOException) {
// LogHelper.e(e)
}
}
if (baos != null) {
try {
baos.close()
} catch (e: IOException) {
// LogHelper.e(e)
}
}
}
}
fun remove(key: String?) {
remove(getDefaultPrefix(), key)
}
fun remove(name: String, key: String?) {
if (APILevel.require(9)) getPreferences()?.edit()?.remove(key)?.apply()
else getPreferences()?.edit()?.remove(key)?.commit()
}
@JvmOverloads
fun clear(name: String = getDefaultPrefix()) {
if (APILevel.require(9)) getPreferences()?.edit()?.clear()?.apply()
else getPreferences()?.edit()?.clear()?.commit()
}
}

View File

@ -3,7 +3,7 @@ package bums.lunatic.launcher.wall
import android.util.Log
import android.view.Surface
class NativeRenderer {
open class NativeRenderer {
interface NextMediaCallback {
fun onNextMediaRequested()

View File

@ -1,16 +1,12 @@
package bums.lunatic.launcher.workers
//import bums.lunatic.launcher.workers.WorkersDb.blockKeyword
import android.content.Context
import androidx.work.WorkerParameters
import bums.lunatic.launcher.model.Arca
import bums.lunatic.launcher.model.RssDataInterface
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.model.getRssData
import bums.lunatic.launcher.model.getT
import bums.lunatic.launcher.utils.Blog
import bums.lunatic.launcher.utils.beforeOneDay
//import bums.lunatic.launcher.workers.WorkersDb.blockKeyword
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
class ArcaGetter : BaseGetter {

View File

@ -4,7 +4,6 @@ import android.content.Context
import androidx.annotation.CallSuper
import androidx.work.Worker
import androidx.work.WorkerParameters
import bums.lunatic.launcher.LauncherActivity
import bums.lunatic.launcher.LunaticLauncher
import bums.lunatic.launcher.model.RssData
import bums.lunatic.launcher.utils.beforeDay

View File

@ -4,16 +4,12 @@ import android.annotation.SuppressLint
import android.content.Context
import androidx.work.WorkerParameters
import bums.lunatic.launcher.LauncherActivity
import bums.lunatic.launcher.home.GeckoWeb
import bums.lunatic.launcher.model.Dotax
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.model.getRssData
import bums.lunatic.launcher.utils.Blog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jsoup.Jsoup
class DotaxGetter : BaseGetter {
companion object {

View File

@ -25,7 +25,6 @@ import com.google.gson.Gson
import io.realm.kotlin.ext.query
import io.realm.kotlin.query.Sort
import okhttp3.ConnectionPool
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request

View File

@ -2,11 +2,6 @@ package bums.lunatic.launcher.workers
import bums.lunatic.launcher.BuildConfig
import bums.lunatic.launcher.apps.SimpleContact
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
import bums.lunatic.launcher.tokiz.data.model.LastInfo
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
import bums.lunatic.launcher.common.letTrue
import bums.lunatic.launcher.model.AppInfo
import bums.lunatic.launcher.model.Astro
@ -30,12 +25,16 @@ import bums.lunatic.launcher.model.TelegramData
import bums.lunatic.launcher.model.TelegramFrom
import bums.lunatic.launcher.model.TelegramMessage
import bums.lunatic.launcher.model.WeatherForcast
import bums.lunatic.launcher.tokiz.data.model.ContentsCollection
import bums.lunatic.launcher.tokiz.data.model.ContentsPageInfo
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
import bums.lunatic.launcher.tokiz.data.model.LastInfo
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
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
import io.realm.kotlin.Realm
import io.realm.kotlin.RealmConfiguration
import io.realm.kotlin.UpdatePolicy
@ -45,9 +44,6 @@ import io.realm.kotlin.query.RealmQuery
import io.realm.kotlin.query.Sort
import io.realm.kotlin.types.BaseRealmObject
import io.realm.kotlin.types.TypedRealmObject
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.regex.Pattern
import kotlin.reflect.KClass

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="48dp"
android:viewportHeight="144.0"
android:viewportWidth="144.0"
android:width="48dp">
<path
android:fillColor="#FF000000"
android:pathData="M84.5,89.3L64.4,70.5l20.2,-18.8c1.2,-1.1 1.3,-3 0.2,-4.2c-1.1,-1.2 -3,-1.3 -4.2,-0.2L58,68.3c-0.6,0.6 -1,1.4 -1,2.2c0,0.8 0.3,1.6 1,2.2l22.5,21c1.2,1.1 3.1,1.1 4.2,-0.1C85.8,92.3 85.8,90.4 84.5,89.3L84.5,89.3z"/>
</vector>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="48dp"
android:viewportHeight="144.0"
android:viewportWidth="144.0"
android:width="48dp">
<path
android:fillColor="#FF000000"
android:pathData="M76.8,72l16.3,-15.8c1.2,-1.2 1.2,-3.1 0.1,-4.2c-1.2,-1.2 -3.1,-1.2 -4.2,-0.1l-16.4,16l-16.4,-16c-1.2,-1.2 -3.1,-1.1 -4.2,0.1c-1.2,1.2 -1.1,3.1 0.1,4.2L68.2,72L51.9,87.8c-1.2,1.2 -1.2,3.1 -0.1,4.2c1.2,1.2 3.1,1.2 4.2,0.1l16.4,-16l16.4,16c1.2,1.2 3.1,1.1 4.2,-0.1c1.2,-1.2 1.1,-3.1 -0.1,-4.2L76.8,72z"/>
</vector>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<selector>
</selector>

View File

@ -2,7 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/grey_hex_20"
android:background="@color/finestSilver"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">

View File

@ -2,7 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/grey_hex_20"
android:background="@color/finestSilver"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">

View File

@ -1,7 +1,5 @@
<?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"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"

View File

@ -20,4 +20,6 @@
<color name="button_color">#994CAF50</color>
<color name="button_color_tint">#99007ACC</color>
<color name="Color_White">#FFF</color>
<color name="finestSilver">#A5A5A5</color>
</resources>

View File

@ -1,4 +1,4 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<resources>
<!-- Base application theme. -->
<style name="Theme.LunarLauncher" parent="Theme.Material3.DynamicColors.DayNight.NoActionBar">

View File

@ -1,18 +1,22 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
val kotlinVersion = "2.0.0"
extra ["kotlinVersion"] = kotlinVersion
dependencies {
classpath (kotlin("gradle-plugin", version = kotlinVersion))
buildscript {
val kotlinVersion = "2.0.10" // Define here
val realmVersion = "2.0.0"
extra ["kotlinVersion"] = kotlinVersion
extra ["realmVersion"] = realmVersion
dependencies { classpath (kotlin("gradle-plugin", version = kotlinVersion))
}
}
plugins {
id ("com.android.application") version "8.10.1" apply false
id ("com.android.library") version "8.10.1" apply false
val kotlinVersion: String by extra
id ("com.android.application") version "8.6.0" apply false
id ("com.android.library") version "8.6.0" apply false
id ("io.realm.kotlin") version "2.0.0" apply false
id("org.jetbrains.kotlin.android") version "2.0.0" apply false
id("org.jetbrains.kotlin.android") version kotlinVersion apply false
}

27
buildSrc/build.gradle.kts Normal file
View File

@ -0,0 +1,27 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
// 이것이 핵심입니다.
// Kotlin DSL 스크립트 플러그인을 적용합니다.
// 이 플러그인은 자동으로 'org.jetbrains.kotlin.jvm' 플러그인을 포함하고
// 'gradleApi()' 및 'kotlin-stdlib' 의존성을 추가해 줍니다.
`kotlin-dsl`
}
repositories {
// 위 플러그인을 다운로드할 저장소가 필요합니다.
mavenCentral()
google()
}
// (선택 사항이지만 강력히 권장)
// buildSrc 코드를 컴파일할 JVM 버전을 프로젝트의 나머지 부분과 일치시킵니다.
// (최신 안드로이드 프로젝트는 JDK 17이 필요합니다)
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "17"
}

View File

@ -0,0 +1,6 @@
object Versions {
const val retrofit = "2.9.0"
const val appcompat = "1.6.1"
const val kotlinVersion = "2.0.10" // Define here
const val realmVersion = "2.0.0"
}

View File

@ -5,7 +5,7 @@ plugins {
android {
namespace = "kr.lunaticbum.awesomewebview"
compileSdk = 35
compileSdk = 36
defaultConfig {
// applicationId = "kr.lunaticbum.awesomewebview"

View File

@ -5,7 +5,7 @@ plugins {
android {
namespace = "kr.lunaticbum.helpers"
compileSdk = 35
compileSdk = 36
defaultConfig {
minSdk = 26
// targetSdk = 34

View File

@ -1,49 +1,49 @@
package kr.lunaticbum
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.AssetManager
import android.content.res.Configuration
import android.content.res.Resources
import android.content.res.Resources.Theme
import android.util.DisplayMetrics
/**
* Base helps to get [Context], [Resources], [AssetManager], [Configuration] and [DisplayMetrics] in any class.
*
* @author Leonardo Taehwan Kim
*/
@SuppressLint("StaticFieldLeak")
object Base {
private var context: Context? = null
fun initialize(context: Context) {
Base.context = context
}
fun getContext(): Context {
synchronized(Base::class.java) {
if (context == null) throw NullPointerException("Call Base.initialize(context) within your Application onCreate() method.")
return context!!.applicationContext
}
}
val resources: Resources
get() = getContext().resources
val theme: Theme
get() = getContext().theme
val assets: AssetManager
get() = getContext().assets
val configuration: Configuration
get() = resources.configuration
val displayMetrics: DisplayMetrics
get() = resources.displayMetrics
} // TODO: Thread safety
// TODO: ripple, bitmap, time, contact list, picture list, video list, connectivity, wake lock, screen lock/off/on, get attributes, cookie, audio
// TODO: keystore
// TODO: http://jo.centis1504.net/?p=1189
// TODO: Test codes
//package kr.lunaticbum
//
//import android.annotation.SuppressLint
//import android.content.Context
//import android.content.res.AssetManager
//import android.content.res.Configuration
//import android.content.res.Resources
//import android.content.res.Resources.Theme
//import android.util.DisplayMetrics
//
///**
// * Base helps to get [Context], [Resources], [AssetManager], [Configuration] and [DisplayMetrics] in any class.
// *
// * @author Leonardo Taehwan Kim
// */
//@SuppressLint("StaticFieldLeak")
//object Base {
// private var context: Context? = null
//
// fun initialize(context: Context) {
// Base.context = context
// }
//
// fun getContext(): Context {
// synchronized(Base::class.java) {
// if (context == null) throw NullPointerException("Call Base.initialize(context) within your Application onCreate() method.")
// return context!!.applicationContext
// }
// }
//
// val resources: Resources
// get() = getContext().resources
//
// val theme: Theme
// get() = getContext().theme
//
// val assets: AssetManager
// get() = getContext().assets
//
// val configuration: Configuration
// get() = resources.configuration
//
// val displayMetrics: DisplayMetrics
// get() = resources.displayMetrics
//} // TODO: Thread safety
//// TODO: ripple, bitmap, time, contact list, picture list, video list, connectivity, wake lock, screen lock/off/on, get attributes, cookie, audio
//// TODO: keystore
//// TODO: http://jo.centis1504.net/?p=1189
//// TODO: Test codes