...
This commit is contained in:
parent
9aee32e42d
commit
112012ce0c
@ -55,22 +55,203 @@ port.onMessage.addListener(response => {
|
||||
var type= response["type"];
|
||||
|
||||
switch (type) {
|
||||
case "CLICK_PREV_CHAPTER" : {
|
||||
const links = document.querySelectorAll("a");
|
||||
let found = false;
|
||||
for (let link of links) {
|
||||
if (link.textContent.includes("이전화 보기")) {
|
||||
link.click();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
port.postMessage({ type: "MSG", msg: "이전화 버튼을 찾을 수 없습니다." });
|
||||
}
|
||||
break;
|
||||
case "SEEK_NEXT": // 5초 앞으로
|
||||
{
|
||||
let btn =
|
||||
document.querySelector('button[aria-label="10초 빨리 감기"]') ||
|
||||
document.querySelector('button[aria-label="뒤로 10초"]') ||
|
||||
document.querySelector('.ytp-right-controls .ytp-button[aria-label*="뒤로"]');
|
||||
|
||||
if (btn) {
|
||||
btn.click();
|
||||
return;
|
||||
}
|
||||
case "CLICK_NEXT_CHAPTER" : {
|
||||
}
|
||||
break;
|
||||
case "PLAY_PAUSE": // 5초 뒤로
|
||||
{
|
||||
if (document.location.href.search("youtube") > -1) {
|
||||
let btn =
|
||||
document.querySelector('button[aria-label="동영상 재생"]') ||
|
||||
document.querySelector('button[aria-label="동영상 일시중지"]') ;
|
||||
|
||||
if (btn) {
|
||||
btn.click();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
case "SEEK_PREV": // 5초 뒤로
|
||||
{
|
||||
if (document.location.href.search("youtube") > -1) {
|
||||
let btn =
|
||||
document.querySelector('button[aria-label="10초 되감기"]') ||
|
||||
document.querySelector('button[aria-label="앞으로 10초"]') ||
|
||||
document.querySelector('.ytp-right-controls .ytp-button[aria-label*="앞으로"]');
|
||||
|
||||
if (btn) {
|
||||
btn.click();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
case "PREV_SHORTS": {
|
||||
if (document.location.href.search("shorts") > -1) {
|
||||
// 1. 유튜브 쇼츠의 스크롤 컨테이너들 후보 (버전에 따라 다름)
|
||||
const container = document.getElementById('shorts-container') ||
|
||||
document.querySelector('ytd-shorts') ||
|
||||
document.querySelector('#items.ytd-vertical-list-renderer');
|
||||
|
||||
if (container) {
|
||||
// 컨테이너 내부에서 현재 뷰포트 높이만큼 스크롤
|
||||
container.scrollBy({
|
||||
top: window.innerHeight * -1,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
} else {
|
||||
// 컨테이너를 못 찾을 경우, 키보드 'J'나 'ArrowDown'을 시뮬레이션하는 게 가장 정확합니다.
|
||||
const event = new KeyboardEvent('keydown', {
|
||||
key: 'ArrowUp',
|
||||
keyCode: 40,
|
||||
code: 'ArrowUp',
|
||||
which: 40,
|
||||
bubbles: true
|
||||
});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
}else {
|
||||
let btn = document.querySelector('.ytp-prev-button');
|
||||
|
||||
if (!btn) {
|
||||
btn = document.querySelector('button[aria-label="이전 동영상"], button[aria-label="이전"]');
|
||||
}
|
||||
|
||||
if (!btn) {
|
||||
btn = Array.from(document.querySelectorAll('[aria-label]'))
|
||||
.find(el => /이전/.test(el.getAttribute('aria-label')));
|
||||
}
|
||||
|
||||
if (btn) {
|
||||
btn.click();
|
||||
} else {
|
||||
console.log('이전 영상 버튼을 찾지 못했습니다.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "NEXT_SHORTS": {
|
||||
if (document.location.href.search("shorts") > -1) {
|
||||
// 1. 유튜브 쇼츠의 스크롤 컨테이너들 후보 (버전에 따라 다름)
|
||||
const container = document.getElementById('shorts-container') ||
|
||||
document.querySelector('ytd-shorts') ||
|
||||
document.querySelector('#items.ytd-vertical-list-renderer');
|
||||
|
||||
if (container) {
|
||||
// 컨테이너 내부에서 현재 뷰포트 높이만큼 스크롤
|
||||
container.scrollBy({
|
||||
top: window.innerHeight,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
} else {
|
||||
// 컨테이너를 못 찾을 경우, 키보드 'J'나 'ArrowDown'을 시뮬레이션하는 게 가장 정확합니다.
|
||||
const event = new KeyboardEvent('keydown', {
|
||||
key: 'ArrowDown',
|
||||
keyCode: 40,
|
||||
code: 'ArrowDown',
|
||||
which: 40,
|
||||
bubbles: true
|
||||
});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
} else {
|
||||
// 1) 예전/기본 플레이어용 클래스
|
||||
let btn = document.querySelector('.ytp-next-button');
|
||||
|
||||
// 2) aria-label 기반 (언어별로 텍스트 다를 수 있음)
|
||||
if (!btn) {
|
||||
btn = document.querySelector('button[aria-label="다음 동영상"], button[aria-label="다음"]');
|
||||
}
|
||||
|
||||
// 3) 혹시 아이콘 버튼이 다른 태그일 수도 있으니 좀 더 느슨하게
|
||||
if (!btn) {
|
||||
btn = Array.from(document.querySelectorAll('[aria-label]'))
|
||||
.find(el => /다음/.test(el.getAttribute('aria-label')));
|
||||
}
|
||||
|
||||
if (btn) {
|
||||
btn.click();
|
||||
} else {
|
||||
console.log('다음 영상 버튼을 찾지 못했습니다.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CLICK_PREV_CHAPTER" : {
|
||||
const links = document.querySelectorAll("a");
|
||||
let found = false;
|
||||
for (let link of links) {
|
||||
if (link.textContent.includes("이전화 보기")) {
|
||||
link.click();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
port.postMessage({ type: "MSG", msg: "이전화 버튼을 찾을 수 없습니다." });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "MARKER": {
|
||||
const isDown = response["isDown"];
|
||||
const scrollRatio = 0.6; // 이동 비율 (30%)
|
||||
const viewportHeight = window.innerHeight;
|
||||
const distance = viewportHeight * scrollRatio;
|
||||
const startY = window.scrollY;
|
||||
|
||||
const id = 'scroll-ghost-layer';
|
||||
let ghost = document.getElementById(id);
|
||||
if (ghost) ghost.remove();
|
||||
|
||||
ghost = document.createElement('div');
|
||||
ghost.id = id;
|
||||
|
||||
// 💡 isDown에 따라 그라데이션 방향과 보더 위치를 반전
|
||||
const gradDir = isDown ? 'to top' : 'to bottom';
|
||||
const borderStyle = isDown ? 'border-top: 3px solid rgba(0,122,255,0.4);' : 'border-bottom: 3px solid rgba(0,122,255,0.3);';
|
||||
|
||||
ghost.style.cssText = `
|
||||
position: absolute;
|
||||
top: ${startY}px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: ${viewportHeight}px;
|
||||
background: linear-gradient(${gradDir}, rgba(0,122,255,0.5), transparent);
|
||||
${borderStyle}
|
||||
z-index: 2147483647;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.8s ease-out;
|
||||
opacity: 1;
|
||||
`;
|
||||
document.body.appendChild(ghost);
|
||||
|
||||
// 실제 스크롤 수행
|
||||
const targetY = isDown ? startY + distance : startY - distance;
|
||||
window.scrollTo({
|
||||
top: targetY,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
|
||||
// 레이어 제거
|
||||
setTimeout(() => {
|
||||
ghost.style.opacity = '0';
|
||||
setTimeout(() => ghost.remove(), 800);
|
||||
}, 1000);
|
||||
break;
|
||||
}
|
||||
case "CLICK_NEXT_CHAPTER" : {
|
||||
const links = document.querySelectorAll("a");
|
||||
let found = false;
|
||||
for (let link of links) {
|
||||
@ -83,17 +264,17 @@ port.onMessage.addListener(response => {
|
||||
if (!found) {
|
||||
port.postMessage({ type: "MSG", msg: "다음화 버튼을 찾을 수 없습니다." });
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case "fetchAllImages": {
|
||||
const targetSrc = response["targetSrc"];
|
||||
const imageUrls = findAllRelatedImages(targetSrc);
|
||||
// 찾은 이미지 URL 목록을 'allImagesFound' 타입으로 네이티브 앱에 다시 전송
|
||||
sendMessage({
|
||||
type: "allImagesFound",
|
||||
urls: imageUrls
|
||||
});
|
||||
break;
|
||||
const targetSrc = response["targetSrc"];
|
||||
const imageUrls = findAllRelatedImages(targetSrc);
|
||||
// 찾은 이미지 URL 목록을 'allImagesFound' 타입으로 네이티브 앱에 다시 전송
|
||||
sendMessage({
|
||||
type: "allImagesFound",
|
||||
urls: imageUrls
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "search" : {
|
||||
var keyword = response["keyword"];
|
||||
@ -131,7 +312,7 @@ port.onMessage.addListener(response => {
|
||||
const elements = document.querySelectorAll(".main-content"); // 또는 getElementsByClassName("item")
|
||||
|
||||
const matched = Array.from(elements).filter(el =>
|
||||
el.textContent.includes(keyword) // 대소문자 구분
|
||||
el.textContent.includes(keyword) // 대소문자 구분
|
||||
);
|
||||
|
||||
|
||||
@ -284,15 +465,15 @@ if(document.querySelector("#html_encoder_div")) {
|
||||
);
|
||||
}
|
||||
function removeSpecificGifs() {
|
||||
const images = document.getElementsByTagName('img');
|
||||
for (let i = images.length - 1; i >= 0; i--) {
|
||||
const src = images[i].src;
|
||||
// 요청하신 특정 도메인과 gif 패턴, 쿼리 파라미터를 체크
|
||||
if (src.includes('tokinbtoki') && src.includes('.gif') && src.includes('_=')) {
|
||||
images[i].parentNode.removeChild(images[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
const images = document.getElementsByTagName('img');
|
||||
for (let i = images.length - 1; i >= 0; i--) {
|
||||
const src = images[i].src;
|
||||
// 요청하신 특정 도메인과 gif 패턴, 쿼리 파라미터를 체크
|
||||
if (src.includes('tokinbtoki') && src.includes('.gif') && src.includes('_=')) {
|
||||
images[i].parentNode.removeChild(images[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getList(children) {
|
||||
// port.postMessage("Start of getList!" + children);
|
||||
@ -395,7 +576,7 @@ function scrollByPercentUpDown(isToDown , max) {
|
||||
window.scrollTo({ top: currentScroll + (moveAmount * isToDown) , behavior: "smooth" });
|
||||
}
|
||||
function loadComplete() {
|
||||
try {port.postMessage(JSON.stringify({type: "NotRegistered"}));}catch (e) {}
|
||||
try {port.postMessage(JSON.stringify({type: "NotRegistered"}));}catch (e) {}
|
||||
}
|
||||
|
||||
function hideBook() {
|
||||
@ -492,7 +673,7 @@ function scrollToLazyImg(fastMode) {
|
||||
// 한 번에 이동할 픽셀
|
||||
const step = fastMode ? 600 : 200;
|
||||
// 반복 간격(ms) (느릴수록 로딩에 더 여유 생김)
|
||||
const delay = fastMode ? 200 : 600;
|
||||
const delay = fastMode ? 300 : 500;
|
||||
// 스크롤 현재 위치 추적
|
||||
let currentY = window.scrollY;
|
||||
let maxY = Math.max(
|
||||
@ -521,7 +702,7 @@ function scrollToLazyImg(fastMode) {
|
||||
// 직접 메시지 보내거나, 원하는 최종 동작 실행
|
||||
// 예: window.postMessage('saveToObsidian', '*');
|
||||
}
|
||||
}, 800);
|
||||
}, delay);
|
||||
}
|
||||
}
|
||||
|
||||
@ -555,7 +736,7 @@ function gotoNext() {
|
||||
var targetElement = null;
|
||||
|
||||
document.querySelectorAll('.btn-group')?.forEach((el) => {
|
||||
var pageLinks =el?.querySelectorAll('a');
|
||||
var pageLinks =el?.querySelectorAll('a');
|
||||
|
||||
if (pageLinks) {
|
||||
pageLinks.forEach(function(link) {
|
||||
|
||||
@ -20,7 +20,14 @@ package bums.lunatic.launcher
|
||||
|
||||
import android.app.Application
|
||||
import android.content.ComponentCallbacks2
|
||||
import android.content.Context
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.RelativeSizeSpan
|
||||
import android.view.View
|
||||
import android.view.View.inflate
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import bums.lunatic.launcher.helpers.HourlyLogWriter
|
||||
import bums.lunatic.launcher.helpers.PrefHelper
|
||||
import bums.lunatic.launcher.home.Base64ImageCache
|
||||
@ -39,6 +46,7 @@ import java.io.File
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
|
||||
internal class LunaticLauncher : Application() {
|
||||
companion object {
|
||||
var appContext : LunaticLauncher? = null
|
||||
@ -49,6 +57,21 @@ internal class LunaticLauncher : Application() {
|
||||
return sRuntime
|
||||
}
|
||||
var privateCompletedDir : File? = null
|
||||
|
||||
var toast : Toast? = null
|
||||
fun Context.toast(msg: String) {
|
||||
val biggerText = SpannableStringBuilder(msg)
|
||||
biggerText.setSpan(RelativeSizeSpan(1.6f), 0, msg.length, 0)
|
||||
val view: View = inflate(this, R.layout.simple_toast, null)
|
||||
view.findViewById<TextView>(R.id.text).text = biggerText
|
||||
if (toast==null) {
|
||||
toast = Toast(this)
|
||||
toast?.duration = Toast.LENGTH_SHORT
|
||||
toast?.cancel()
|
||||
}
|
||||
toast?.view = view
|
||||
toast?.show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initGeckoRuntime() {
|
||||
|
||||
@ -170,7 +170,7 @@ class ForeGroundService : Service() {
|
||||
set(value) {
|
||||
field = value
|
||||
if (value == null) {
|
||||
startForeGround(max= 0, progress = 0, vibrator = true)
|
||||
startForeGround(max= 0, progress = 0, vibrator = false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ class ForeGroundService : Service() {
|
||||
currentProcessId = UUID.randomUUID().toString()
|
||||
YoutubeDL.getInstance()
|
||||
.execute(command, currentProcessId) { progress, est, str ->
|
||||
startForeGround(100, progress.toInt(),str, true)
|
||||
startForeGround(100, progress.toInt(),str, false)
|
||||
if (progress >= 100) {
|
||||
targetUrls.remove(url)
|
||||
currentProcessId = null
|
||||
@ -210,7 +210,7 @@ class ForeGroundService : Service() {
|
||||
}
|
||||
}
|
||||
|
||||
fun startForeGround(max : Int = 0, progress : Int = 0, str : String? = "실행중입니다.", vibrator : Boolean? = false) {
|
||||
fun startForeGround(max : Int = 0, progress : Int = 0, str : String? = "실행중입니다.", vibrator : Boolean = false) {
|
||||
|
||||
val currentChannelId = if (vibrator == true) "${CHANNEL_ID}_vibrate" else "${CHANNEL_ID}_silent"
|
||||
|
||||
|
||||
@ -7,6 +7,8 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.text.SpannableStringBuilder
|
||||
@ -30,6 +32,7 @@ import androidx.core.net.toUri
|
||||
import androidx.core.view.isVisible
|
||||
import bums.lunatic.launcher.BookmarkUploader
|
||||
import bums.lunatic.launcher.LunaticLauncher.Companion.getRuntime
|
||||
import bums.lunatic.launcher.LunaticLauncher.Companion.toast
|
||||
import bums.lunatic.launcher.R
|
||||
import bums.lunatic.launcher.helpers.ForeGroundService
|
||||
import bums.lunatic.launcher.helpers.ForeGroundService.Companion.ACTION_VIDEO_DOWNLOAD
|
||||
@ -306,6 +309,16 @@ open class GeckoWeb @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
fun nextShorts() {
|
||||
|
||||
sendJsonMsg("NEXT_SHORTS")
|
||||
saveCurrentSessionState()
|
||||
}
|
||||
fun prevShorts() {
|
||||
|
||||
sendJsonMsg("PREV_SHORTS")
|
||||
saveCurrentSessionState()
|
||||
}
|
||||
|
||||
// [Navigation Delegate]
|
||||
private val navigationDelegate = object : GeckoSession.NavigationDelegate {
|
||||
@ -605,25 +618,62 @@ open class GeckoWeb @JvmOverloads constructor(
|
||||
var HH = 0.3
|
||||
fun pageDown() {
|
||||
val session = this.session ?: return
|
||||
val pzc = session.panZoomController
|
||||
|
||||
// 💡 현재 눈에 보이는 GeckoView의 높이를 가져옵니다.
|
||||
val viewHeight = this.height.toDouble().times(HH)
|
||||
|
||||
// 세로 방향(y)으로 뷰 높이만큼 아래로 스크롤 (픽셀 단위)
|
||||
// 세 번째 인자는 애니메이션 여부입니다.
|
||||
pzc.scrollBy(ScreenLength.fromPixels(0.0), ScreenLength.fromPixels(viewHeight),
|
||||
PanZoomController.SCROLL_BEHAVIOR_SMOOTH)
|
||||
sendJsonMsg("MARKER",Pair<String, Any?>("isDown",true))
|
||||
// val pzc = session.panZoomController
|
||||
//
|
||||
// // 💡 현재 눈에 보이는 GeckoView의 높이를 가져옵니다.
|
||||
// val viewHeight = this.height.toDouble().times(HH)
|
||||
//
|
||||
// // 세로 방향(y)으로 뷰 높이만큼 아래로 스크롤 (픽셀 단위)
|
||||
// // 세 번째 인자는 애니메이션 여부입니다.
|
||||
// pzc.scrollBy(ScreenLength.fromPixels(0.0), ScreenLength.fromPixels(viewHeight),
|
||||
// PanZoomController.SCROLL_BEHAVIOR_SMOOTH)
|
||||
//
|
||||
// showGuideLine((this.height - viewHeight).toInt())
|
||||
}
|
||||
|
||||
fun pageUp() {
|
||||
val session = this.session ?: return
|
||||
val pzc = session.panZoomController
|
||||
val viewHeight = this.height.toDouble().times(HH)
|
||||
sendJsonMsg("MARKER",Pair<String, Any?>("isDown",false))
|
||||
// val pzc = session.panZoomController
|
||||
// val viewHeight = this.height.toDouble().times(HH)
|
||||
//
|
||||
// // 위로 스크롤
|
||||
// pzc.scrollBy(ScreenLength.fromPixels(0.0), ScreenLength.fromPixels(-viewHeight),
|
||||
// PanZoomController.SCROLL_BEHAVIOR_SMOOTH)
|
||||
//
|
||||
// showGuideLine(viewHeight.toInt())
|
||||
}
|
||||
|
||||
// 위로 스크롤
|
||||
pzc.scrollBy(ScreenLength.fromPixels(0.0), ScreenLength.fromPixels(-viewHeight),
|
||||
PanZoomController.SCROLL_BEHAVIOR_SMOOTH)
|
||||
private val guideView: View by lazy {
|
||||
View(context).apply {
|
||||
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, 150.dpToPx()) // 150dp 정도의 넓은 영역
|
||||
// 위는 투명하고 아래로 갈수록 강조색이 보이는 그라데이션
|
||||
background = GradientDrawable(
|
||||
GradientDrawable.Orientation.TOP_BOTTOM,
|
||||
intArrayOf(0x00FF0000, 0x40FF0000) // 투명 -> 반투명 빨강
|
||||
)
|
||||
visibility = GONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun showGuideLine(yPosition: Int) {
|
||||
sendJsonMsg("MARKER",Pair<String, Any?>("yPos",yPosition))
|
||||
// if (guideView.parent == null) this.addView(guideView)
|
||||
//
|
||||
// guideView.apply {
|
||||
// // PageDown 시에는 이전 바닥 지점(yPosition)에 뷰의 상단을 맞춤
|
||||
// // PageUp 시에는 이전 천장 지점(yPosition)에 뷰의 하단을 맞춤
|
||||
// translationY = if (isDown) (yPosition - 150.dpToPx()).toFloat() else yPosition.toFloat()
|
||||
// visibility = VISIBLE
|
||||
// alpha = 1f
|
||||
//
|
||||
// animate()
|
||||
// .alpha(0f)
|
||||
// .setDuration(800) // 너무 길면 거슬리니 0.8초 정도가 적당합니다.
|
||||
// .withEndAction { visibility = GONE }
|
||||
// .start()
|
||||
// }
|
||||
}
|
||||
|
||||
// File/Download Helpers
|
||||
@ -712,19 +762,7 @@ open class GeckoWeb @JvmOverloads constructor(
|
||||
|
||||
private fun getFilterF() = String(Base64.decode("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=", Base64.DEFAULT))
|
||||
|
||||
var toast : Toast? = null
|
||||
private fun Context.toast(msg: String) {
|
||||
val biggerText = SpannableStringBuilder(msg)
|
||||
biggerText.setSpan(RelativeSizeSpan(1.6f), 0, msg.length, 0)
|
||||
val view: View = inflate(this, R.layout.simple_toast, null)
|
||||
view.findViewById<TextView>(R.id.text).text = biggerText
|
||||
if (toast==null) {
|
||||
toast = Toast(this)
|
||||
toast?.duration = Toast.LENGTH_SHORT
|
||||
}
|
||||
toast?.view = view
|
||||
toast?.show()
|
||||
}
|
||||
|
||||
|
||||
private fun View.post(action: () -> Unit) = this.post(Runnable(action))
|
||||
fun onPause() {
|
||||
@ -738,4 +776,18 @@ open class GeckoWeb @JvmOverloads constructor(
|
||||
restoreSessionState()
|
||||
session?.setActive(true)
|
||||
}
|
||||
|
||||
// dp 변환 확장 함수
|
||||
private fun Int.dpToPx(): Int = (this * context.resources.displayMetrics.density).toInt()
|
||||
fun prev10() {
|
||||
sendJsonMsg("SEEK_PREV")
|
||||
}
|
||||
|
||||
fun next10() {
|
||||
sendJsonMsg("SEEK_NEXT")
|
||||
}
|
||||
|
||||
fun play_pause() {
|
||||
sendJsonMsg("PLAY_PAUSE")
|
||||
}
|
||||
}
|
||||
@ -116,7 +116,7 @@ internal class RssHome : RemoteGestureFragment() , KeyEventHandler {
|
||||
|
||||
override fun onRemoteLeft(isDouble : Boolean) {
|
||||
if (binding.lunaticBrowser.isVisible) {
|
||||
doNextPage()
|
||||
binding.lunaticBrowser.geckoWeb.goBack()
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -124,7 +124,7 @@ internal class RssHome : RemoteGestureFragment() , KeyEventHandler {
|
||||
|
||||
override fun onRemoteRight(isDouble : Boolean) {
|
||||
if (binding.lunaticBrowser.isVisible) {
|
||||
binding.lunaticBrowser.geckoWeb.goBack()
|
||||
doNextPage()
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -1076,12 +1076,4 @@ internal class RssHome : RemoteGestureFragment() , KeyEventHandler {
|
||||
}
|
||||
fun randomOrNull() : RssData? = lasted.randomOrNull()
|
||||
|
||||
}
|
||||
var toast: Toast? = null
|
||||
fun Context.toast(string: String) {
|
||||
if (toast == null) {
|
||||
toast = Toast.makeText(this,string,Toast.LENGTH_SHORT)
|
||||
}
|
||||
toast?.setText(string)
|
||||
toast?.show()
|
||||
}
|
||||
@ -41,6 +41,7 @@ import java.util.Calendar
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import androidx.camera.lifecycle.ProcessCameraProvider
|
||||
import androidx.core.content.ContextCompat
|
||||
import bums.lunatic.launcher.LunaticLauncher.Companion.toast
|
||||
|
||||
class SystemStatusFragment : Fragment() {
|
||||
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
package bums.lunatic.launcher.home.tokiz
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.media.AudioManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
@ -31,6 +33,7 @@ import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import bums.lunatic.launcher.LunaticLauncher.Companion.toast
|
||||
import bums.lunatic.launcher.R
|
||||
import bums.lunatic.launcher.common.RemoteGestureFragment
|
||||
import bums.lunatic.launcher.databinding.BooktokiBinding
|
||||
@ -38,7 +41,6 @@ import bums.lunatic.launcher.home.GeckoWeb
|
||||
import bums.lunatic.launcher.home.GeckoWeb.JxEvent
|
||||
import bums.lunatic.launcher.home.KeyEventHandler
|
||||
import bums.lunatic.launcher.home.NeoRssActivity
|
||||
import bums.lunatic.launcher.home.toast
|
||||
import bums.lunatic.launcher.home.tokiz.view.PagedTextLayout
|
||||
import bums.lunatic.launcher.home.tokiz.view.PagedTextViewInterface
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
@ -238,7 +240,12 @@ class TokiFragment : RemoteGestureFragment(), PagedTextViewInterface,KeyEventHan
|
||||
}
|
||||
|
||||
override fun onRemoteCenterClick() {
|
||||
super.onRemoteCenterClick()
|
||||
if (contentsType.contains("youtube")) {
|
||||
binding.lunaticBrowser.geckoWeb.play_pause()
|
||||
binding.lunaticBrowser.geckoWeb.saveCurrentSessionState()
|
||||
} else {
|
||||
super.onRemoteCenterClick()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRemoteCenterDoubleClick() {
|
||||
@ -253,6 +260,11 @@ class TokiFragment : RemoteGestureFragment(), PagedTextViewInterface,KeyEventHan
|
||||
} else if (contentsType.contains("comics")) {
|
||||
if (contentsType == "comics") sendViewerTouch("right") else actionNextEvent()
|
||||
}
|
||||
else if (contentsType.contains("youtube")) {
|
||||
binding.lunaticBrowser.geckoWeb.next10()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onRemoteLeft(isDouble : Boolean) {
|
||||
@ -260,6 +272,8 @@ class TokiFragment : RemoteGestureFragment(), PagedTextViewInterface,KeyEventHan
|
||||
actionPrevEvent(isDouble)
|
||||
} else if (contentsType.contains("comics")) {
|
||||
if (contentsType == "comics") sendViewerTouch("left") else actionNextEvent()
|
||||
}else if (contentsType.contains("youtube")) {
|
||||
binding.lunaticBrowser.geckoWeb.prev10()
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,12 +281,15 @@ class TokiFragment : RemoteGestureFragment(), PagedTextViewInterface,KeyEventHan
|
||||
if (binding.pagedLayer.isVisible) {
|
||||
|
||||
} else {
|
||||
if (binding.lunaticBrowser.geckoWeb.scrollState > 0) {
|
||||
|
||||
if (contentsType.contains("youtube")) {
|
||||
binding.lunaticBrowser.geckoWeb.nextShorts()
|
||||
} else {
|
||||
binding.lunaticBrowser.geckoWeb.pageDown()
|
||||
}
|
||||
if (binding.lunaticBrowser.geckoWeb.scrollState > 0) {
|
||||
|
||||
} else {
|
||||
binding.lunaticBrowser.geckoWeb.pageDown()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,10 +297,14 @@ class TokiFragment : RemoteGestureFragment(), PagedTextViewInterface,KeyEventHan
|
||||
if (binding.pagedLayer.isVisible) {
|
||||
|
||||
} else {
|
||||
if (binding.lunaticBrowser.geckoWeb.scrollState < 0) {
|
||||
|
||||
if (contentsType.contains("youtube")) {
|
||||
binding.lunaticBrowser.geckoWeb.prevShorts()
|
||||
} else {
|
||||
binding.lunaticBrowser.geckoWeb.pageUp()
|
||||
if (binding.lunaticBrowser.geckoWeb.scrollState < 0) {
|
||||
|
||||
} else {
|
||||
binding.lunaticBrowser.geckoWeb.pageUp()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -526,13 +547,17 @@ class TokiFragment : RemoteGestureFragment(), PagedTextViewInterface,KeyEventHan
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private var originalVolume: Int = -1
|
||||
private val audioManager by lazy {
|
||||
requireContext().getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
}
|
||||
override fun onHiddenChanged(hidden: Boolean) {
|
||||
super.onHiddenChanged(hidden)
|
||||
saveContinuation = false
|
||||
if (hidden) {
|
||||
// 💡 화면에서 사라질 때: 타이머 중지 및 애니메이션 중지
|
||||
binding.lunaticBrowser.geckoWeb?.onPause()
|
||||
|
||||
// 일반 WebView라면: webView.onPause() 및 webView.pauseTimers()
|
||||
} else {
|
||||
// 💡 다시 나타날 때: 다시 시작
|
||||
@ -541,6 +566,8 @@ class TokiFragment : RemoteGestureFragment(), PagedTextViewInterface,KeyEventHan
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
@ -551,7 +578,10 @@ class TokiFragment : RemoteGestureFragment(), PagedTextViewInterface,KeyEventHan
|
||||
|
||||
// 💡 1. Toki용 레이아웃 설정
|
||||
binding.lunaticBrowser.setupForToki()
|
||||
originalVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
|
||||
// 미디어 볼륨을 0으로 설정 (FLAG_SHOW_UI를 0으로 주면 볼륨 바가 뜨지 않음)
|
||||
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0)
|
||||
// 💡 2. GeckoWeb 접근 및 설정
|
||||
val geckoWeb = binding.lunaticBrowser.geckoWeb
|
||||
|
||||
@ -740,7 +770,21 @@ class TokiFragment : RemoteGestureFragment(), PagedTextViewInterface,KeyEventHan
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
originalVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
if (contentsType.contains("youtube")) {
|
||||
// 미디어 볼륨을 0으로 설정 (FLAG_SHOW_UI를 0으로 주면 볼륨 바가 뜨지 않음)
|
||||
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0)
|
||||
}
|
||||
|
||||
Blog.LOGE("RssHome 활성화: 미디어 볼륨 0 설정 (이전 볼륨: $originalVolume)")
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (originalVolume != -1 && contentsType.contains("youtube")) {
|
||||
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, originalVolume, 0)
|
||||
Blog.LOGE("RssHome 비활성화: 미디어 볼륨 복구 ($originalVolume)")
|
||||
}
|
||||
}
|
||||
|
||||
fun getLastinfo() : LastInfo? {
|
||||
@ -1013,21 +1057,7 @@ class TokiFragment : RemoteGestureFragment(), PagedTextViewInterface,KeyEventHan
|
||||
|
||||
|
||||
fun showToast(origin: String) {
|
||||
activity?.runOnUiThread {
|
||||
val toast = Toast(requireContext())
|
||||
toast.duration = Toast.LENGTH_SHORT
|
||||
val biggerText = SpannableStringBuilder(origin)
|
||||
biggerText.setSpan(RelativeSizeSpan(1.6f), 0, origin.length, 0)
|
||||
val view: View = inflate(requireContext(), R.layout.simple_toast, null)
|
||||
view.findViewById<TextView>(R.id.text).text = biggerText
|
||||
toast.view = view
|
||||
toast.show()
|
||||
// Toast.makeText(
|
||||
// baseContext,
|
||||
// biggerText,
|
||||
// Toast.LENGTH_SHORT
|
||||
// ).show()
|
||||
}
|
||||
activity?.toast(origin)
|
||||
}
|
||||
|
||||
var delayed = 3500L + Math.abs(Random.nextLong().rem(9999L))
|
||||
|
||||
@ -27,7 +27,7 @@ import android.net.NetworkCapabilities
|
||||
import android.net.NetworkRequest
|
||||
import android.os.*
|
||||
import androidx.annotation.RequiresApi
|
||||
import bums.lunatic.launcher.home.toast
|
||||
import bums.lunatic.launcher.LunaticLauncher.Companion.toast
|
||||
import bums.lunatic.launcher.utils.Blog
|
||||
import com.frostwire.jlibtorrent.swig.error_code
|
||||
import com.frostwire.jlibtorrent.swig.libtorrent
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user