diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b4c9a6a1..55982c4a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -100,6 +100,7 @@
+
@@ -130,14 +131,14 @@
-
-
-
-
-
-
+
-
+
diff --git a/app/src/main/assets/extensions/my_extension/messaging.js b/app/src/main/assets/extensions/my_extension/messaging.js
index c8099bdc..3e092ce3 100644
--- a/app/src/main/assets/extensions/my_extension/messaging.js
+++ b/app/src/main/assets/extensions/my_extension/messaging.js
@@ -5,6 +5,27 @@ port.onMessage.addListener(response => {
var type= response["type"];
switch (type) {
+ case "search" : {
+ var keyword = response["keyword"];
+ if (location.href.search("bigkinds.or.kr") > -1) {
+ document.querySelector('input[id^="total-search-key"]').value = keyword
+ } else if (location.href.search("www.google") > -1) {
+ document.querySelector('form[action^="/search"]').querySelector("textarea").value = keyword
+ } else if(location.href.search("naver.com") > -1) {
+ document.querySelector('input[id^="query"]').value = keyword
+ } else if(location.href.search("namu.wiki") > -1) {
+ document.querySelector('input[type^="search"]').value = keyword
+ }
+ }
+ case "searchDo" : {
+ if (location.href.search("bigkinds.or.kr") > -1) {
+ document.querySelector('a[class^="bk_keywordSearchBtn"]').click()
+ } else if (location.href.search("www.google") > -1) {
+ document.querySelector('form[action^="/search"]').submit()
+ } else if(location.href.search("naver.com") > -1) {
+ document.querySelector('[class^="sch_btn_search"]').click()
+ }
+ }
case "getList": {
try {
// var listBody = null
@@ -39,6 +60,7 @@ port.onMessage.addListener(response => {
}break;
case "scrollDown":{
+ autoScrollAndSave()
var max = response["max"]
var current = response["current"]
var isUpDown = response["isUpDown"]
@@ -74,7 +96,7 @@ port.onMessage.addListener(response => {
}
break;
case "saveContent":{
- scrollToLazyImg()
+ scrollToLazyImg(true === response["fast"])
}
default:
port.postMessage(`Received: ${JSON.stringify(response)}`);
@@ -235,12 +257,12 @@ document.addEventListener('DOMContentLoaded', function () {
})
-function scrollToLazyImg() {
+function scrollToLazyImg(fastMode) {
(function(autoScrollAndSave){
// 한 번에 이동할 픽셀
- const step = 200;
+ const step = fastMode ? 600 : 200;
// 반복 간격(ms) (느릴수록 로딩에 더 여유 생김)
- const delay = 600;
+ const delay = fastMode ? 200 : 600;
// 스크롤 현재 위치 추적
let currentY = window.scrollY;
let maxY = Math.max(
@@ -322,357 +344,62 @@ function isNewerThanOneDay(dateStr) {
return (now - date) < oneDayMs;
}
function autoScrollAndSave(senContents) {
- if (location.href.search("nate.com") > -1 && document.querySelectorAll("#ad_sponsorBar")) {
- if (location.href.startsWith("https://news.nate.com")) {
- var string = location.href.toString()
- string = string.replace("https://","https://m.");
- location.href = string
- }
- document.querySelectorAll('[class^="float-adv-wrap"]').forEach(e => e.remove())
- document.querySelectorAll('[id^="ad_"]').forEach(e => e.remove())
- document.querySelectorAll("#ad_sponsorBar").forEach((element) => {element.remove();});
- document.querySelectorAll("#newsSidebar").forEach((element) => {element.remove();});
- document.querySelectorAll("#header").forEach((element) => {element.remove();});
- document.querySelectorAll('iframe[id^="ad"]').forEach(e => e.remove())
- document.querySelectorAll("#module_ssul").forEach((element) => {element.remove();});
- document.querySelectorAll('[class^="boxtype1 thisTimeNews"]').forEach(e => e.remove())
- document.querySelectorAll("#mediaFooter").forEach((element) => {element.remove();});
- document.querySelectorAll('[class^="news_cmt"]').forEach(e => e.remove())
- document.querySelectorAll('section[class^="rwd_right"]').forEach(e => e.remove())
+ // 도메인에 맞는 handler 실행
+ const matchedRule = domainRules.find(rule => rule.test(location.href));
+ if (matchedRule) {
+ matchedRule.handler();
+ }
+ // 공통 광고 요소 제거는 항상 실행
+ handleCommon();
+ window.scrollTo({ top: 2, behavior: 'smooth' });
+ if (mainContentsEl == null) {
+ mainContentsEl = document.body.outerHTML
+ }
+ if (senContents) {
+ sendMessage({type: "MainContentsEl", contents: mainContentsEl.outerHTML, currentPage: location.href});
+ }
+}
- }
+// 도메인 규칙 배열
+const domainRules = [
+ { test: url => url.includes("nate.com") && document.querySelectorAll("#ad_sponsorBar").length > 0, handler: handleNate },
+ { test: url => url.includes("zdnet.co.kr"), handler: handleZdnet },
+ { test: url => url.includes("inews24"), handler: handleInews24 },
+ { test: url => url.includes("starnewskorea"), handler: handleStarnewsKorea },
+ { test: url => url.includes("khan.co.kr"), handler: handleKhan },
+ { test: url => url.includes("m.health.chosun.com"), handler: handleHealthChosun },
+ { test: url => url.includes("betanews"), handler: handleBetanews },
+ { test: url => url.includes("newsis.com"), handler: handleNewsis },
+ { test: url => url.includes("seoul.co.kr"), handler: handleSeoul },
+ { test: url => url.includes("ytn.co.kr"), handler: handleYtn },
+ { test: url => url.includes("nocutnews.co.kr"), handler: handleNocutnews },
+ { test: url => url.includes("sedaily.com"), handler: handleSedaily },
+ { test: url => url.includes("digitaltoday"), handler: handleDigitaltoday },
+ { test: url => url.includes("kormedi"), handler: handleKormedi },
+ { test: url => url.includes("chosun.com"), handler: handleChosun },
+ { test: url => url.includes("traveltimes"), handler: handleTraveltimes },
+ { test: url => url.includes("theqoo.net") && document.querySelectorAll('[class^="m-list m-element"]').length > 0, handler: handleTheqoo },
+ { test: url => url.includes("doctorsnews"), handler: handleDoctorsnews },
+ { test: url => url.includes("dcinside.com") && document.querySelectorAll('[class^="container"]').length > 0, handler: handleDcinside },
+ { test: url => url.includes("fmkorea.com") && document.querySelectorAll('[class^="bd bd_mobile"]').length > 0, handler: handleFmkorea },
+ { test: url => url.includes("torrentzota"), handler: handleToreentZota},
+ { test: url => url.includes("acrofan.com") && document.querySelectorAll('[id^="wide"]').length > 0, handler: handleAcrofan },
+ { test: url => url.includes("yna.co.kr") && document.querySelectorAll('[class^="wrapper"]').length > 0, handler: handleYna },
+ { test: url => url.includes("clien") && document.querySelectorAll('[class^="content_view"]').length > 0, handler: handleClien },
+ { test: url => url.includes("toki") && (document.querySelectorAll('[id^="id_mbv"]').length > 0 || document.querySelectorAll('[class^="basic-banner"]').length > 0), handler: handleToki },
+];
- if (location.href.search("khan.co.kr") > -1) {
- document.querySelectorAll('[class^="banner-"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="google-auto-placed"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="relationList"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="reporter_news"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="box"]').forEach(e => e.remove())
- document.querySelectorAll('footer').forEach(e => e.remove())
- document.querySelectorAll('iframe').forEach(e => e.remove())
- document.querySelectorAll('[class^="bottom-wrap"]').forEach(e => e.remove())
- document.querySelectorAll('aside[class^="list-wrap"]').forEach(e => e.remove())
- document.querySelectorAll('div[style^="width:100%;height:250px;text-align:center;margin-bottom:20px;overflow:hidden;"]').forEach(e => e.remove())
+function handleCommon() {
+ // 공통 광고 제거
+ 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();
-
- }
- if (location.href.search("betanews") > -1) {
- document.querySelectorAll('[class^="banner"]').forEach(e => e.remove())
- document.querySelectorAll('aside[class^="list-wrap"]').forEach(e => e.remove())
- document.querySelectorAll('section[class^="bottom"]').forEach(e => e.remove())
- document.querySelectorAll('footer').forEach(e => e.remove())
- }
- if (location.href.search("newsis.com") > -1) {
- document.querySelectorAll('div[style^="width: 300px; margin: 0 auto 25px;"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="listStyle"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="headtopBanner"]').forEach(e => e.remove())
- document.querySelectorAll('div[id^="ad_"]').forEach(e => e.remove())
- document.querySelectorAll('div[id^="adbay"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="article"]').forEach(function (e) {
- e.querySelectorAll("iframe").forEach(e => e.remove())
- })
- document.querySelectorAll('div[class^="Float"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="bxcn"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="A1"]').forEach(e => e.remove())
- document.querySelectorAll('div[id^="news_body_end"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="linkNews"]').forEach(e => e.remove())
- document.querySelectorAll('div[id^="footer"]').forEach(e => e.remove())
- }
-
- if (location.href.search("seoul.co.kr") > -1) {
- document.querySelectorAll('div[class^="rowAd"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="ad"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="articleBottomNews"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="sub-layoutBorder"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="m-sectionLayout"]').forEach(e => e.remove())
- document.querySelectorAll('[id^="rollingAdDiv"]').forEach(e => e.remove())
- document.querySelectorAll('footer').forEach(e => e.remove())
- document.querySelectorAll('[class^="banner"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="joinPopup"]').forEach(e => e.remove())
- }
-
-
- if (location.href.search("ytn.co.kr") > -1) {
-
- document.querySelectorAll('div[class^="footer"]').forEach(e => e.remove())
- document.querySelectorAll('div[style^="width: 100%; background-color: rgb(255, 255, 255); display: flex; justify-content: center;"]').forEach(e => e.remove())
- document.querySelectorAll('div[style^="width:100%"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="ad_"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="bx_hot"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="bx_ad"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="bx_pro"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="bx_main"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="bx_sns"]').forEach(e => e.remove())
- document.querySelectorAll('div[id^="popularArea"]').forEach(e => e.remove())
- }
- if (location.href.search("nocutnews.co.kr")> -1) {
- document.querySelectorAll('div[style^="width:300px; margin:0 auto 25px;"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="ct2"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="footer"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="con_b"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="v_like"]').forEach(e => e.remove())
- document.querySelectorAll('div[id^="divCommonRelated"]').forEach(e => e.remove())
- document.querySelectorAll('iframe').forEach(e => e.remove())
- }
- if (location.href.search("sedaily.com") > -1) {
- document.querySelectorAll('div[class^="article"]').forEach(function (e) {
- e.querySelectorAll("iframe").forEach(e => e.remove())
- })
- document.querySelectorAll('div[class^="banner"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^=" banner"]').forEach(e => e.remove())
- document.querySelectorAll('div[class^="col-right"]').forEach(e => e.remove())
- document.querySelectorAll('footer[class^="footer"]').forEach(e => e.remove())
- }
- if (location.href.search("digitaltoday") > -1) {
- document.querySelectorAll('[class^="aedi"]').forEach(e => e.remove())
- document.querySelectorAll('[id^="layer-popups"]').forEach(e => e.remove())
- document.querySelectorAll('[id^="enters"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="view-toast"]').forEach(e => e.remove())
- document.querySelectorAll('footer[id^="user"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="clearfix"]').forEach(e => e.remove())
- document.querySelectorAll('[id^="bottom-sticky"]').forEach(e => e.remove())
-
- if (location.href.search("kormedi") > -1) {
- document.querySelectorAll('[class^="entry-content-after"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="code-block"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="post-featured"]').forEach(e => e.remove())
- document.querySelectorAll('footer[class^="cs"]').forEach(e => e.remove())
- document.querySelectorAll('ins[class^="adsbygoogle"]').forEach(e => e.remove())
-
- }
- }
-
- if (location.href.search("chosun.com") > -1) {
- document.querySelectorAll('[class^="arcad-wrapper"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="flex-chain-wrapper"]').forEach(e => e.remove())
- document.querySelectorAll('footer[class^="layout"]').forEach(e => e.remove())
- document.querySelectorAll('aside[class^="layout"]').forEach(e => e.remove())
- document.querySelectorAll('ins').forEach(e => e.remove())
- }
- if (location.href.search("traveltimes") > -1) {
- document.querySelectorAll('ins').forEach(e => e.remove())
- document.querySelectorAll('[class^="teads"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="tdn"]').forEach(e => e.remove())
- document.querySelectorAll('aside[class^="grid"]').forEach(e => e.remove())
- document.querySelectorAll('footer[id^="user"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="clearfix"]').forEach(e => e.remove())
- }
- if (location.href.search("theqoo.net") > -1 && document.querySelectorAll('[class^="m-list m-element"]')) {
- document.querySelectorAll('[class^="m-list m-element"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="button_area"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="board_content_google_ad"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="clearfix list-header"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="clearfix list-footer"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="main-footer"]').forEach(e => e.remove())
- document.querySelectorAll('ins[class^="adsbygoogle"]').forEach(e => e.remove())
- mainContentsEl = document.querySelector('div[id="grid-content"]')
- }
- if(location.href.search("doctorsnews") > -1) {
- document.querySelectorAll('[class^="clearfix"]').forEach(e => e.remove())
- document.querySelectorAll('aside').forEach(e => e.remove())
- document.querySelectorAll('[class^="banner_"]').forEach(e => e.remove())
- }
- if (location.href.search("dcinside.com") > -1 && document.querySelectorAll('[class^="container"]')) {
- document.querySelectorAll('[id^="view_btn_area"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="trend-rank"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="view-btm-con"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="md-tit-box"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="gall-detail-lst"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="outside-search-box"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="footer ftlong"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="adv-group"]').forEach(e => e.remove())
- document.querySelectorAll('li[style^="cursor:default;"]').forEach(e => e.remove())
- mainContentsEl = document.querySelector('div[class="container"]')
- }
-
- if (location.href.search("fmkorea.com") > -1 && document.querySelectorAll('[class^="bd bd_mobile"]')) {
- document.querySelectorAll('[class^="fmad_wrapper fmad_naver_power_link"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="ad ad_wrapper"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="bd_lst_wrp"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="m_top_hotdeal"]').forEach(e => e.remove())
- document.querySelectorAll('[style^="margin-top:2px;line-height:0;"]').forEach(e => e.remove())
- mainContentsEl = document.querySelector('div[class="bd bd_mobile"]')
- }
-
- if (location.hostname.search("acrofan.com") > -1 && document.querySelectorAll('[id^="wide"]')) {
- document.querySelectorAll('[class^="header"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="footer"]').forEach(e => e.remove())
- document.querySelectorAll('[id^="tabmenu"]').forEach(e => e.remove())
- mainContentsEl = document.querySelector('div[class="wide"]')
- }
-
- if (location.hostname.search("yna.co.kr") > -1 && document.querySelectorAll('[class^="wrapper"]')) {
- document.querySelectorAll('[class^="aside-box426 sticky"]').forEach(e => e.remove())
- document.querySelectorAll('aside[class^="aside-box"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="section02"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="content03 wide"]').forEach(e => e.remove())
- document.querySelectorAll('[id="footer"]').forEach(e => e.remove())
- mainContentsEl = document.querySelector('div[id="container"]')
- }
-
- if (location.hostname.search("clien") > -1 && document.querySelectorAll('[class^="content_view"]')) {
- document.querySelectorAll('[class^="view_top"]').forEach(e => e.remove())
- document.querySelectorAll('[id^="naverAd"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="content_view_list"]').forEach(e => e.remove())
- document.querySelectorAll('[class^="footer_wrap"]').forEach(e => e.remove())
- mainContentsEl = document.querySelector('div[id="content_view"]')
- }
-
- if (location.hostname.search("toki") > -1 && document.querySelectorAll('[id^="id_mbv"]')) {
- document.querySelectorAll('[id^="id_mbv"]').forEach(e => e.remove())
- }
- if (location.hostname.search("toki") > -1 && document.querySelectorAll('[class^="basic-banner"]')) {
- document.querySelectorAll('[class^="basic-banner"]').forEach(e => e.remove())
- }
- if (document.querySelector(".top_google_ad_space")) {
- document.querySelector(".top_google_ad_space").remove()
- }
- if (document.querySelectorAll(".adv-group")) {
- document.querySelectorAll(".adv-group").forEach(e =>
- e.remove()
- )
- }
- if (document.querySelectorAll('[id^="div-gpt-ad"]')) {
- document.querySelectorAll('[id^="div-gpt-ad"]').forEach(e =>
- e.remove()
- )
- }
- if (document.location.href.search("reddit") > -1) {
- if (document.querySelector('#xpromo-bottom-sheet')) {
- document.querySelector('#xpromo-bottom-sheet').remove()
- }
- }
- if (document.querySelectorAll('[id^="div_adnmore_area"]')) {
- document.querySelectorAll('[id^="div_adnmore_area"]').forEach(e =>
- e.remove()
- )
- }
- if (document.querySelectorAll('[id^="div_adnmore_area"]')) {
- document.querySelectorAll('[id^="div_adnmore_area"]').forEach(e =>
- e.remove()
- )
- }
- if (document.querySelectorAll('[class^="adv-groupno"]')) {
- document.querySelectorAll('[class^="adv-groupno"]').forEach(e =>
- e.remove()
- )
- }
- if (document.querySelectorAll('[class^="code-block"]')) {
- document.querySelectorAll('[class^="code-block"]').forEach(e => e.remove())
- }
- if (document.querySelectorAll('.ad-template')) {
- document.querySelectorAll('.ad-template').forEach(function (e) {
- e.remove()
- })
- }
- if (location.href.search("arca.live") > -1 && document.querySelectorAll('[class^="vrow hybrid"]')) {
- const tempArray = [];
- document.querySelectorAll('[class^="vrow hybrid"]').forEach(function (aracaLi) {
- if (aracaLi.innerHTML.search("title ") > -1) {
- // title.hybrid-title 클래스가 붙은 첫 번째 요소 텍스트 추출
- let titleEl = aracaLi.querySelector('.title.hybrid-title');
- let title = titleEl ? titleEl.textContent.trim() : '';
-
- // badge 클래스 텍스트와 user-info 클래스 텍스트 합치기
- let descBadge = aracaLi.querySelector('.badge');
- let descUserInfo = aracaLi.querySelector('.user-info');
- let desc = (descBadge ? descBadge.textContent.trim() : '')
- if (desc.length > 0) {
- desc = desc + ","
- }
- desc = desc + (descUserInfo ? descUserInfo.textContent.trim() : '');
- if (descUserInfo) {
- desc = desc + ","
- }
-
- // time 태그 datetime 속성 값
- let timeEl = aracaLi.querySelector('time');
-
- let dateTime = timeEl ? timeEl.getAttribute('datetime') : '';
- // console.log("dateTime >>> "+ dateTime)
- // const dateObj = new Date(dateTime);
- // console.log(dateObj.getFullYear()); // 2025
- // console.log(dateObj.getMonth() + 1); // 7 (월은 0부터 시작하므로 +1)
- // console.log(dateObj.getDate()); // 30
- // console.log(dateObj.getHours()); // 13 (현지 시간 기준)
- // console.log(dateObj.getMinutes()); // 45
- // console.log(dateObj.getSeconds());
- // console.log(dateObj);
- // img 태그 src 값
- let imgEl = aracaLi.querySelector('img');
- let thumbnail = imgEl ? imgEl.getAttribute('src') : '';
-
- // 링크 만들기
- let link = 'https://arca.live';
- if (titleEl && titleEl.getAttribute('href')) {
- link += titleEl.getAttribute('href');
- } else {
- let aEl = aracaLi.querySelector('a');
- if (aEl && aEl.getAttribute('href')) {
- link += aEl.getAttribute('href');
- }
- }
-
- if (title.length > 0 && link.length > 20) {
- // thumbnail 절대경로 처리 (프로토콜이 없는 경우 https: 붙이기)
- if (thumbnail.startsWith('//')) {
- thumbnail = 'https:' + thumbnail;
- }
-
- // 날짜가 하루 이내인지 확인하는 함수 사용
-
- tempArray.push({
- title: title.replace(/\s+/g, ' ').trim(),
- description: desc.replace(/\s+/g, ' ').trim() + "ARCA",
- pubDate: new Date(dateTime).getTime(),
- originPage: link,
- "category": "ARCA",
- thumbnail: thumbnail
- });
-
- }
- }
-
- })
- if (tempArray.length > 0) {
- console.log(tempArray);
- sendMessage(
- {
- type: "PRIVATES",
- privates: tempArray,
- currentPage: location.href
- }
- );
- location.href = "about:blank;"
- }
- }
- if (document.querySelectorAll('[class^="popupBanner_w popupOpen"]')) {
- document.querySelectorAll('[class^="popupBanner_w popupOpen"]').forEach(function (e) {
- e.remove()
- })
- }
-
- if (document.querySelectorAll('iframe')) {
- document.querySelectorAll('iframe').forEach(function (e) {
- if (e.getAttribute("src") != null && (e.getAttribute("src").search("ads") > -1 || e.getAttribute("src").search("coupang") > -1)) {
- e.remove()
- }
- })
- }
- if (location.href.search("x.com") > -1) {
- var mainClass = document.querySelector('section').className
-
- document.querySelector('section').querySelectorAll('div[class="' + mainClass + '"]').forEach(function (e) {
- if (e.hasAttribute("data-testid") && e.querySelector('video')) {
- e.querySelectorAll('[poster]').forEach(function (e) {
-
- })
- console.log(e.innerHTML)
- }
- })
-
- }
+ document.querySelectorAll('iframe').forEach(e => {
+ const src = e.getAttribute("src");
+ if (src != null && (src.includes("ads") || src.includes("coupang"))) e.remove();
+ });
if (document.querySelectorAll('[data-banner^="coupang-"]')) {
document.querySelectorAll('[data-banner^="coupang-"]').forEach(e => e.remove())
@@ -690,6 +417,127 @@ function autoScrollAndSave(senContents) {
if (document.querySelectorAll('[class^="science-banner-area"]')) {
document.querySelectorAll('[class^="science-banner-area"]').forEach(e => e.remove())
}
+
+
+ if (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 {
+ const dateString = e.querySelector('[class^="mb-2"]').querySelector("a").textContent.trim();
+
+ const [day, month, year] = dateString.split("/").map(Number);
+ date = new Date(year, month - 1, day).getTime();
+ } catch (e) {
+
+ }
+ var actor = ""
+ try {
+ actor = e.querySelector('[class^="mb-1"]').getAttribute("alt").trim()
+ } catch (e) {
+
+ }
+ var desc = ""
+ try {
+ e.querySelectorAll('[class^="badge badge-"]').forEach(function (e) {
+ try {
+ if (Number(e.textContent) > 0) {
+
+ } else {
+ if (desc.length > 0) {
+ desc += ","
+ }
+ desc += e.textContent.trim()
+ }
+ } catch (e) {
+ }
+ }
+ )
+ } catch (e) {
+
+ }
+ var thumb = ""
+ try {
+ thumb = e.querySelector("td").querySelector("a").getAttribute('data-link')
+ try {
+ var sets = e.querySelector("td").querySelector("img").getAttribute('srcset')
+ if (sets.search(",") > -1) {
+ var srcSet = sets.split(",")
+ var newT = srcSet[srcSet.length - 1]
+ if (newT != null && newT.length > 5) {
+ thumb = newT
+ }
+ }
+ } catch (e) {
+ }
+ } catch (e) {
+ }
+ var magnet = ""
+ try {
+ e.querySelectorAll("td").forEach(function (e) {
+ e.querySelectorAll("a").forEach(function (e) {
+ if (e.getAttribute("href").startsWith("magnet")) {
+ magnet = e.getAttribute("href").replaceAll("&", "&");
+ }
+ })
+ })
+ } catch (e) {
+
+ }
+
+ var title = "";
+ try {
+ e.querySelector(".name").querySelector("a").querySelectorAll("span").forEach(function (e) {
+ if (e.hasAttribute("class") == false) {
+ title = e.textContent.trim();
+ }
+ })
+ } catch (e) {
+
+ }
+ var originPage = ""
+ try {
+ originPage = location.protocol + "//" + location.hostname + e.querySelector(".name").querySelector("a").getAttribute("href");
+ } catch (e) {
+
+ }
+ var screenshots = ""
+ try {
+ e.querySelectorAll("a").forEach(function (e) {
+ if (e.getAttribute("href").search("screenshots") > -1) {
+ screenshots = e.getAttribute("href");
+ }
+ })
+ } catch (e) {
+
+ }
+ if (thumb.length > 0 || screenshots.length > 0) {
+ }
+ datas.push({
+ "title": title,
+ "description": desc,
+ "originPage": originPage,
+ "magnet_link": magnet,
+ "thumbnail": thumb,
+ "pubDate": date,
+ "screenshotsUrl": screenshots,
+ "chosung": "",
+ "category": "PRIVATE"
+ });
+ })
+ sendMessage(
+ {
+ type: "PRIVATES",
+ privates: datas,
+ currentPage: location.href
+ }
+ );
+
+ gotoNext()
+ }
+ window.scrollTo({ top: 2, behavior: 'smooth' });
+}
+function handleToreentZota() {
if (location.href.search("torrentzota") > -1 && document.querySelectorAll('a')) {
document.querySelectorAll('a').forEach(function (e) {
if (e.getAttribute('href') != null && e.getAttribute('href').startsWith("/adver-")) {
@@ -812,125 +660,122 @@ function autoScrollAndSave(senContents) {
}
}
-
- if (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 {
- const dateString = e.querySelector('[class^="mb-2"]').querySelector("a").textContent.trim();
-
- const [day, month, year] = dateString.split("/").map(Number);
- date = new Date(year, month - 1, day).getTime();
- } catch (e) {
-
- }
- var actor = ""
- try {
- actor = e.querySelector('[class^="mb-1"]').getAttribute("alt").trim()
- } catch (e) {
-
- }
- var desc = ""
- try {
- e.querySelectorAll('[class^="badge badge-"]').forEach(function (e) {
- try {
- if (Number(e.textContent) > 0) {
-
- } else {
- if (desc.length > 0) {
- desc += ","
- }
- desc += e.textContent.trim()
- }
- } catch (e) {
- }
- }
- )
- } catch (e) {
-
- }
- var thumb = ""
- try {
- thumb = e.querySelector("td").querySelector("a").getAttribute('data-link')
- try {
- var sets = e.querySelector("td").querySelector("img").getAttribute('srcset')
- if (sets.search(",") > -1) {
- var srcSet = sets.split(",")
- var newT = srcSet[srcSet.length - 1]
- if (newT != null && newT.length > 5) {
- thumb = newT
- }
- }
- } catch (e) {
- }
- } catch (e) {
- }
- var magnet = ""
- try {
- e.querySelectorAll("td").forEach(function (e) {
- e.querySelectorAll("a").forEach(function (e) {
- if (e.getAttribute("href").startsWith("magnet")) {
- magnet = e.getAttribute("href").replaceAll("&", "&");
- }
- })
- })
- } catch (e) {
-
- }
-
- var title = "";
- try {
- e.querySelector(".name").querySelector("a").querySelectorAll("span").forEach(function (e) {
- if (e.hasAttribute("class") == false) {
- title = e.textContent.trim();
- }
- })
- } catch (e) {
-
- }
- var originPage = ""
- try {
- originPage = location.protocol + "//" + location.hostname + e.querySelector(".name").querySelector("a").getAttribute("href");
- } catch (e) {
-
- }
- var screenshots = ""
- try {
- e.querySelectorAll("a").forEach(function (e) {
- if (e.getAttribute("href").search("screenshots") > -1) {
- screenshots = e.getAttribute("href");
- }
- })
- } catch (e) {
-
- }
- if (thumb.length > 0 || screenshots.length > 0) {
- }
- datas.push({
- "title": title,
- "description": desc,
- "originPage": originPage,
- "magnet_link": magnet,
- "thumbnail": thumb,
- "pubDate": date,
- "screenshotsUrl": screenshots,
- "chosung": "",
- "category": "PRIVATE"
- });
- })
- sendMessage(
- {
- type: "PRIVATES",
- privates: datas,
- currentPage: location.href
- }
- );
-
- gotoNext()
- }
- window.scrollTo({ top: 2, behavior: 'smooth' });
- if (senContents) {
- sendMessage({type: "MainContentsEl", contents: mainContentsEl.outerHTML, currentPage: location.href});
+}
+// 도메인별 처리 함수 모음
+function handleNate() {
+ if (location.href.startsWith("https://news.nate.com")) {
+ location.href = location.href.replace("https://", "https://m.");
}
+ document.querySelectorAll('[class^="float-adv-wrap"]').forEach(e => e.remove());
+ document.querySelectorAll('[id^="ad_"]').forEach(e => e.remove());
+ document.querySelectorAll("#ad_sponsorBar, #newsSidebar, #header, #module_ssul, #mediaFooter").forEach(e => e.remove());
+ document.querySelectorAll('iframe[id^="ad"]').forEach(e => e.remove());
+ document.querySelectorAll('[class^="boxtype1 thisTimeNews"], [class^="news_cmt"], section[class^="rwd_right"]').forEach(e => e.remove());
+}
+
+function handleZdnet() {
+ document.querySelectorAll('div[id*="FloatCon"]').forEach(e => e.remove());
+}
+
+function handleInews24() {
+ document.querySelectorAll('ad[alt^="a"], div[class^="topnews"], form[class^="talkplus"], form[class^="timeline"], form[class^="photo"], ins[class^="adsbygoogle"], footer[class^="footer"], ad, footer').forEach(e => e.remove());
+}
+
+function handleStarnewsKorea() {
+ document.querySelectorAll('div[class^="floating-top-ad"], div[class^="fixed bottom"], section[class^="mt-4"], div[id^="dablewidget_"], footer[class^="footer"]').forEach(e => e.remove());
+}
+
+function handleKhan() {
+ document.querySelectorAll('[class^="banner-"], [class^="google-auto-placed"], [class^="relationList"], [class^="reporter_news"], [class^="box"], footer, iframe, [class^="bottom-wrap"], aside[class^="list-wrap"], div[style^="width:100%;height:250px"]').forEach(e => e.remove());
+}
+
+function handleHealthChosun() {
+ document.querySelectorAll('ins, iframe, footer, div[class^="google-"], div[id^="banner-"], section[class^="hranking"], section[class^="related-articles"], div[class^="separator-container"], div[class^="raw-html"]').forEach(e => e.remove());
+ mainContentsEl = document.querySelectorAll('article[class^="layout_"]');
+}
+
+function handleBetanews() {
+ document.querySelectorAll('[class^="banner"], aside[class^="list-wrap"], section[class^="bottom"], footer').forEach(e => e.remove());
+}
+
+function handleNewsis() {
+ document.querySelectorAll('div[style^="width: 300px; margin: 0 auto 25px;"], div[class^="listStyle"], div[class^="headtopBanner"], div[id^="ad_"], div[id^="adbay"], div[class^="article"], div[class^="Float"], div[class^="bxcn"], div[class^="A1"], div[id^="news_body_end"], div[class^="linkNews"], div[id^="footer"]').forEach(e => e.remove());
+ document.querySelectorAll('div[class^="article"]').forEach(e => e.querySelectorAll("iframe").forEach(i => i.remove()));
+}
+
+function handleSeoul() {
+ document.querySelectorAll('div[class^="rowAd"], div[class^="ad"], [class^="articleBottomNews"], [class^="sub-layoutBorder"], [class^="m-sectionLayout"], [id^="rollingAdDiv"], footer, [class^="banner"], [class^="joinPopup"]').forEach(e => e.remove());
+}
+
+function handleYtn() {
+ document.querySelectorAll(
+ 'div[class^="footer"], div[style^="width: 100%; background-color: rgb(255, 255, 255); display: flex; justify-content: center;"], div[style^="width:100%"], ' +
+ 'div[class^="ad_"], div[class^="bx_hot"], div[class^="bx_ad"], div[class^="bx_pro"], div[class^="bx_main"], div[class^="bx_sns"], div[id^="popularArea"]'
+ ).forEach(e => e.remove());
+}
+
+function handleNocutnews() {
+ document.querySelectorAll('div[style^="width:300px; margin:0 auto 25px;"], div[class^="ct2"], div[class^="footer"], div[class^="con_b"], div[class^="v_like"], div[id^="divCommonRelated"], iframe').forEach(e => e.remove());
+}
+
+function handleSedaily() {
+ document.querySelectorAll('div[class^="article"]').forEach(e => e.querySelectorAll("iframe").forEach(i => i.remove()));
+ document.querySelectorAll('div[class^="banner"], div[class^=" banner"], div[class^="col-right"], footer[class^="footer"]').forEach(e => e.remove());
+}
+
+function handleDigitaltoday() {
+ document.querySelectorAll('[class^="aedi"], [id^="layer-popups"], [id^="enters"], [class^="view-toast"], footer[id^="user"], [class^="clearfix"], [id^="bottom-sticky"]').forEach(e => e.remove());
+}
+
+function handleKormedi() {
+ document.querySelectorAll('[class^="entry-content-after"], [class^="code-block"], [class^="post-featured"], footer[class^="cs"], ins[class^="adsbygoogle"]').forEach(e => e.remove());
+}
+
+function handleChosun() {
+ document.querySelectorAll('[class^="arcad-wrapper"], [class^="flex-chain-wrapper"], footer[class^="layout"], aside[class^="layout"], ins, div[id^="paywallCont"], div[class^="paywall--bg"]').forEach(e => e.remove());
+}
+
+function handleTraveltimes() {
+ document.querySelectorAll('ins, [class^="teads"], [class^="tdn"], aside[class^="grid"], footer[id^="user"], [class^="clearfix"]').forEach(e => e.remove());
+}
+
+function handleTheqoo() {
+ document.querySelectorAll('[class^="m-list m-element"], [class^="button_area"], [class^="board_content_google_ad"], [class^="clearfix list-header"], [class^="clearfix list-footer"], [class^="main-footer"], ins[class^="adsbygoogle"]').forEach(e => e.remove());
+ mainContentsEl = document.querySelector('div[id="grid-content"]');
+}
+
+function handleDoctorsnews() {
+ document.querySelectorAll('[class^="clearfix"], aside, [class^="banner_"]').forEach(e => e.remove());
+}
+
+function handleDcinside() {
+ document.querySelectorAll(
+ '[id^="view_btn_area"], [class^="trend-rank"], [class^="view-btm-con"], [class^="md-tit-box"], [class^="gall-detail-lst"], [class^="outside-search-box"], [class^="footer ftlong"], [class^="adv-group"], li[style^="cursor:default;"], [id^="div_adnmore_area"]'
+ ).forEach(e => e.remove());
+ document.querySelectorAll('div[class="container"]').forEach(e => e.remove()); // just in case
+ mainContentsEl = document.querySelector('div[class="container"]');
+}
+
+function handleFmkorea() {
+ document.querySelectorAll('[class^="fmad_wrapper fmad_naver_power_link"], [class^="ad ad_wrapper"], [class^="bd_lst_wrp"], [class^="m_top_hotdeal"], [style^="margin-top:2px;line-height:0;"]').forEach(e => e.remove());
+ mainContentsEl = document.querySelector('div[class="bd bd_mobile"]');
+}
+
+function handleAcrofan() {
+ document.querySelectorAll('[class^="header"], [class^="footer"], [id^="tabmenu"]').forEach(e => e.remove());
+ mainContentsEl = document.querySelector('div[class="wide"]');
+}
+
+function handleYna() {
+ document.querySelectorAll('[class^="aside-box426 sticky"], aside[class^="aside-box"], [class^="section02"], [class^="content03 wide"], [id="footer"]').forEach(e => e.remove());
+ mainContentsEl = document.querySelector('div[id="container"]');
+}
+
+function handleClien() {
+ document.querySelectorAll('[class^="view_top"], [id^="naverAd"], [class^="content_view_list"], [class^="footer_wrap"]').forEach(e => e.remove());
+ mainContentsEl = document.querySelector('div[id="content_view"]');
+}
+
+function handleToki() {
+ document.querySelectorAll('[id^="id_mbv"], [class^="basic-banner"]').forEach(e => e.remove());
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/bums/lunatic/launcher/LauncherActivity.kt b/app/src/main/kotlin/bums/lunatic/launcher/LauncherActivity.kt
index 5331bc6d..7ce4c0da 100644
--- a/app/src/main/kotlin/bums/lunatic/launcher/LauncherActivity.kt
+++ b/app/src/main/kotlin/bums/lunatic/launcher/LauncherActivity.kt
@@ -79,6 +79,8 @@ import bums.lunatic.launcher.home.RssViewBuilder
import bums.lunatic.launcher.model.RssData
import bums.lunatic.launcher.model.RssDataType
import bums.lunatic.launcher.tokiz.Comics
+import bums.lunatic.launcher.tokiz.Magnet
+import bums.lunatic.launcher.tokiz.Perplexity
import bums.lunatic.launcher.tokiz.Twitter
import bums.lunatic.launcher.tokiz.Webtoons
import bums.lunatic.launcher.tokiz.Zota
@@ -518,15 +520,6 @@ internal class LauncherActivity : CommonActivity() {
binding.tabs.setOnCheckedChangeListener { g, id ->
showContents(id)
}
- binding.hidden.setOnLongClickListener {
- supportFragmentManager.beginTransaction()
- .replace(R.id.fragment_container, RssHome().apply {
- arguments = Bundle().apply {
- putBoolean("HIDDEN", true)
- }}
- ).commit()
- true
- }
/* handle navigation back events */
handleBackPress()
@@ -559,6 +552,11 @@ internal class LauncherActivity : CommonActivity() {
.replace(R.id.fragment_container, Comics())
.commit()
}
+ R.id.perplexity ->{
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.fragment_container, Perplexity())
+ .commit()
+ }
R.id.zota ->{
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, Zota())
@@ -569,6 +567,11 @@ internal class LauncherActivity : CommonActivity() {
.replace(R.id.fragment_container, Twitter())
.commit()
}
+ R.id.magnet ->{
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.fragment_container, Magnet())
+ .commit()
+ }
else -> {}
}
}
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 2437beee..9c5bcefa 100644
--- a/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt
+++ b/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt
@@ -75,7 +75,10 @@ class GeckoWeb : BWebview {
super.setVisibility(visibility)
decoViews.forEach { it.visibility = visibility }
}
-
+ interface OnSave {
+ fun saved()
+ }
+ var mOnSave : OnSave? = null
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
buildWeb()
}
@@ -173,6 +176,28 @@ class GeckoWeb : BWebview {
Blog.LOGE(Gson().toJson(message))
mPort?.postMessage(message)
}
+ fun sendSearch(keyword: String) {
+ val message: JSONObject = JSONObject()
+ try {
+ message.put("type", "search")
+ message.put("keyword", keyword)
+ } catch (ex: JSONException) {
+ throw RuntimeException(ex)
+ }
+ Blog.LOGE(Gson().toJson(message))
+ mPort?.postMessage(message)
+ }
+
+ fun sendSearchDo() {
+ val message: JSONObject = JSONObject()
+ try {
+ message.put("type", "searchDo")
+ } catch (ex: JSONException) {
+ throw RuntimeException(ex)
+ }
+ Blog.LOGE(Gson().toJson(message))
+ mPort?.postMessage(message)
+ }
var mExtension: WebExtension? = null
var mSession: GeckoSession? = null
@@ -342,6 +367,7 @@ class GeckoWeb : BWebview {
// 저장 성공 알림 등 후속 처리
println("PDF 저장 완료: ${outputFile.absolutePath}")
+ mOnSave?.saved()
}
fun downloadImage(context: Context, url: Uri, isGif : Boolean = false) {
@@ -604,10 +630,11 @@ class GeckoWeb : BWebview {
}
}
- fun saveMd() {
+ fun saveMd(fast : Boolean? = false) {
val message: JSONObject = JSONObject()
try {
message.put("type", "saveContent")
+ message.put("fast", fast)
} catch (ex: JSONException) {
throw RuntimeException(ex)
}
diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/RssHome.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/RssHome.kt
index 246af4d4..b3636c9c 100644
--- a/app/src/main/kotlin/bums/lunatic/launcher/home/RssHome.kt
+++ b/app/src/main/kotlin/bums/lunatic/launcher/home/RssHome.kt
@@ -103,7 +103,7 @@ internal class RssHome : Fragment() {
var infosJob: Job? = null
// var rssId = ""
lateinit var mRssAdapter: RssItemAdapter
-
+ var mLastedQuery: RealmQuery? = null
var mRssDataResult: RealmResults? = null
val mSimpleFingerGestures =
@@ -199,7 +199,7 @@ internal class RssHome : Fragment() {
return false
}
})
- var useHiddenMenu = false
+ var useHiddenMenu = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
@@ -319,39 +319,72 @@ internal class RssHome : Fragment() {
fun ask() {
- val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
- builder.setTitle("Command Line")
- val viewInflated: View = LayoutInflater.from(requireContext())
- .inflate(R.layout.text_inpu_password, binding.root as ViewGroup?, false)
- val input = viewInflated.findViewById(R.id.input) as EditText
- val privateMode = viewInflated.findViewById(R.id.private_mode) as CheckBox
- (viewInflated.findViewById(R.id.add_vote) as CheckBox)?.let{ it.visibility = View.GONE}
- (viewInflated.findViewById(R.id.add_read) as CheckBox)?.let{ it.visibility = View.GONE}
- privateMode.setOnCheckedChangeListener { v,c->
- binding.geckoWeb.privateMode = c
- }
- privateMode.isChecked = true
- binding.geckoWeb.privateMode = true
- builder.setView(viewInflated)
- builder.setPositiveButton(
- android.R.string.ok,
- DialogInterface.OnClickListener { dialog, which ->
- dialog.dismiss()
- var command = input.editableText?.toString()
- if (command?.length ?: 0 > 0) {
- binding.geckoWeb.loadUrl(
- "aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=",
- "/?searchTerm=${command}"
- )
- } else {
- binding.geckoWeb.loadUrl("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=")
- }
- })
- builder.setNegativeButton(
- android.R.string.cancel,
- DialogInterface.OnClickListener { dialog, which -> dialog.cancel() })
+ val bottomSheet = WebBottomSheet()
+ bottomSheet.listener = object : WebBottomSheet.OnGoToWebListener{
+ override fun enterSearch() {
+ binding.geckoWeb.sendSearchDo()
+ }
+ override fun onGotoWeb(
+ keyword: String,
+ category: RssDataType,
+ privateMode: Boolean
+ ) {
+ when (category) {
+ RssDataType.GOOGLE -> {
+ if (binding.geckoWeb.lastedUrl?.contains("www.google") == true) {
+ binding.geckoWeb.sendSearch(keyword)
+ } else {
+ binding.geckoWeb.loadUrl("https://www.google.com/", if (keyword.length ?: 0 > 0) { "/?q=${keyword}" } else { null })
+ }
+ binding.geckoWeb.privateMode = false
+ }
+ RssDataType.NAMU -> {
+ if (binding.geckoWeb.lastedUrl?.contains("namu.wiki") == true) {
+ binding.geckoWeb.sendSearch(keyword)
+ } else {
+ binding.geckoWeb.loadUrl("https://namu.wiki", if (keyword.length ?: 0 > 0) {"/Search?q=${keyword}"} else {null})
+ }
+ binding.geckoWeb.privateMode = false
+ }
+ RssDataType.NAVER -> {
+ if (binding.geckoWeb.lastedUrl?.contains("naver") == true) {
+ binding.geckoWeb.sendSearch(keyword)
+ } else {
+ binding.geckoWeb.loadUrl("https://search.naver.com/", if (keyword.length ?: 0 > 0) {"search.naver?where=nexearch&query==${keyword}"} else {null})
+ }
+ binding.geckoWeb.privateMode = false
+ }
+ RssDataType.NEWSFEED -> {
+ if (binding.geckoWeb.lastedUrl?.contains("news.google") == true) {
+ binding.geckoWeb.sendSearch(keyword)
+ } else {
+ binding.geckoWeb.loadUrl("https://news.google.com/", if (keyword.length ?: 0 > 0) {"search?q=${keyword}&hl=ko&gl=KR&ceid=KR%3Ako"} else {null})
+ }
+ binding.geckoWeb.privateMode = false
+ }
+ RssDataType.NEWS -> {
+ if (binding.geckoWeb.lastedUrl?.contains("bigkinds") == true) {
+ binding.geckoWeb.sendSearch(keyword)
+ } else {
+ binding.geckoWeb.loadUrl("https://www.bigkinds.or.kr/", if (keyword.length ?: 0 > 0) {"search?q=${keyword}&hl=ko&gl=KR&ceid=KR%3Ako"} else {null})
+ }
+ binding.geckoWeb.privateMode = false
+ }
+ RssDataType.PRIVATE -> {
+// if (binding.geckoWeb.lastedUrl?.contains("naver") == true) {
+//
+// } else {
+ binding.geckoWeb.privateMode = privateMode
+ binding.geckoWeb.loadUrl("aHR0cHM6Ly9pamF2dG9ycmVudC5jb20=", if (keyword.length ?: 0 > 0) {"/?searchTerm=${keyword}"} else {null})
+// }
+ }
+ else -> {
- builder.show()
+ }
+ }
+ }
+ }
+ bottomSheet.show(childFragmentManager, "SearchBottomSheet")
}
var currentRss : RssData? = null
@@ -500,7 +533,25 @@ internal class RssHome : Fragment() {
binding.privateBtn.visibility = View.GONE
binding.search.visibility = View.GONE
}
-
+ binding.geckoWeb?.mOnSave = object : GeckoWeb.OnSave{
+ override fun saved() {
+ currentRss?.originPage.let {
+ Blog.LOGE("Arrow Center Click")
+ WorkersDb.getRealm().apply {
+ writeBlocking {
+ val result = query().query(
+ if (imageView) "thumbnail == $0" else "originPage == $0",
+ it
+ ).find()
+ if (result.size > 0) {
+ result.forEach { it.vote = true }
+ }
+ }
+ }
+ doNextPage()
+ }
+ }
+ }
binding.hide.setOnClickListener {
if (binding.geckoWeb.isVisible) {
WorkersDb.getRealm().apply {
@@ -583,22 +634,7 @@ internal class RssHome : Fragment() {
}
fun vote() {
- binding.geckoWeb?.saveMd()
- currentRss?.originPage.let {
- Blog.LOGE("Arrow Center Click")
- WorkersDb.getRealm().apply {
- writeBlocking {
- val result = query().query(
- if (imageView) "thumbnail == $0" else "originPage == $0",
- it
- ).find()
- if (result.size > 0) {
- result.forEach { it.vote = true }
- }
- }
- }
- doNextPage()
- }
+ binding.geckoWeb?.saveMd(true)
}
@@ -654,14 +690,11 @@ internal class RssHome : Fragment() {
Blog.LOGE("updateQuery >>> ${q.description()}")
infosJob?.cancel()
commandHandler.removeCallbacks(infoUpdate)
-
- mRssDataResult =
- q.sort("pubDate ", Sort.DESCENDING).limit(300).distinct("originPage", "title").find()
+ mLastedQuery = q.sort("pubDate ", Sort.DESCENDING).limit(300).distinct("originPage", "title")
+ mRssDataResult = mLastedQuery?.find()
mRssDataResult?.asFlow()?.let { flow ->
infosJob = CoroutineScope(Dispatchers.IO).launch {
flow.collect { changes: ResultsChange ->
-// when (changes) {
-// is InitialResults -> {
synchronized(lasted) {
commandHandler.removeCallbacks(infoUpdate)
WorkersDb.getRealm().apply {
@@ -670,17 +703,6 @@ internal class RssHome : Fragment() {
}
commandHandler.post(infoUpdate)
}
-// }
-//
-// is UpdatedResults -> {
-// CoroutineScope(Dispatchers.Main).launch {
-// changes.changeRanges.forEach {
-// mRssAdapter.notifyItemRangeChanged(it.startIndex, it.length)
-// }
-// }
-// }
-//
-// }
}
}
infosJob?.start()
@@ -771,18 +793,7 @@ internal class RssHome : Fragment() {
Blog.LOGE("onViewCreated()")
-
-// fragManager.addOnBackStackChangedListener {
-// Blog.LOGE("addOnBackStackChangedListener()")
-// shouldResume = if (fragManager.backStackEntryCount == 0) {
-// binding.root.visibility = View.VISIBLE
-// true
-// } else {
-// binding.root.visibility = View.GONE
-// false
-// }
-// }
- enableSwipeToDeleteAndUndo()
+// enableSwipeToDeleteAndUndo()
}
diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/SearchBottomSheet.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/SearchBottomSheet.kt
index 5f3c8c1c..419c649a 100644
--- a/app/src/main/kotlin/bums/lunatic/launcher/home/SearchBottomSheet.kt
+++ b/app/src/main/kotlin/bums/lunatic/launcher/home/SearchBottomSheet.kt
@@ -64,17 +64,12 @@ class SearchBottomSheet : BottomSheetDialogFragment() {
text = category.name
isAllCaps = false
setBackgroundResource(android.R.drawable.btn_default)
-
- // 초기 색상(활성 상태 색 표시)
- updateButtonStyle(this, true)
-
+ setTextColor(Color.WHITE)
+ setBackgroundResource(R.color.tabs_black)
setOnClickListener {
- // 상태 반전
val current = categoryStates[category.name] ?: true
categoryStates[category.name] = !current
-
- // 스타일 업데이트
- updateButtonStyle(this, !current)
+ this.isSelected = !this.isSelected
triggerSearchWithDebounce(inputKeyword.text.toString())
}
}
@@ -113,15 +108,6 @@ class SearchBottomSheet : BottomSheetDialogFragment() {
}
}
- private fun updateButtonStyle(button: Button, isActive: Boolean) {
- if (isActive) {
- button.setBackgroundColor(Color.parseColor("#FF9800")) // 활성화 색상
- button.setTextColor(Color.WHITE)
- } else {
- button.setBackgroundColor(Color.LTGRAY) // 비활성화 색상
- button.setTextColor(Color.DKGRAY)
- }
- }
private fun triggerSearchWithDebounce(keyword: String) {
searchRunnable?.let { debounceHandler.removeCallbacks(it) }
diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/WebBottomSheet.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/WebBottomSheet.kt
new file mode 100644
index 00000000..0f946350
--- /dev/null
+++ b/app/src/main/kotlin/bums/lunatic/launcher/home/WebBottomSheet.kt
@@ -0,0 +1,136 @@
+package bums.lunatic.launcher.home
+
+import android.content.Context
+import android.graphics.Color
+import android.os.Build
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.text.Editable
+import android.text.TextWatcher
+import android.view.LayoutInflater
+import android.view.View
+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 bums.lunatic.launcher.R
+import bums.lunatic.launcher.model.RssDataType
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+
+class WebBottomSheet : BottomSheetDialogFragment() {
+
+ private val debounceHandler = Handler(Looper.getMainLooper())
+ private var searchRunnable: Runnable? = null
+ private val debounceDelay = 300L // 0.3초 지연
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.bottom_sheet_web, container, false)
+ }
+
+ interface OnGoToWebListener {
+ fun onGotoWeb(keyword: String, category: RssDataType, privateMode : Boolean)
+ fun enterSearch()
+ }
+
+ var listener: OnGoToWebListener? = null
+
+ var selectedRssType : RssDataType = RssDataType.GOOGLE
+ lateinit var privateMode : CheckBox
+ lateinit var inputKeyword : EditText
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ inputKeyword = view.findViewById(R.id.inputKeyword)
+ val categoryContainer = view.findViewById(R.id.categoryContainer)
+ privateMode = view.findViewById(R.id.check_private) as CheckBox
+ privateMode.setOnCheckedChangeListener {v,b->triggerSearchWithDebounce(inputKeyword.text.toString())}
+ // 카테고리 목록
+ val categories = listOf(RssDataType.GOOGLE, RssDataType.NAVER,RssDataType.NEWS,RssDataType.NEWSFEED,RssDataType.NAMU,RssDataType.PRIVATE)
+
+ // 버튼 동적 생성
+ categoryContainer.removeAllViews()
+
+ categoryContainer.setOnCheckedChangeListener { g,checked ->
+ ((g.findViewById(checked))?.tag as? RssDataType)?.let {
+ selectedRssType = it
+ }
+ }
+
+ for (category in categories) {
+ val btn = RadioButton(requireContext()).apply {
+ layoutParams = RadioGroup.LayoutParams(RadioGroup.LayoutParams.WRAP_CONTENT,RadioGroup.LayoutParams.MATCH_PARENT)
+ setPadding(50,2,50,2)
+ tag = category
+ text = category.name
+ isAllCaps = false
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ setButtonIcon(null)
+ }
+ setTextColor(Color.WHITE)
+ setBackgroundResource(R.color.tabs_black)
+ setOnClickListener {
+ triggerSearchWithDebounce(inputKeyword.text.toString())
+ }
+ }
+ categoryContainer.addView(btn)
+ }
+
+ (categoryContainer.getChildAt(0) as? RadioButton)?.let { it.isChecked = true }
+
+ inputKeyword.requestFocus()
+ // 키보드 강제 오픈
+ inputKeyword.postDelayed( {
+ val imm = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.showSoftInput(inputKeyword, InputMethodManager.SHOW_IMPLICIT)
+ },150L)
+
+// EditText 입력 실시간 감지 + debounce
+ inputKeyword.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+ triggerSearchWithDebounce(s.toString())
+ }
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
+ })
+ // 키보드 "검색" 액션 처리
+ inputKeyword.setOnEditorActionListener { _, actionId, _ ->
+ if (actionId == EditorInfo.IME_ACTION_SEARCH) {
+ val keyword = inputKeyword.text.toString()
+ if (keyword.isNotEmpty()) {
+ triggerSearchWithDebounce(keyword)
+ dismiss() // 필요 시 닫기
+ }
+ true
+ } else {
+ false
+ }
+ }
+ }
+
+ private fun triggerSearchWithDebounce(keyword: String) {
+ searchRunnable?.let { debounceHandler.removeCallbacks(it) }
+ searchRunnable = Runnable {
+ listener?.onGotoWeb(keyword, selectedRssType, privateMode.isChecked)
+ }
+ debounceHandler.postDelayed(searchRunnable!!, debounceDelay)
+ }
+
+ override fun onStart() {
+ super.onStart()
+ // 전체 창 높이를 키보드에 맞게 조정
+ dialog?.window?.setSoftInputMode(
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE or
+ WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
+ )
+ }
+}
diff --git a/app/src/main/kotlin/bums/lunatic/launcher/model/RssDataInterface.kt b/app/src/main/kotlin/bums/lunatic/launcher/model/RssDataInterface.kt
index 84eb92ff..5d0a6ce3 100644
--- a/app/src/main/kotlin/bums/lunatic/launcher/model/RssDataInterface.kt
+++ b/app/src/main/kotlin/bums/lunatic/launcher/model/RssDataInterface.kt
@@ -10,6 +10,7 @@ enum class RssDataType {
TORRENT,
YOUTUBE,
NEWSFEED,
+ NEWS,
TAGS,
REDDIT,
REDDIT_NSFW,
@@ -19,6 +20,9 @@ enum class RssDataType {
RULIWEB,
CLIEN,
THEQOO,
+ NAVER,
+ GOOGLE,
+ NAMU,
ARCA;
fun getResId() = when (this) {
diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/Magnet.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/Magnet.kt
new file mode 100644
index 00000000..cf736900
--- /dev/null
+++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/Magnet.kt
@@ -0,0 +1,185 @@
+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 {
+// "https://btsearch.love/
+ override val contentsType = "btsearch"
+ override var lastNumber : Int = 143
+ override val webcontentsName : String = "btsearch"
+ override val afterDot = "love"
+ override fun getLastedDoamin(): String {
+ return String.format("https://%s.%s", webcontentsName, afterDot)
+ }
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ super.onCreateView(inflater, container, savedInstanceState)
+ return binding.root
+ }
+
+ override fun onStart() {
+ super.onStart()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ loadLastInfo()
+ }
+
+ override fun onTouch(touchArea: TouchArea) {
+ Blog.LOGD(log = "onTouch ${touchArea}")
+ when (touchArea) {
+ TouchArea.Center -> {
+
+ }
+
+ TouchArea.Right -> {
+ actionNextEvent()
+ }
+
+ TouchArea.Left -> {
+ actionPrevEvent()
+ }
+
+ TouchArea.DoubleRight -> {
+ actionNextEvent(true)
+ }
+
+ TouchArea.DoubleLeft -> {
+ actionPrevEvent(true)
+ }
+ else -> {
+
+ }
+ }
+
+
+ }
+
+ override fun onLongClick() {
+ Blog.LOGD(log = "onLongClick")
+
+ }
+
+ override fun onSwipeLeft(count: Int) {
+ Blog.LOGD(log = "onSwipeLeft ${count}")
+ actionNextEvent(count > 1)
+
+ }
+
+ override fun onSwipeRight(count: Int) {
+ Blog.LOGD(log = "onSwipeRight ${count}")
+ actionPrevEvent(count > 1)
+ }
+
+ override fun onSwipeUp(touchCount: Int) {
+
+ }
+
+ override fun onSwipeDown(touchCount: Int) {
+ if (touchCount == 2) {
+ if (binding.pagedLayer.isVisible) {
+ binding.pagedLayer.visibility = GONE
+ }
+ }
+ }
+
+ override fun onTimeoverTouch() {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/Perplexity.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/Perplexity.kt
new file mode 100644
index 00000000..f1dc5c21
--- /dev/null
+++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/Perplexity.kt
@@ -0,0 +1,185 @@
+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 {
+// "https://btsearch.love/
+ override val contentsType = "perplexity"
+ override var lastNumber : Int = 143
+ override val webcontentsName : String = "www.perplexity"
+ override val afterDot = "ai"
+ override fun getLastedDoamin(): String {
+ return String.format("https://%s.%s", webcontentsName, afterDot)
+ }
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ super.onCreateView(inflater, container, savedInstanceState)
+ return binding.root
+ }
+
+ override fun onStart() {
+ super.onStart()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ loadLastInfo()
+ }
+
+ override fun onTouch(touchArea: TouchArea) {
+ Blog.LOGD(log = "onTouch ${touchArea}")
+ when (touchArea) {
+ TouchArea.Center -> {
+
+ }
+
+ TouchArea.Right -> {
+ actionNextEvent()
+ }
+
+ TouchArea.Left -> {
+ actionPrevEvent()
+ }
+
+ TouchArea.DoubleRight -> {
+ actionNextEvent(true)
+ }
+
+ TouchArea.DoubleLeft -> {
+ actionPrevEvent(true)
+ }
+ else -> {
+
+ }
+ }
+
+
+ }
+
+ override fun onLongClick() {
+ Blog.LOGD(log = "onLongClick")
+
+ }
+
+ override fun onSwipeLeft(count: Int) {
+ Blog.LOGD(log = "onSwipeLeft ${count}")
+ actionNextEvent(count > 1)
+
+ }
+
+ override fun onSwipeRight(count: Int) {
+ Blog.LOGD(log = "onSwipeRight ${count}")
+ actionPrevEvent(count > 1)
+ }
+
+ override fun onSwipeUp(touchCount: Int) {
+
+ }
+
+ override fun onSwipeDown(touchCount: Int) {
+ if (touchCount == 2) {
+ if (binding.pagedLayer.isVisible) {
+ binding.pagedLayer.visibility = GONE
+ }
+ }
+ }
+
+ override fun onTimeoverTouch() {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/color/tabs_black.xml b/app/src/main/res/color/tabs_black.xml
index 5642ec02..5505df03 100644
--- a/app/src/main/res/color/tabs_black.xml
+++ b/app/src/main/res/color/tabs_black.xml
@@ -1,5 +1,6 @@
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/h_divider.xml b/app/src/main/res/drawable/h_divider.xml
new file mode 100644
index 00000000..1ec7437d
--- /dev/null
+++ b/app/src/main/res/drawable/h_divider.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/bottom_sheet_search.xml b/app/src/main/res/layout/bottom_sheet_search.xml
index 1d6589f6..d55b3d72 100644
--- a/app/src/main/res/layout/bottom_sheet_search.xml
+++ b/app/src/main/res/layout/bottom_sheet_search.xml
@@ -1,46 +1,57 @@
-
-
-
-
-
+
+
+
+
-
+
diff --git a/app/src/main/res/layout/bottom_sheet_web.xml b/app/src/main/res/layout/bottom_sheet_web.xml
new file mode 100644
index 00000000..5ba7760d
--- /dev/null
+++ b/app/src/main/res/layout/bottom_sheet_web.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/launcher_activity.xml b/app/src/main/res/layout/launcher_activity.xml
index 0528f900..55cb16bb 100644
--- a/app/src/main/res/layout/launcher_activity.xml
+++ b/app/src/main/res/layout/launcher_activity.xml
@@ -59,6 +59,11 @@
android:id="@+id/comics"
style="@style/tabItem"
android:layout_height="match_parent"/>
+
-