From 57039939fd128f87ac6f9ea93e702aec051a0fb8 Mon Sep 17 00:00:00 2001 From: lunaticbum Date: Mon, 30 Mar 2026 14:10:05 +0900 Subject: [PATCH] ... --- .../extensions/my_extension/messaging.js | 7 +++ .../bums/lunatic/launcher/home/GeckoWeb.kt | 41 +++--------- .../launcher/view/LunaticBrowserLayout.kt | 4 +- .../launcher/wall/MyWallpaperService.kt | 63 ++++--------------- .../lunatic/launcher/wall/NativeRenderer.kt | 2 + .../res/layout/layout_lunatic_browser.xml | 2 +- 6 files changed, 36 insertions(+), 83 deletions(-) diff --git a/app/src/main/assets/extensions/my_extension/messaging.js b/app/src/main/assets/extensions/my_extension/messaging.js index 36887ccf..4934d5ca 100644 --- a/app/src/main/assets/extensions/my_extension/messaging.js +++ b/app/src/main/assets/extensions/my_extension/messaging.js @@ -55,6 +55,13 @@ port.onMessage.addListener(response => { var type= response["type"]; switch (type) { + case "SCROLL_TOP": { + window.scrollTo({ + top: 0, + behavior: 'smooth' + }); + } + break; case "SEEK_NEXT": // 5초 앞으로 { let btn = diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt index 67f0014e..bab856ca 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt @@ -129,6 +129,10 @@ open class GeckoWeb @JvmOverloads constructor( } } + fun scrollTop() { + sendJsonMsg("SCROLL_TOP") + } + // UI & State var decoViews = arrayListOf() var progress: ProgressBar? = null @@ -297,29 +301,6 @@ open class GeckoWeb @JvmOverloads constructor( } } catch (e: Exception) { Blog.LOGE("Download Check Error", e) - -// val msg = e.message ?: "" - -// if (msg.contains("parse video information") && !lastCheckUrlS.contains(cleanUrl)) { -// CoroutineScope(Dispatchers.Main).launch { -// CoroutineScope(Dispatchers.Main).launch { -// decoViews.firstOrNull { it.id == R.id.btn_dl_video }?.let { view -> -// view.setOnClickListener { -// AlertDialog.Builder(context) -// .setTitle("음악 전용으로 재시도?") -// .setMessage("parse 에러 발생. forMusic=true로 재시도합니다.") -// .setPositiveButton("오키") { _, _ -> -// checkIfDownloadable(cleanUrl, true) -// } -// .setNegativeButton("취소", null) -// .show() -// lastCheckUrlS.add(cleanUrl) -// } -// } -// } -// -// } -// } } } } @@ -398,7 +379,6 @@ open class GeckoWeb @JvmOverloads constructor( url?.let { if (it.contains(getFilterF()) && privateMode) this@GeckoWeb.visibility = View.INVISIBLE lastedUrl = if (it.split("//").size > 1) it.replace("//", "/").replace("https:/", "https://") else it - checkIfDownloadable(it) onLocationChangeCallback?.invoke(it) // 외부 콜백 } @@ -435,7 +415,7 @@ open class GeckoWeb @JvmOverloads constructor( } override fun onCanGoBack(session: GeckoSession, canGoBack: Boolean) { - Blog.LOGE("onCanGoBack $canGoBack ${session}") +// Blog.LOGE("onCanGoBack $canGoBack ${session}") this@GeckoWeb.canGoBack = canGoBack } } @@ -469,21 +449,19 @@ open class GeckoWeb @JvmOverloads constructor( saveCurrentSessionState() } onPageStartCallback?.invoke(url) -// Blog.LOGE("onPageStart $url ${session}") - checkIfDownloadable(url) } override fun onPageStop(session: GeckoSession, success: Boolean) { onPageStopCallback?.invoke(success) if (success) { saveCurrentSessionState() } - Blog.LOGE("onPageStop $success ${session}") +// Blog.LOGE("onPageStop $success ${session}") } override fun onSessionStateChange(session: GeckoSession, sessionState: GeckoSession.SessionState) { lastSessionState = sessionState onSessionStateChangeCallback?.invoke(sessionState) - Blog.LOGE("onSessionStateChange $sessionState ${session}") +// Blog.LOGE("onSessionStateChange $sessionState ${session}") } } private var lastSessionState: GeckoSession.SessionState? = null @@ -634,15 +612,16 @@ open class GeckoWeb @JvmOverloads constructor( private fun handlePortMessage(msg: PortMessage) { when (msg.type) { "COOKIES_REPORT"-> { - Blog.LOGE("${msg.value} -> ${msg.url}") +// Blog.LOGE("${msg.value} -> ${msg.url}") currentCookieString = msg.value ?: "" currentCookieUrlString = msg.url ?: "" CoroutineScope(Dispatchers.IO).launch { saveYoutubeCookiesToFile() } + checkIfDownloadable(currentCookieUrlString) } "SCROLL_STATE" -> { - Blog.LOGE("${msg.type} : ${msg.value}") +// Blog.LOGE("${msg.type} : ${msg.value}") scrollState = msg.value?.toInt() ?: 0 } "allImagesFound" -> lastedUrl?.let { startBookmarkSaveProcessForMultipleImages(it, msg.urls) } diff --git a/app/src/main/kotlin/bums/lunatic/launcher/view/LunaticBrowserLayout.kt b/app/src/main/kotlin/bums/lunatic/launcher/view/LunaticBrowserLayout.kt index 787468d3..0d959dcb 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/view/LunaticBrowserLayout.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/view/LunaticBrowserLayout.kt @@ -35,7 +35,9 @@ class LunaticBrowserLayout @JvmOverloads constructor( context.startActivity(Intent.createChooser(intent, "공유")) } } - + binding.tvTitle.setOnClickListener { + geckoWeb.scrollTop() + } // GeckoWeb 내부에서 주소 등 업데이트 시 연동되도록 등록 geckoWeb.decoViews.addAll(listOf( binding.tvAddress, binding.btnDlVideo, binding.btnReload, binding.btnBack, binding.tvTitle diff --git a/app/src/main/kotlin/bums/lunatic/launcher/wall/MyWallpaperService.kt b/app/src/main/kotlin/bums/lunatic/launcher/wall/MyWallpaperService.kt index 3f7edf43..d808ef15 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/wall/MyWallpaperService.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/wall/MyWallpaperService.kt @@ -17,6 +17,8 @@ import java.io.File class MyWallpaperService : WallpaperService() { + + private val TAG = "MyWallpaperService" override fun onCreateEngine(): Engine { @@ -187,7 +189,7 @@ class MyWallpaperService : WallpaperService() { Log.d(TAG, "Initializing Renderer...") nativeRenderer = NativeRenderer() nativeRenderer?.initialize() // nativeInit() -> initialize() - nativeRenderer?.setFadeDuration(1500) + nativeRenderer?.setFadeDuration(3000) nativeRenderer?.setTurnPageDuration(8000) nativeRenderer?.setAnimationMode(NativeRenderer.ANIMATION_MODE_PAN) nativeRenderer?.setTransitionMode(NativeRenderer.TRANSITION_MODE_FADE) @@ -199,23 +201,22 @@ class MyWallpaperService : WallpaperService() { handler.post { loadMediaFiles() } } } - // ... loadMediaFiles, nextMediaCallback, getFdFromPath는 이전과 동일 ... - private fun loadMediaFiles() { + + val requiredSizeRatio = 0.5 + + fun loadFiles() { if (!mediaDir.exists()) mediaDir.mkdirs() -// mediaFiles = mediaDir.listFiles() -// ?.filter { supportedExtensions.contains(it.extension.lowercase()) } -// ?.toList() ?: emptyList() Log.d(TAG, "Found ${mediaFiles.size} media files.") - val allFiles = mediaDir.listFiles() + val allFiles = mediaDir.listFiles().filter { supportedExtensions.contains(it.extension) } val trashFolder = File(mediaDir, "low_res_backup") if (!trashFolder.exists()) trashFolder.mkdirs() val invalidImages = mutableListOf() val wm = WallpaperManager.getInstance(this@MyWallpaperService) val minWidth = wm.desiredMinimumWidth val minHeight = wm.desiredMinimumHeight - val requiredSize = Math.max(minWidth, minHeight).times(0.6) + val requiredSize = Math.max(minWidth, minHeight).times(requiredSizeRatio) for (file in allFiles) { if (file.isFile && (file.extension.equals("jpg", true) || @@ -240,7 +241,10 @@ class MyWallpaperService : WallpaperService() { val targetFile = File(trashFolder, file.name) file.renameTo(targetFile) // 파일 이동 } + } + private fun loadMediaFiles() { + loadFiles() if (mediaFiles.isNotEmpty()) { val initialFile = mediaFiles.random() Log.d(TAG, "Attempting to load initial random media via preloader: ${initialFile.absolutePath}") @@ -256,48 +260,7 @@ class MyWallpaperService : WallpaperService() { private val nextMediaCallback = object : NativeRenderer.NextMediaCallback { override fun onNextMediaRequested() { - - if (!mediaDir.exists()) mediaDir.mkdirs() - - -// mediaFiles = mediaDir.listFiles() -// ?.filter { supportedExtensions.contains(it.extension.lowercase()) } -// ?.toList() ?: emptyList() - - val allFiles = mediaDir.listFiles() - val trashFolder = File(mediaDir, "low_res_backup") - if (!trashFolder.exists()) trashFolder.mkdirs() -// val validImages = mutableListOf() - val invalidImages = mutableListOf() - val wm = WallpaperManager.getInstance(this@MyWallpaperService) - val minWidth = wm.desiredMinimumWidth - val minHeight = wm.desiredMinimumHeight - val requiredSize = Math.max(minWidth, minHeight).times(0.6) - for (file in allFiles) { - - if (file.isFile && (file.extension.equals("jpg", true) || - file.extension.equals("png", true) || - file.extension.equals("jpeg", true) || - file.extension.equals("bmp", true) || // BMP 추가 - file.extension.equals("webp", true))) { - - val options = BitmapFactory.Options().apply { inJustDecodeBounds = true } - BitmapFactory.decodeFile(file.absolutePath, options) - Blog.LOGE("requiredSize ${requiredSize} w :${options.outWidth} , h : ${options.outHeight}") - if (options.outWidth >= requiredSize && options.outHeight >= requiredSize) { - mediaFiles.add(file) - } else { - invalidImages.add(file) // 조건 미달 - } - } - } - - // 2. 부적합 이미지 이동 처리 (Job 밖에서 따로 돌려도 무방) - invalidImages.forEach { file -> - val targetFile = File(trashFolder, file.name) - file.renameTo(targetFile) // 파일 이동 - } - + loadFiles() val nextFile = mediaFiles.random() Log.d(TAG, "Callback: Preloading next random media: ${nextFile.absolutePath}") diff --git a/app/src/main/kotlin/bums/lunatic/launcher/wall/NativeRenderer.kt b/app/src/main/kotlin/bums/lunatic/launcher/wall/NativeRenderer.kt index bf520ddd..996c8bea 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/wall/NativeRenderer.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/wall/NativeRenderer.kt @@ -96,6 +96,8 @@ open class NativeRenderer { } } + + // --- Private JNI declarations --- private external fun nativeStartRenderLoop(nativeHandle: Long, surface: Surface) private external fun nativeStopRenderLoop(nativeHandle: Long) diff --git a/app/src/main/res/layout/layout_lunatic_browser.xml b/app/src/main/res/layout/layout_lunatic_browser.xml index 743f9eb5..5a1ad977 100644 --- a/app/src/main/res/layout/layout_lunatic_browser.xml +++ b/app/src/main/res/layout/layout_lunatic_browser.xml @@ -11,7 +11,7 @@ android:layout_height="40dp" android:orientation="horizontal" android:gravity="center_vertical" - android:background="#CC000000" + android:background="#D000" app:layout_constraintTop_toTopOf="parent">