....
This commit is contained in:
parent
405b8c8fed
commit
a00b2764b0
@ -14,7 +14,6 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "bums.lunatic.launcher"
|
applicationId = "bums.lunatic.launcher"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 34
|
|
||||||
versionCode = 38
|
versionCode = 38
|
||||||
versionName = "2.8.2"
|
versionName = "2.8.2"
|
||||||
multiDexEnabled = true
|
multiDexEnabled = true
|
||||||
|
|||||||
@ -109,20 +109,14 @@
|
|||||||
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
|
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<!-- <activity-->
|
|
||||||
<!-- android:name=".PhotoFilter"-->
|
|
||||||
<!-- android:label="@string/lunar_settings"-->
|
|
||||||
<!-- android:exported="true">-->
|
|
||||||
<!-- </activity>-->
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".feeds.Feeds"
|
android:name=".tokiz.Settings"
|
||||||
android:label="@string/lunar_settings"
|
android:label="@string/lunar_settings"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleInstance"
|
||||||
android:excludeFromRecents="true"
|
android:excludeFromRecents="true"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".settings.SettingsActivity"
|
android:name=".settings.SettingsActivity"
|
||||||
|
|||||||
40
app/src/main/assets/extensions/my_extension/background.js
Normal file
40
app/src/main/assets/extensions/my_extension/background.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
browser.webRequest.onHeadersReceived.addListener(
|
||||||
|
function(details) {
|
||||||
|
let headers = details.responseHeaders || [];
|
||||||
|
// Cache-Control 헤더가 없거나 no-store, no-cache 등일 때 수정
|
||||||
|
let found = false;
|
||||||
|
for (let header of headers) {
|
||||||
|
if (header.name.toLowerCase() === "cache-control") {
|
||||||
|
header.value = "public, max-age=31536000"; // 1년 캐시
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
headers.push({name: "Cache-Control", value: "public, max-age=31536000"});
|
||||||
|
}
|
||||||
|
return {responseHeaders: headers};
|
||||||
|
},
|
||||||
|
{urls: ["*://*/*.gif"], types: ["image"]},
|
||||||
|
["blocking", "responseHeaders"]
|
||||||
|
);
|
||||||
|
//const originalLog = console.log;
|
||||||
|
//console.log = function(...args) {
|
||||||
|
// // 메시지 가공 또는 네이티브로 전달
|
||||||
|
// originalLog.apply(console, args);
|
||||||
|
// browser.runtime.sendNativeMessage("browser", args);
|
||||||
|
//};
|
||||||
|
|
||||||
|
browser.webRequest.onBeforeRequest.addListener(
|
||||||
|
function(details) {
|
||||||
|
return { cancel: true };
|
||||||
|
},
|
||||||
|
{ urls: ["*://*/*.gif"], types: ["image"] },
|
||||||
|
["blocking"]
|
||||||
|
);
|
||||||
|
//window.addEventListener('error', function(event) {
|
||||||
|
// if (event.message && event.message.includes('No impl for message: MozAfterPaint')) {
|
||||||
|
// // 앱으로 오류 신호 전달
|
||||||
|
// browser.runtime.sendMessage({ type: 'RELOAD_REQUEST' });
|
||||||
|
// }
|
||||||
|
//});
|
||||||
86
app/src/main/assets/extensions/my_extension/demo.js
Normal file
86
app/src/main/assets/extensions/my_extension/demo.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
function getList() {
|
||||||
|
const contentsType = location.hostname.search('newtoki') > -1 ? 'newtoki' : location.hostname.search('booktoki') > -1 ? 'booktoki' : 'manatoki';
|
||||||
|
const contentsArray = [];
|
||||||
|
var children = document.getElementsByClassName('list-body')[0].children;
|
||||||
|
var maxCount = children.length;
|
||||||
|
for (i= 0; i < maxCount; i++) {
|
||||||
|
var chapterNum = children[i].getElementsByClassName('wr-num')[0].textContent;
|
||||||
|
var pageUrl = children[i].getElementsByClassName('wr-subject')[0].getElementsByTagName('a')[0].href;
|
||||||
|
if (pageUrl != null && pageUrl.length > 0 && pageUrl.startsWith('http')) {
|
||||||
|
pageUrl = new URL(pageUrl).pathname;
|
||||||
|
if (pageUrl && pageUrl.startsWith('http')) {
|
||||||
|
var urlObj = new URL(pageUrl);
|
||||||
|
var paths = urlObj.pathname.split('/').filter(Boolean);
|
||||||
|
if (paths.length > 0) {
|
||||||
|
var last = paths[paths.length - 1];
|
||||||
|
if (!/^\\d+$/.test(last)) {
|
||||||
|
paths.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pageUrl = '/' + paths.join('/');
|
||||||
|
}
|
||||||
|
console.log(pageUrl);
|
||||||
|
} else {
|
||||||
|
console.log("pageUrl.startsWith('http') == false" + pageUrl);
|
||||||
|
}
|
||||||
|
var chapterTitle = children[i].getElementsByClassName('wr-subject')[0].getElementsByTagName('a')[0].innerText;
|
||||||
|
if(chapterTitle.split('\\n').length > 1) {
|
||||||
|
chapterTitle = chapterTitle.split('\\n')[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
var bookPageUrl = location.pathname;
|
||||||
|
var bookTitle = document.getElementsByClassName('view-title')[0].getElementsByTagName('span')[0].innerText;
|
||||||
|
var data = {
|
||||||
|
'contentsType': contentsType,
|
||||||
|
'chapterID': Number(chapterNum),
|
||||||
|
'chapterNum': Number(chapterNum),
|
||||||
|
'pathUrl': pageUrl,
|
||||||
|
'bookPageUrl': bookPageUrl,
|
||||||
|
'chapterTitle': chapterTitle,
|
||||||
|
'bookTitle': bookTitle,
|
||||||
|
};
|
||||||
|
contentsArray.push(
|
||||||
|
data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(contentsArray.length > 0) {
|
||||||
|
window.webkit.messageHandlers.ContentsRcv.postMessage(JSON.stringify({
|
||||||
|
'contentsType': contentsType,
|
||||||
|
'bookTitle': bookTitle,
|
||||||
|
'bookPageUrl': new URL(location.href).pathname,
|
||||||
|
'pages': contentsArray ,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getList();
|
||||||
|
|
||||||
|
|
||||||
|
function check2() {
|
||||||
|
var children = document.getElementsByClassName('list-body')[0].children;
|
||||||
|
var maxCount = children.length;
|
||||||
|
for (i= 0; i < maxCount; i++) {
|
||||||
|
var pageUrl = children[i].getElementsByClassName('wr-subject')[0].getElementsByTagName('a')[0].href;
|
||||||
|
if (pageUrl != null && pageUrl.length > 0 && pageUrl.startsWith('http')) {
|
||||||
|
if (pageUrl) {
|
||||||
|
var paths = pageUrl.split('/')
|
||||||
|
if (paths.length > 0) {
|
||||||
|
var last = paths[paths.length - 1];
|
||||||
|
if (last && Array.from(last).every(ch => ch >= '0' && ch <= '9')) {
|
||||||
|
console.log("only nums " + last)
|
||||||
|
} else {
|
||||||
|
console.log("not only nums " + last)
|
||||||
|
paths.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pageUrl = paths.join('/');
|
||||||
|
pageUrl = new URL(pageUrl).pathname;
|
||||||
|
}
|
||||||
|
console.log(pageUrl);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
check2();
|
||||||
28
app/src/main/assets/extensions/my_extension/manifest.json
Normal file
28
app/src/main/assets/extensions/my_extension/manifest.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"browser_specific_settings": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "messaging@booktoki468.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"manifest_version": 2,
|
||||||
|
"version": "1.0",
|
||||||
|
|
||||||
|
"name": "Sample Extension",
|
||||||
|
"background": {
|
||||||
|
"scripts": ["background.js"]
|
||||||
|
},
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"matches": ["<all_urls>"],
|
||||||
|
"js": ["messaging.js"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"permissions": [
|
||||||
|
"nativeMessaging",
|
||||||
|
"nativeMessagingFromContent",
|
||||||
|
"geckoViewAddons",
|
||||||
|
"webRequest",
|
||||||
|
"webRequestBlocking",
|
||||||
|
"*://*/*.gif"
|
||||||
|
]
|
||||||
|
}
|
||||||
177
app/src/main/assets/extensions/my_extension/messaging.js
Normal file
177
app/src/main/assets/extensions/my_extension/messaging.js
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
|
||||||
|
const port = browser.runtime.connectNative("browser");
|
||||||
|
port.onMessage.addListener(response => {
|
||||||
|
var type= response["type"];
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case "getList": {
|
||||||
|
try {
|
||||||
|
// var listBody = null
|
||||||
|
// try {listBody = document.querySelector(".list-body");}catch (e) {}
|
||||||
|
// var title = null
|
||||||
|
// var contents = null
|
||||||
|
// try {title = toonTitle(document.querySelector(".page-desc")); }catch (e) {}
|
||||||
|
// try {contents = toonContents(document.querySelector("#novel_content"))}catch (e) {}
|
||||||
|
// console.log("listBody", listBody);
|
||||||
|
// console.log("title", title);
|
||||||
|
if(listBody) {
|
||||||
|
// getList(listBody.children)
|
||||||
|
} else if(title && contents) {
|
||||||
|
// if (toonTitle !== undefined && toonContents !== undefined && toonTitle !== "" && toonContents !=="") {
|
||||||
|
// sendMessage(
|
||||||
|
// {
|
||||||
|
// type: "BookContents",
|
||||||
|
// book : {
|
||||||
|
// chapterTitle : title,
|
||||||
|
// bookContents : contents
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
loadComplete()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
loadComplete()
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}break;
|
||||||
|
case "scrollDown":{
|
||||||
|
var max = response["max"]
|
||||||
|
var current = response["current"]
|
||||||
|
var isUpDown = response["isUpDown"]
|
||||||
|
if (max > 0 && current > 0) { scrollByPercent(Number(current),Number(max)); }
|
||||||
|
else scrollByPercentUpDown(Number(isUpDown),100);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "onLoaded":{
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
port.postMessage(`Received: ${JSON.stringify(response)}`);
|
||||||
|
break
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(document.querySelector(".list-body")) {
|
||||||
|
var listBody = null
|
||||||
|
try {listBody = document.querySelector(".list-body");}catch (e) {}
|
||||||
|
getList(listBody.children)
|
||||||
|
} else if(document.querySelector("#novel_content")){
|
||||||
|
var title = null
|
||||||
|
var contents = null
|
||||||
|
try {title = toonTitle(document.querySelector(".page-desc")); }catch (e) {}
|
||||||
|
try {contents = toonContents(document.querySelector("#novel_content"))}catch (e) {}
|
||||||
|
if (toonTitle !== undefined && toonContents !== undefined && toonTitle !== "" && toonContents !=="") {
|
||||||
|
sendMessage(
|
||||||
|
{
|
||||||
|
type: "BookContents",
|
||||||
|
book : {
|
||||||
|
chapterTitle : title,
|
||||||
|
bookContents : contents
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if(document.querySelector("#html_encoder_div")) {
|
||||||
|
sendMessage(
|
||||||
|
{
|
||||||
|
type: "WebtoonContents",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
sendMessage({type:"MSG",msg:"connected has Nothings"});
|
||||||
|
loadComplete()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getList(children) {
|
||||||
|
// port.postMessage("Start of getList!" + children);
|
||||||
|
const contentsArray = [];
|
||||||
|
var maxCount = children.length;
|
||||||
|
for (i= 0; i < maxCount; i++) {
|
||||||
|
var chapterNum = children[i].getElementsByClassName('wr-num')[0].textContent;
|
||||||
|
var pageUrl = children[i].getElementsByClassName('wr-subject')[0].getElementsByTagName('a')[0].href;
|
||||||
|
if (pageUrl != null && pageUrl.length > 0 && pageUrl.startsWith("http")) {
|
||||||
|
pageUrl = new URL(pageUrl).pathname;
|
||||||
|
}
|
||||||
|
var chapterTitle = children[i].getElementsByClassName('wr-subject')[0].getElementsByTagName('a')[0].innerText;
|
||||||
|
if(chapterTitle.split('\n').length > 1) {
|
||||||
|
chapterTitle = chapterTitle.split('\n')[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
var bookPageUrl = location.pathname;
|
||||||
|
var bookTitle = document.getElementsByClassName('view-title')[0].getElementsByTagName('span')[0].innerText;
|
||||||
|
var data = {
|
||||||
|
'chapterID': Number(chapterNum),
|
||||||
|
'chapterNum': Number(chapterNum),
|
||||||
|
'pathUrl': pageUrl,
|
||||||
|
'bookPageUrl': bookPageUrl,
|
||||||
|
'chapterTitle': chapterTitle,
|
||||||
|
'bookTitle': bookTitle,
|
||||||
|
};
|
||||||
|
contentsArray.push(
|
||||||
|
data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(contentsArray.length > 0) {
|
||||||
|
sendMessage(
|
||||||
|
{
|
||||||
|
type: "getListResult",
|
||||||
|
bookInfos: {
|
||||||
|
bookTitle: bookTitle,
|
||||||
|
bookPageUrl: new URL(location.href).pathname,
|
||||||
|
pages: contentsArray ,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toonTitle(toon_title) {
|
||||||
|
return toon_title != null ? toon_title.innerText : null
|
||||||
|
}
|
||||||
|
function toonContents(novel_content) {
|
||||||
|
return novel_content != null ? novel_content.innerText : null
|
||||||
|
}
|
||||||
|
function scrollByPercent(current , max) {
|
||||||
|
const pageHeight = Math.max(
|
||||||
|
document.body.scrollHeight,
|
||||||
|
document.documentElement.scrollHeight,
|
||||||
|
document.body.offsetHeight,
|
||||||
|
document.documentElement.offsetHeight,
|
||||||
|
document.body.clientHeight,
|
||||||
|
document.documentElement.clientHeight
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentScroll = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
|
||||||
|
const moveAmount = pageHeight / max;
|
||||||
|
window.scrollTo({ top: moveAmount * current, behavior: "smooth" });
|
||||||
|
}
|
||||||
|
|
||||||
|
function scrollByPercentUpDown(isToDown , max) {
|
||||||
|
const pageHeight = Math.max(
|
||||||
|
document.body.scrollHeight,
|
||||||
|
document.documentElement.scrollHeight,
|
||||||
|
document.body.offsetHeight,
|
||||||
|
document.documentElement.offsetHeight,
|
||||||
|
document.body.clientHeight,
|
||||||
|
document.documentElement.clientHeight
|
||||||
|
);
|
||||||
|
const currentScroll = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
|
||||||
|
const moveAmount = Math.max(pageHeight / max,100);
|
||||||
|
window.scrollTo({ top: currentScroll + (moveAmount * isToDown) , behavior: "smooth" });
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadComplete() {
|
||||||
|
// try {port.postMessage(JSON.stringify({type: "NotRegistered"}));}catch (e) {}
|
||||||
|
}
|
||||||
|
function sendMessage(msg) {
|
||||||
|
port.postMessage(JSON.stringify(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
function dssd() {
|
||||||
|
|
||||||
|
}
|
||||||
@ -20,17 +20,12 @@ package bums.lunatic.launcher
|
|||||||
|
|
||||||
//import rasel.lunar.launcher.home.LauncherHome.Companion.rssSet
|
//import rasel.lunar.launcher.home.LauncherHome.Companion.rssSet
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
import android.content.BroadcastReceiver
|
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
@ -40,8 +35,6 @@ import android.os.Environment.isExternalStorageManager
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.support.v4.media.MediaBrowserCompat
|
|
||||||
import android.telephony.TelephonyManager
|
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.KeyEvent.ACTION_UP
|
import android.view.KeyEvent.ACTION_UP
|
||||||
import android.view.KeyEvent.KEYCODE_BUTTON_A
|
import android.view.KeyEvent.KEYCODE_BUTTON_A
|
||||||
@ -51,8 +44,6 @@ import android.view.KeyEvent.KEYCODE_BUTTON_START
|
|||||||
import android.view.KeyEvent.KEYCODE_BUTTON_X
|
import android.view.KeyEvent.KEYCODE_BUTTON_X
|
||||||
import android.view.KeyEvent.KEYCODE_BUTTON_Y
|
import android.view.KeyEvent.KEYCODE_BUTTON_Y
|
||||||
import android.view.KeyEvent.KEYCODE_DPAD_DOWN
|
import android.view.KeyEvent.KEYCODE_DPAD_DOWN
|
||||||
import android.view.KeyEvent.KEYCODE_DPAD_LEFT
|
|
||||||
import android.view.KeyEvent.KEYCODE_DPAD_RIGHT
|
|
||||||
import android.view.KeyEvent.KEYCODE_DPAD_UP
|
import android.view.KeyEvent.KEYCODE_DPAD_UP
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -67,6 +58,7 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
|||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
import androidx.work.OneTimeWorkRequest
|
import androidx.work.OneTimeWorkRequest
|
||||||
@ -74,27 +66,26 @@ import androidx.work.PeriodicWorkRequestBuilder
|
|||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
||||||
import bums.lunatic.launcher.apps.AppDrawer
|
import bums.lunatic.launcher.apps.AppDrawer
|
||||||
|
import bums.lunatic.launcher.tokiz.Novels
|
||||||
import bums.lunatic.launcher.common.CommonActivity
|
import bums.lunatic.launcher.common.CommonActivity
|
||||||
import bums.lunatic.launcher.databinding.LauncherActivityBinding
|
import bums.lunatic.launcher.databinding.LauncherActivityBinding
|
||||||
import bums.lunatic.launcher.feeds.WidgetHost
|
import bums.lunatic.launcher.feeds.WidgetHost
|
||||||
import bums.lunatic.launcher.helpers.BluetoothManager
|
import bums.lunatic.launcher.helpers.BluetoothManager
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_APPLICATION_THEME
|
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_APPLICATION_THEME
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_FIRST_LAUNCH
|
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_STATUS_BAR
|
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_STATUS_BAR
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_FIRST_LAUNCH
|
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.widgetHostId
|
import bums.lunatic.launcher.helpers.Constants.Companion.widgetHostId
|
||||||
import bums.lunatic.launcher.helpers.HeadsetActionButtonReceiver
|
import bums.lunatic.launcher.helpers.HeadsetActionButtonReceiver
|
||||||
import bums.lunatic.launcher.helpers.PrefLong
|
import bums.lunatic.launcher.helpers.PrefLong
|
||||||
import bums.lunatic.launcher.home.LauncherHome
|
import bums.lunatic.launcher.home.LauncherHome
|
||||||
import bums.lunatic.launcher.home.RssViewBuilder
|
import bums.lunatic.launcher.home.RssViewBuilder
|
||||||
import bums.lunatic.launcher.home.adapters.RssItemAdapter.Companion.rssList
|
|
||||||
import bums.lunatic.launcher.model.RssData
|
import bums.lunatic.launcher.model.RssData
|
||||||
import bums.lunatic.launcher.model.RssDataType
|
import bums.lunatic.launcher.model.RssDataType
|
||||||
import bums.lunatic.launcher.receiver.NLService
|
import bums.lunatic.launcher.receiver.NLService
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
import bums.lunatic.launcher.utils.FeedParseManager
|
import bums.lunatic.launcher.utils.FeedParseManager
|
||||||
import bums.lunatic.launcher.utils.getJ
|
import bums.lunatic.launcher.utils.getJ
|
||||||
|
import bums.lunatic.launcher.view.TableRadioGroup
|
||||||
import bums.lunatic.launcher.workers.AppInfoGetter
|
import bums.lunatic.launcher.workers.AppInfoGetter
|
||||||
import bums.lunatic.launcher.workers.ArcaGetter
|
import bums.lunatic.launcher.workers.ArcaGetter
|
||||||
import bums.lunatic.launcher.workers.CalendarGetter
|
import bums.lunatic.launcher.workers.CalendarGetter
|
||||||
@ -120,18 +111,19 @@ import bums.lunatic.launcher.workers.WorkersDb
|
|||||||
import bums.lunatic.launcher.workers.YoutubeGetter
|
import bums.lunatic.launcher.workers.YoutubeGetter
|
||||||
import bums.lunatic.launcher.workers.YoutubeGetter.Companion.YT_WORK_TAG
|
import bums.lunatic.launcher.workers.YoutubeGetter.Companion.YT_WORK_TAG
|
||||||
import com.google.android.material.color.DynamicColors
|
import com.google.android.material.color.DynamicColors
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import io.realm.kotlin.ext.query
|
import io.realm.kotlin.ext.query
|
||||||
import io.realm.kotlin.query.Sort
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kr.lunaticbum.utils.ui.DisplayUtil
|
import kr.lunaticbum.utils.ui.DisplayUtil
|
||||||
import java.text.SimpleDateFormat
|
import org.json.JSONObject
|
||||||
|
import org.mozilla.geckoview.ExperimentDelegate
|
||||||
|
import org.mozilla.geckoview.GeckoResult
|
||||||
|
import org.mozilla.geckoview.GeckoRuntime
|
||||||
|
import org.mozilla.geckoview.GeckoRuntimeSettings
|
||||||
import java.util.Base64
|
import java.util.Base64
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@ -143,6 +135,12 @@ internal class LauncherActivity : CommonActivity() {
|
|||||||
// lateinit var viewPager: ViewPager2
|
// lateinit var viewPager: ViewPager2
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private var sRuntime: GeckoRuntime? = null
|
||||||
|
fun getRuntime() : GeckoRuntime? {
|
||||||
|
lActivity?.initGeckoRuntime()
|
||||||
|
return sRuntime
|
||||||
|
}
|
||||||
|
|
||||||
private var mWorkManager: WorkManager? = null
|
private var mWorkManager: WorkManager? = null
|
||||||
var isOpendFold = false
|
var isOpendFold = false
|
||||||
val qDayPeriod = 60L * 8L
|
val qDayPeriod = 60L * 8L
|
||||||
@ -179,11 +177,11 @@ internal class LauncherActivity : CommonActivity() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun runWeatherGetter() {
|
// fun runWeatherGetter() {
|
||||||
Executors.newSingleThreadScheduledExecutor().schedule({
|
// Executors.newSingleThreadScheduledExecutor().schedule({
|
||||||
mWorkManager?.enqueue(OneTimeWorkRequest.from(OpenWeatherGetter::class.java))
|
// mWorkManager?.enqueue(OneTimeWorkRequest.from(OpenWeatherGetter::class.java))
|
||||||
}, 200L, TimeUnit.MILLISECONDS)
|
// }, 200L, TimeUnit.MILLISECONDS)
|
||||||
}
|
// }
|
||||||
|
|
||||||
fun getCal() {
|
fun getCal() {
|
||||||
Executors.newSingleThreadScheduledExecutor().schedule({
|
Executors.newSingleThreadScheduledExecutor().schedule({
|
||||||
@ -276,6 +274,7 @@ internal class LauncherActivity : CommonActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressLint("MissingSuperCall")
|
||||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||||
super.onConfigurationChanged(newConfig)
|
super.onConfigurationChanged(newConfig)
|
||||||
|
|
||||||
@ -284,13 +283,30 @@ internal class LauncherActivity : CommonActivity() {
|
|||||||
Blog.LOGE("onConfigurationChanged newConfig?.screenWidthDp >> ${newConfig?.screenWidthDp}")
|
Blog.LOGE("onConfigurationChanged newConfig?.screenWidthDp >> ${newConfig?.screenWidthDp}")
|
||||||
Blog.LOGE("onConfigurationChanged newConfig?.screenHeightDp >> ${newConfig?.screenHeightDp}")
|
Blog.LOGE("onConfigurationChanged newConfig?.screenHeightDp >> ${newConfig?.screenHeightDp}")
|
||||||
isOpendFold = (newConfig.screenWidthDp * 1.1f) > newConfig.screenHeightDp
|
isOpendFold = (newConfig.screenWidthDp * 1.1f) > newConfig.screenHeightDp
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// override fun onKeyClick(keyCode: Int): Boolean {
|
||||||
|
// when (keyCode) {
|
||||||
|
// KeyEvent.KEYCODE_VOLUME_DOWN -> {
|
||||||
|
// actionNextEvent()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// KeyEvent.KEYCODE_VOLUME_UP -> {
|
||||||
|
// actionPrevEvent()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// KeyEvent.KEYCODE_VOLUME_MUTE -> {
|
||||||
|
// actionNextEvent()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// return super.onKeyClick(keyCode)
|
||||||
|
// }
|
||||||
var actionButtonPressX = 0f
|
var actionButtonPressX = 0f
|
||||||
var actionButtonPressY = 0f
|
var actionButtonPressY = 0f
|
||||||
var onExit = false
|
var onExit = false
|
||||||
var lastAction = MotionEvent.ACTION_HOVER_EXIT
|
var lastAction = MotionEvent.ACTION_HOVER_EXIT
|
||||||
override fun dispatchKeyEvent(ev: KeyEvent): Boolean {
|
override fun dispatchKeyEvent(ev: KeyEvent): Boolean {
|
||||||
|
|
||||||
Blog.LOGE("dispatch ev?.device?.name >>> ${ev?.device?.name}")
|
Blog.LOGE("dispatch ev?.device?.name >>> ${ev?.device?.name}")
|
||||||
if (ev?.device?.name?.contains("SM-031N Mouse") == true) {
|
if (ev?.device?.name?.contains("SM-031N Mouse") == true) {
|
||||||
|
|
||||||
@ -366,6 +382,25 @@ internal class LauncherActivity : CommonActivity() {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if(MotionEvent.ACTION_UP.equals(ev?.action ?: MotionEvent.ACTION_CANCEL) == true) {
|
||||||
|
when (ev.keyCode) {
|
||||||
|
KeyEvent.KEYCODE_VOLUME_DOWN -> {
|
||||||
|
|
||||||
|
novels?.actionNextEvent()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyEvent.KEYCODE_VOLUME_UP -> {
|
||||||
|
novels?.actionPrevEvent()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else -> return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
return super.dispatchKeyEvent(ev)
|
return super.dispatchKeyEvent(ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,31 +576,68 @@ internal class LauncherActivity : CommonActivity() {
|
|||||||
// }
|
// }
|
||||||
super.onNewIntent(intent)
|
super.onNewIntent(intent)
|
||||||
}
|
}
|
||||||
lateinit var home : LauncherHome
|
var home : LauncherHome? = null
|
||||||
|
var novels : Novels? = null
|
||||||
@SuppressLint("NewApi", "MissingPermission")
|
@SuppressLint("NewApi", "MissingPermission")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
installSplashScreen()
|
installSplashScreen()
|
||||||
|
lActivity = this
|
||||||
mWorkManager = WorkManager.getInstance(this)
|
mWorkManager = WorkManager.getInstance(this)
|
||||||
DynamicColors.applyToActivityIfAvailable(this)
|
DynamicColors.applyToActivityIfAvailable(this)
|
||||||
lActivity = this
|
|
||||||
|
|
||||||
settingsPrefs = getSharedPreferences(PREFS_SETTINGS, 0)
|
settingsPrefs = getSharedPreferences(PREFS_SETTINGS, 0)
|
||||||
AppCompatDelegate.setDefaultNightMode(settingsPrefs.getInt(KEY_APPLICATION_THEME, MODE_NIGHT_FOLLOW_SYSTEM))
|
// AppCompatDelegate.setDefaultNightMode(settingsPrefs.getInt(KEY_APPLICATION_THEME, MODE_NIGHT_FOLLOW_SYSTEM))
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
|
||||||
binding = LauncherActivityBinding.inflate(layoutInflater)
|
binding = LauncherActivityBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
appWidgetManager = AppWidgetManager.getInstance(applicationContext)
|
appWidgetManager = AppWidgetManager.getInstance(applicationContext)
|
||||||
appWidgetHost = WidgetHost(applicationContext, widgetHostId)
|
appWidgetHost = WidgetHost(applicationContext, widgetHostId)
|
||||||
appWidgetHost?.startListening()
|
appWidgetHost?.startListening()
|
||||||
HeadsetActionButtonReceiver.register(this)
|
HeadsetActionButtonReceiver.register(this)
|
||||||
// MediaBrowserCompat.ConnectionCallback
|
|
||||||
/* if this is the first launch,
|
|
||||||
then remember the event and show the welcome dialog */
|
|
||||||
|
|
||||||
home = binding.home.getFragment<LauncherHome>()
|
|
||||||
|
binding.tabs.setOnCheckedChangeListener { g, id ->
|
||||||
|
when(id) {
|
||||||
|
R.id.feeds -> {
|
||||||
|
if(binding.feeds.isChecked) {
|
||||||
|
if (home == null) {
|
||||||
|
home = binding.home.getFragment<LauncherHome>()
|
||||||
|
}
|
||||||
|
binding.home.visibility = View.VISIBLE
|
||||||
|
binding.booktoki.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
binding.home.visibility = View.GONE
|
||||||
|
if (novels == null) {
|
||||||
|
novels = binding.booktoki.getFragment<Novels>()
|
||||||
|
|
||||||
|
} else {
|
||||||
|
novels?.onResume()
|
||||||
|
}
|
||||||
|
binding.booktoki.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
R.id.book ->{
|
||||||
|
if(binding.book.isChecked) {
|
||||||
|
binding.home.visibility = View.GONE
|
||||||
|
if (novels == null) {
|
||||||
|
novels = binding.booktoki.getFragment<Novels>()
|
||||||
|
} else {
|
||||||
|
novels?.onResume()
|
||||||
|
}
|
||||||
|
binding.booktoki.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
if (home == null) {
|
||||||
|
home = binding.home.getFragment<LauncherHome>()
|
||||||
|
}
|
||||||
|
binding.home.visibility = View.VISIBLE
|
||||||
|
binding.booktoki.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* handle navigation back events */
|
/* handle navigation back events */
|
||||||
handleBackPress()
|
handleBackPress()
|
||||||
@ -592,13 +664,38 @@ internal class LauncherActivity : CommonActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateLocationService()
|
updateLocationService()
|
||||||
|
binding.book.isChecked = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initGeckoRuntime() {
|
||||||
|
if (sRuntime == null) {
|
||||||
|
try {
|
||||||
|
sRuntime = GeckoRuntime.create(this, GeckoRuntimeSettings.Builder().extensionsProcessEnabled(true)
|
||||||
|
.extensionsWebAPIEnabled(true).experimentDelegate(experimentDelegate)
|
||||||
|
.remoteDebuggingEnabled(true).build())
|
||||||
|
} catch (e : Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTouchEvent(event: MotionEvent?): Boolean {
|
||||||
|
Blog.LOGE("event >>> ${event}")
|
||||||
|
return super.onTouchEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
|
||||||
|
|
||||||
appWidgetHost?.stopListening()
|
appWidgetHost?.stopListening()
|
||||||
|
try {
|
||||||
|
sRuntime?.shutdown()
|
||||||
|
sRuntime = null
|
||||||
|
} catch (e: Exception) {e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
var blutoothManager : BluetoothManager? = null
|
var blutoothManager : BluetoothManager? = null
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
@ -608,132 +705,19 @@ internal class LauncherActivity : CommonActivity() {
|
|||||||
blutoothManager?.initBluetoothAdapter()
|
blutoothManager?.initBluetoothAdapter()
|
||||||
blutoothManager?.blueToothState()
|
blutoothManager?.blueToothState()
|
||||||
blutoothManager?.getPairedDevices()
|
blutoothManager?.getPairedDevices()
|
||||||
Blog.LOGE("LauncherActivity onStart()")
|
|
||||||
statusBarView()
|
statusBarView()
|
||||||
setBgColor()
|
setBgColor()
|
||||||
welcomeDialog()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O_MR1)
|
@RequiresApi(Build.VERSION_CODES.O_MR1)
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
refreshFeeds()
|
||||||
blutoothManager?.getPairedDevices()
|
blutoothManager?.getPairedDevices()
|
||||||
Blog.LOGE("LauncherActivity onResume")
|
Blog.LOGE("LauncherActivity onResume")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun welcomeDialog() {
|
|
||||||
|
|
||||||
var needAsk = if (
|
|
||||||
this.checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.RECEIVE_MMS) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|
|
||||||
) {
|
|
||||||
true
|
|
||||||
} else false
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
||||||
if (!isExternalStorageManager()) {
|
|
||||||
needAsk = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val cn = ComponentName(this, NLService::class.java)
|
|
||||||
val n = applicationContext.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
if (n.isNotificationListenerAccessGranted(cn)) {
|
|
||||||
} else {
|
|
||||||
needAsk = true
|
|
||||||
}
|
|
||||||
getSharedPreferences(PREFS_FIRST_LAUNCH, 0).let {
|
|
||||||
if (it.getBoolean(KEY_FIRST_LAUNCH, true) || needAsk) {
|
|
||||||
it.edit().putBoolean(KEY_FIRST_LAUNCH, false).apply()
|
|
||||||
MaterialAlertDialogBuilder(this)
|
|
||||||
.setTitle(R.string.welcome)
|
|
||||||
.setMessage(R.string.welcome_description)
|
|
||||||
.setPositiveButton(R.string.got_it) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
askPermissions()
|
|
||||||
}.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!needAsk) {
|
|
||||||
refreshDeviceData()
|
|
||||||
refreshFeeds()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ask for the permissions */
|
|
||||||
private fun askPermissions() {
|
|
||||||
/* phone permission */
|
|
||||||
val cn = ComponentName(this, NLService::class.java)
|
|
||||||
val n = applicationContext.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
|
|
||||||
if (
|
|
||||||
this.checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.RECEIVE_MMS) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED ||
|
|
||||||
this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|
|
||||||
|
|
||||||
) {
|
|
||||||
this.requestPermissions(arrayOf(
|
|
||||||
Manifest.permission.BLUETOOTH_CONNECT,
|
|
||||||
Manifest.permission.READ_CALENDAR,
|
|
||||||
Manifest.permission.WRITE_CALENDAR,
|
|
||||||
Manifest.permission.READ_CONTACTS,
|
|
||||||
Manifest.permission.READ_CALL_LOG,
|
|
||||||
Manifest.permission.CALL_PHONE,
|
|
||||||
Manifest.permission.READ_SMS,
|
|
||||||
Manifest.permission.READ_PHONE_STATE,
|
|
||||||
Manifest.permission.RECEIVE_MMS,
|
|
||||||
Manifest.permission.RECEIVE_SMS,
|
|
||||||
Manifest.permission.ACCESS_COARSE_LOCATION,
|
|
||||||
Manifest.permission.ACCESS_BACKGROUND_LOCATION,
|
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
|
||||||
Manifest.permission.CALL_PHONE,
|
|
||||||
Manifest.permission.READ_SMS), 1)
|
|
||||||
}
|
|
||||||
/* modify system settings */
|
|
||||||
if (!Settings.System.canWrite(this)) {
|
|
||||||
this.startActivity(
|
|
||||||
Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS)
|
|
||||||
.setData(Uri.parse("package:" + this.packageName))
|
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
)
|
|
||||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
||||||
if (!isExternalStorageManager()) {
|
|
||||||
try {
|
|
||||||
startActivityForResult(Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).apply {
|
|
||||||
data = Uri.parse(String.format("package:%s", applicationContext.packageName))
|
|
||||||
}, 300)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
startActivityForResult(Intent().apply {
|
|
||||||
action = Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
|
|
||||||
}, 300)
|
|
||||||
}
|
|
||||||
}else if (!n.isNotificationListenerAccessGranted(cn)) {
|
|
||||||
val intent = Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val appDrawer by lazy { AppDrawer() }
|
val appDrawer by lazy { AppDrawer() }
|
||||||
@ -776,14 +760,10 @@ internal class LauncherActivity : CommonActivity() {
|
|||||||
private fun handleBackPress() {
|
private fun handleBackPress() {
|
||||||
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
|
if (binding.booktoki.isVisible) {
|
||||||
// if (binding.feeds.visibility == View.VISIBLE) {
|
finish()
|
||||||
// switchFeeds()
|
} else {
|
||||||
// } else
|
finish()
|
||||||
if (binding.appDrawer.visibility == View.VISIBLE) {
|
|
||||||
switchAppDrawer()
|
|
||||||
} else if (binding.home.visibility == View.VISIBLE) {
|
|
||||||
// switchAppDrawer()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -804,313 +784,33 @@ internal class LauncherActivity : CommonActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val experimentDelegate = object : ExperimentDelegate {
|
||||||
|
override fun onGetExperimentFeature(feature: String): GeckoResult<JSONObject?> {
|
||||||
|
Blog.LOGE("onGetExperimentFeature $feature")
|
||||||
|
return super.onGetExperimentFeature(feature)
|
||||||
|
}
|
||||||
|
|
||||||
class EndCallReceiver : BroadcastReceiver() {
|
override fun onRecordExposureEvent(feature: String): GeckoResult<Void?> {
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
Blog.LOGE("onRecordExposureEvent $feature")
|
||||||
Blog.LOGE("EndCallReceiver >>> ${intent}")
|
return super.onRecordExposureEvent(feature)
|
||||||
val phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE) ?: return
|
}
|
||||||
if (phoneState == TelephonyManager.EXTRA_STATE_IDLE) {
|
|
||||||
refreshDeviceData()
|
override fun onRecordExperimentExposureEvent(
|
||||||
}
|
feature: String,
|
||||||
|
slug: String
|
||||||
|
): GeckoResult<Void?> {
|
||||||
|
Blog.LOGE("onRecordExperimentExposureEvent $feature , $slug")
|
||||||
|
return super.onRecordExperimentExposureEvent(feature, slug)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRecordMalformedConfigurationEvent(
|
||||||
|
feature: String,
|
||||||
|
part: String
|
||||||
|
): GeckoResult<Void?> {
|
||||||
|
Blog.LOGE("onRecordMalformedConfigurationEvent $feature , $part")
|
||||||
|
return super.onRecordMalformedConfigurationEvent(feature, part)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class SMSReceiver : BroadcastReceiver() {
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
|
||||||
Blog.LOGE("SMSReceiver >>> ${intent}")
|
|
||||||
refreshDeviceData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun openDrive(gmmIntentUri : Uri, pakage : String? = null) {
|
|
||||||
val mapIntent = Intent(Intent.ACTION_MEDIA_SHARED, gmmIntentUri)
|
|
||||||
pakage?.let {
|
|
||||||
mapIntent.setPackage(pakage)
|
|
||||||
}
|
|
||||||
startActivity(mapIntent)
|
|
||||||
}
|
|
||||||
|
|
||||||
var callBack : CommadCallabck? = null
|
|
||||||
var isF = false
|
|
||||||
// fun doWebParseStart(url : String, callBack :CommadCallabck?) {
|
|
||||||
// isF = false
|
|
||||||
// this.callBack = callBack
|
|
||||||
// binding.searcher01.post { binding.searcher01.visibility = View.VISIBLE }
|
|
||||||
// BLog.LOGE("binding.otherCheck before ThreadRun")
|
|
||||||
// binding.searcher01.webViewClient = object : WebViewClient() {
|
|
||||||
// override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
|
|
||||||
// BLog.LOGE("binding.otherCheck before ${url}")
|
|
||||||
// if ((url?.contains("guru") == true || url?.contains("missav") == true) && !isF) {
|
|
||||||
// BLog.LOGE("binding.otherCheck before reload")
|
|
||||||
// view?.loadUrl(url!!)
|
|
||||||
// isF = true
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
|
|
||||||
// BLog.LOGE("binding.otherCheck searcher01 in onPageStarted ${url}")
|
|
||||||
// super.onPageStarted(view, url, favicon)
|
|
||||||
// }
|
|
||||||
// override fun onReceivedError(
|
|
||||||
// view: WebView?,
|
|
||||||
// request: WebResourceRequest?,
|
|
||||||
// error: WebResourceError?
|
|
||||||
// ) {
|
|
||||||
//// super.onReceivedError(view, request, error)
|
|
||||||
// }
|
|
||||||
// override fun onReceivedSslError(
|
|
||||||
// view: WebView?,
|
|
||||||
// handler: SslErrorHandler?,
|
|
||||||
// error: SslError?
|
|
||||||
// ) {
|
|
||||||
// handler?.proceed()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onPageFinished(view: WebView?, url: String?) {
|
|
||||||
// super.onPageFinished(view, url)
|
|
||||||
// lastedFinishedPageUrl = url ?: ""
|
|
||||||
// BLog.LOGE("binding.otherCheck searcher01 in onPageFinished ${url}")
|
|
||||||
// //lastedFinishedPageUrl?.length ?: 0 > 10 &&
|
|
||||||
//// if(url?.startsWith("https://") == true) {
|
|
||||||
//// if (url?.contains("guru", true) == true) {
|
|
||||||
//// isF = true
|
|
||||||
//// view?.loadUrl(url)
|
|
||||||
//// }
|
|
||||||
// if (url?.contains("youtube", false) == true) {
|
|
||||||
// view?.evaluateJavascript(
|
|
||||||
// "function getAll() {\n" +
|
|
||||||
// " MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
|
|
||||||
// " };getAll()"
|
|
||||||
// ) { result ->
|
|
||||||
// (result as? String)?.let {}
|
|
||||||
// }
|
|
||||||
// } else if(url?.contains("translate.google.com") == true) {
|
|
||||||
// binding.searcher01.postDelayed({
|
|
||||||
// binding.searcher01.evaluateJavascript(
|
|
||||||
// "function getAll() {\n" +
|
|
||||||
// " MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
|
|
||||||
// " };getAll()"
|
|
||||||
// ) { result ->
|
|
||||||
// (result as? String)?.let {}
|
|
||||||
// }
|
|
||||||
// }, 6000L)
|
|
||||||
// } else if (url?.contains("guru", true) == true) {
|
|
||||||
// if (!isF) {
|
|
||||||
// binding.searcher01.postDelayed({
|
|
||||||
// view?.loadUrl(url)
|
|
||||||
// isF = true
|
|
||||||
// },5000)
|
|
||||||
// } else {
|
|
||||||
// binding.searcher01.postDelayed({
|
|
||||||
// binding.searcher01.evaluateJavascript(
|
|
||||||
// "function getAll() {\n" +
|
|
||||||
// " MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
|
|
||||||
// " };getAll()"
|
|
||||||
// ) { result ->
|
|
||||||
// (result as? String)?.let {}
|
|
||||||
// }
|
|
||||||
// }, 10000L)
|
|
||||||
// }
|
|
||||||
// }else {
|
|
||||||
// //
|
|
||||||
// view?.evaluateJavascript(
|
|
||||||
// "function getAll() {\n" +
|
|
||||||
// " MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
|
|
||||||
// " };getAll()"
|
|
||||||
// ) { result ->
|
|
||||||
// (result as? String)?.let {}
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (isF) this@LauncherActivity.callBack?.collectComplete()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// WebView.setWebContentsDebuggingEnabled(false)
|
|
||||||
// binding.searcher01.apply {
|
|
||||||
//// Jsoup.connect("https://missav.com/dm11/ko").userAgent()
|
|
||||||
//// .timeout(30000).get()?.apply {
|
|
||||||
//// BLog.LOGE("Jsoup.connect(missAv).get() ${this}")
|
|
||||||
//// }
|
|
||||||
// try {
|
|
||||||
// this.removeJavascriptInterface("MyJavaScriptInterface")
|
|
||||||
// }catch (e :Exception) {}
|
|
||||||
// this.addJavascriptInterface(MyJavaScriptInterface(this),"MyJavaScriptInterface")
|
|
||||||
// setBackgroundColor(Color.WHITE) // 백그라운드 색상 설정
|
|
||||||
// setLayerType(View.LAYER_TYPE_SOFTWARE, null) // 랜더링 이슈 해결
|
|
||||||
// try {
|
|
||||||
// settings.apply {
|
|
||||||
// userAgentString = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
|
|
||||||
// javaScriptEnabled = true // 자바스크립트 사용 가능하도록 설정
|
|
||||||
// loadWithOverviewMode = true // 전체 웹페이지를 화면에 맞게 로드
|
|
||||||
// useWideViewPort = true // 화면에 맞게 페이지 확대/축소
|
|
||||||
// domStorageEnabled = true // DOM 저장소 사용 가능하도록 설정
|
|
||||||
// setSupportMultipleWindows(true)
|
|
||||||
// javaScriptCanOpenWindowsAutomatically = true // 팝업창 차단 해제
|
|
||||||
// cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK
|
|
||||||
// textZoom = 100 // system 에 의한 글꼴 변형 방지
|
|
||||||
// defaultTextEncodingName = "UTF-8" // 인코딩 설정
|
|
||||||
// allowContentAccess = true // 웹뷰를 통해 content url에 접근할지 여부
|
|
||||||
// layoutAlgorithm = WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING // 웹페이지의 레이아웃을 화면에 맞게 자동으로 조정
|
|
||||||
// }
|
|
||||||
// } catch (ignore: NoSuchMethodError) {
|
|
||||||
//
|
|
||||||
// }.apply {
|
|
||||||
// loadUrl(url) // 웹페이지 연결
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
var maxDate : Long = Long.MIN_VALUE
|
|
||||||
var minDate : Long = Long.MAX_VALUE
|
|
||||||
val triple = 1000L * 60L * 60L * 24L * 2L
|
|
||||||
val simpldateFormat = SimpleDateFormat("d MMM, yy", Locale.US)
|
|
||||||
// fun jGuruToday(doc: Document) {
|
|
||||||
// var temp = arrayListOf<RssData>()
|
|
||||||
// doc.getElementsByTag("li").forEach {
|
|
||||||
// if (it.getElementsByTag("img").size > 0) {
|
|
||||||
// var title = it.getElementsByTag("a").get(0).attr("title")
|
|
||||||
// var model = title.replace("[", "").split("]")[0]
|
|
||||||
// var pageLink = it.getElementsByTag("a").get(0).attr("href")
|
|
||||||
// var imgg = it.getElementsByTag("img").get(0).attr("src")
|
|
||||||
// var actor = if (it.getElementsByClass("wpptax").size > 0 )it.getElementsByClass("wpptax").get(0).text() else ""
|
|
||||||
// if (pageLink.length > 0 && imgg.length > 0 && title.length > 0 && model.length > 0) {
|
|
||||||
// temp.add(
|
|
||||||
// JGuru(
|
|
||||||
// model = model,
|
|
||||||
// title = title,
|
|
||||||
// pageLink = pageLink,
|
|
||||||
// image = imgg,
|
|
||||||
// tags = actor,
|
|
||||||
// date = beforeDay(Date(),3) + 360000
|
|
||||||
// ).getRssData()
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }.apply {
|
|
||||||
// this@LauncherActivity.callBack?.collectComplete()
|
|
||||||
// WorkersDb.insertBulkInteface(temp)
|
|
||||||
// Toast.makeText(this@LauncherActivity,
|
|
||||||
// "Stored rank data", Toast.LENGTH_LONG).show()
|
|
||||||
// binding.searcher01?.post { binding.searcher01.loadUrl(jGuruMain) }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// fun jGuruMain(doc: Document) {
|
|
||||||
// var temp = arrayListOf<RssData>()
|
|
||||||
// val prevUrl = doc.getElementsByClass("prev").get(0).getElementsByAttribute("href").get(0).attr("href")
|
|
||||||
// doc.getElementsByClass("column").forEach {
|
|
||||||
// var title = it.getElementsByAttribute("title").get(0).text()
|
|
||||||
// var model = title.replace("[","").split("]")[0]
|
|
||||||
// var pageLink = it.getElementsByClass("imgg").get(0).getElementsByAttribute("href").get(0).attr("href")
|
|
||||||
// var imgg = it.getElementsByClass("imgg").get(0).getElementsByAttribute("src").get(0).attr("src")
|
|
||||||
// var tags = it.getElementsByClass("tags").get(0).text()
|
|
||||||
// var date = it.getElementsByClass("date").get(0).text()
|
|
||||||
// var regDate = simpldateFormat.parse(date).time
|
|
||||||
//
|
|
||||||
// minDate = Math.min(minDate,regDate)
|
|
||||||
// maxDate = Math.max(maxDate,regDate)
|
|
||||||
// temp.add(JGuru(model = model, title = title, pageLink = pageLink, image = imgg, tags = tags, date = make0H(simpldateFormat.parse(date))).getRssData())
|
|
||||||
// }.apply {
|
|
||||||
// var itemC = 0
|
|
||||||
// WorkersDb.insertBulkInteface(temp)
|
|
||||||
// callBack?.onConsoleLog("Stored data :: ${simpldateFormat.format(Date(minDate))} ~ ${simpldateFormat.format(Date(maxDate))} set in ${itemC}")
|
|
||||||
// binding.searcher01?.post { binding.searcher01.loadData("<html></html>",null,null) }
|
|
||||||
// this@LauncherActivity.callBack?.collectComplete()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fun jGuruTag(doc: Document) {
|
|
||||||
// doc.getElementsByTag("ul").forEach {
|
|
||||||
// it.children().forEach {
|
|
||||||
// if (it.tag().name.contains("li")) {
|
|
||||||
// listTags.add(
|
|
||||||
// jGuruTag(
|
|
||||||
// tagTitle = it.getElementsByTag("a").get(0).text(),
|
|
||||||
// link = it.getElementsByTag("a").get(0).attr("href")
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }.apply {
|
|
||||||
// binding.searcher01?.post { binding.searcher01.loadData("<html></html>",null,null) }
|
|
||||||
// this@LauncherActivity.callBack?.collectComplete()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fun switchFeeds() {
|
|
||||||
// startActivity(Intent(this,Feeds::class.java))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// inner class MyJavaScriptInterface(val webView: WebView) {
|
|
||||||
// @JavascriptInterface
|
|
||||||
// fun sendValueFromHtml(result: String) {
|
|
||||||
// if (lastedFinishedPageUrl.contains(jGuruMain)) {
|
|
||||||
// var htmlString = result.replace("\\u003","<")
|
|
||||||
// val doc: Document = Jsoup.parse(htmlString)
|
|
||||||
// if (lastedFinishedPageUrl?.contains("page") == true || lastedFinishedPageUrl?.equals(jGuruMain) == true) {
|
|
||||||
// jGuruMain(doc)
|
|
||||||
// } else if (lastedFinishedPageUrl?.contains("/most-watched-rank") == true) {
|
|
||||||
// jGuruToday(doc)
|
|
||||||
// } else if (lastedFinishedPageUrl?.contains("/tags/") == true) {
|
|
||||||
// jGuruTag(doc)
|
|
||||||
// }
|
|
||||||
// } else if (lastedFinishedPageUrl?.contains("missav")==true) {
|
|
||||||
// val doc: Document = Jsoup.parse(result)
|
|
||||||
// var temp = arrayListOf<RssData>()
|
|
||||||
// doc.getElementsByClass("thumbnail group").forEach { miss_li ->
|
|
||||||
// if (miss_li.getElementsByTag("img").size > 0 && miss_li.getElementsByTag("img").get(0).attr("data-src").length > 10 &&
|
|
||||||
// miss_li.getElementsByTag("img").get(0).attr("data-src").startsWith("https") &&
|
|
||||||
// miss_li.getElementsByTag("img").get(0).attr("data-src").endsWith("jpg")) {
|
|
||||||
// var link = if(miss_li.getElementsByTag("a").size > 0) miss_li.getElementsByTag("a").get(0).attr("href") else ""
|
|
||||||
// var title = miss_li.getElementsByClass("text-secondary group-hover:text-primary").getT()
|
|
||||||
// var thumb = miss_li.getElementsByTag("img").get(0).attr("data-src")
|
|
||||||
// var desc = miss_li.getElementsByTag("img").get(0).text()
|
|
||||||
// MissD().apply {
|
|
||||||
// this.link = link
|
|
||||||
// this.title = title
|
|
||||||
// this.thumb = thumb
|
|
||||||
// this.desc = desc
|
|
||||||
// temp.add(this.getRssData())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }.apply {
|
|
||||||
// WorkersDb.insertBulkData(temp)
|
|
||||||
// }
|
|
||||||
// } else if(lastedFinishedPageUrl?.contains("https://translate.google.com") == true){
|
|
||||||
// callBackHandler.removeCallbacks(postNext)
|
|
||||||
// val doc: Document = Jsoup.parse(result)
|
|
||||||
// doc.getElementsByTag("span").forEach { span ->
|
|
||||||
//// BLog.LOGE("on getHangule ${span.text()}")
|
|
||||||
// if(span.hasAttr("jsaction") &&
|
|
||||||
// span.attr("jsaction").contains("mouseout") &&
|
|
||||||
// span.attr("jsaction").contains("contextmenu") &&
|
|
||||||
// span.attr("jsaction").contains("click") &&
|
|
||||||
// span.attr("jsaction").contains("mouseover")
|
|
||||||
// ) {
|
|
||||||
// BLog.LOGE("on getHangule $span")
|
|
||||||
// val resultString = span.text()
|
|
||||||
// if (resultString != null && resultString.length > 0) {
|
|
||||||
// callBackHandler.removeCallbacks(postNext)
|
|
||||||
// callBack?.onConsoleLog("result::${span.text()}")
|
|
||||||
// callBack = null
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }.apply {
|
|
||||||
// callBackHandler.removeCallbacks(postNext)
|
|
||||||
// callBackHandler.postDelayed(postNext,25000L)
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// val doc: Document = Jsoup.parse(result)
|
|
||||||
// callBack?.onConsoleLog("lastedFinishedPageUrl >>> ${doc}")
|
|
||||||
// }
|
|
||||||
// BLog.LOGE("binding.otherCheck after ThreadRun")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
var postNext : Runnable = Runnable{
|
|
||||||
callBack?.collectComplete()
|
|
||||||
}
|
|
||||||
|
|
||||||
val callBackHandler = Handler(Looper.getMainLooper())
|
val callBackHandler = Handler(Looper.getMainLooper())
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1127,18 +827,6 @@ fun beforeDay(date: Date): Long {
|
|||||||
return cal.timeInMillis
|
return cal.timeInMillis
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CommadCallabck {
|
|
||||||
fun onConsoleLog(log : String)
|
|
||||||
fun collectComplete()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun openNews(schemeString : String) {
|
|
||||||
val gmmIntentUri = Uri.parse(schemeString)
|
|
||||||
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
|
||||||
mapIntent.setPackage("com.android.chrome")
|
|
||||||
lActivity?.startActivity(mapIntent)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun openClient(url : String){
|
fun openClient(url : String){
|
||||||
val browserIntent = Intent(
|
val browserIntent = Intent(
|
||||||
Intent.ACTION_VIEW, Uri.parse(
|
Intent.ACTION_VIEW, Uri.parse(
|
||||||
@ -1146,11 +834,9 @@ fun openClient(url : String){
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
browserIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
|
browserIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
|
||||||
// browserIntent.setPackage("org.chromium.webapk.a74a80967bc356126_v2")
|
|
||||||
// org.chromium.webapk.a74a80967bc356126_v2/org.chromium.webapk.shell_apk.h2o.H2OOpaqueMainActivity
|
|
||||||
// browserIntent.setComponent(ComponentName("org.chromium.webapk.a74a80967bc356126_v2","org.chromium.webapk.shell_apk.h2o.H2OOpaqueMainActivity"))
|
|
||||||
lActivity?.startActivity(browserIntent)
|
lActivity?.startActivity(browserIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openYouTube(schemeString : String) {
|
fun openYouTube(schemeString : String) {
|
||||||
val gmmIntentUri = Uri.parse(schemeString)
|
val gmmIntentUri = Uri.parse(schemeString)
|
||||||
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
||||||
|
|||||||
@ -23,12 +23,19 @@ import android.content.ComponentCallbacks2
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.database.sqlite.SQLiteDatabase
|
import android.database.sqlite.SQLiteDatabase
|
||||||
import bums.lunatic.launcher.helpers.PrefHelper
|
import bums.lunatic.launcher.helpers.PrefHelper
|
||||||
|
import bums.lunatic.launcher.utils.Blog
|
||||||
import kr.lunaticbum.Base
|
import kr.lunaticbum.Base
|
||||||
|
import org.json.JSONObject
|
||||||
|
import org.mozilla.geckoview.ExperimentDelegate
|
||||||
|
import org.mozilla.geckoview.GeckoResult
|
||||||
|
import org.mozilla.geckoview.GeckoRuntime
|
||||||
|
import org.mozilla.geckoview.GeckoRuntimeSettings
|
||||||
|
|
||||||
|
|
||||||
internal class LunaticLauncher : Application() {
|
internal class LunaticLauncher : Application() {
|
||||||
companion object {
|
companion object {
|
||||||
var appContext : Context? = null
|
var appContext : LunaticLauncher? = null
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
@ -37,6 +44,8 @@ internal class LunaticLauncher : Application() {
|
|||||||
Base.initialize(this)
|
Base.initialize(this)
|
||||||
PrefHelper.initialize(this)
|
PrefHelper.initialize(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onTrimMemory(level: Int) {
|
override fun onTrimMemory(level: Int) {
|
||||||
super.onTrimMemory(level)
|
super.onTrimMemory(level)
|
||||||
// Picasso.
|
// Picasso.
|
||||||
|
|||||||
@ -21,9 +21,7 @@ package bums.lunatic.launcher.apps
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.ApplicationInfo
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.pm.ResolveInfo
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
@ -35,7 +33,6 @@ import android.view.inputmethod.InputMethodManager
|
|||||||
import androidx.core.widget.doOnTextChanged
|
import androidx.core.widget.doOnTextChanged
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import bums.lunatic.launcher.BuildConfig
|
import bums.lunatic.launcher.BuildConfig
|
||||||
import bums.lunatic.launcher.LauncherActivity
|
|
||||||
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
||||||
import bums.lunatic.launcher.common.CommonActivity
|
import bums.lunatic.launcher.common.CommonActivity
|
||||||
import bums.lunatic.launcher.common.letTrue
|
import bums.lunatic.launcher.common.letTrue
|
||||||
@ -55,7 +52,6 @@ import io.realm.kotlin.ext.query
|
|||||||
import io.realm.kotlin.query.RealmResults
|
import io.realm.kotlin.query.RealmResults
|
||||||
import io.realm.kotlin.query.Sort
|
import io.realm.kotlin.query.Sort
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
import java.text.Normalizer
|
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
package bums.lunatic.launcher.behavior
|
package bums.lunatic.launcher.behavior
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -13,12 +11,9 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import bums.lunatic.launcher.R
|
import bums.lunatic.launcher.R
|
||||||
import bums.lunatic.launcher.behavior.calendar.CalendarAdapter
|
|
||||||
import bums.lunatic.launcher.behavior.calendar.CalendarBean
|
import bums.lunatic.launcher.behavior.calendar.CalendarBean
|
||||||
import bums.lunatic.launcher.behavior.calendar.CalendarDateView
|
|
||||||
import bums.lunatic.launcher.behavior.calendar.CalendarFactory.getMonthOfDayList
|
import bums.lunatic.launcher.behavior.calendar.CalendarFactory.getMonthOfDayList
|
||||||
import bums.lunatic.launcher.behavior.calendar.CalendarUtil
|
import bums.lunatic.launcher.behavior.calendar.CalendarUtil
|
||||||
import bums.lunatic.launcher.behavior.calendar.CalendarView
|
|
||||||
import bums.lunatic.launcher.databinding.ItemCalendarBinding
|
import bums.lunatic.launcher.databinding.ItemCalendarBinding
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import android.util.AttributeSet
|
|||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.annotation.NonNull
|
import androidx.annotation.NonNull
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
|||||||
@ -3,19 +3,12 @@ package bums.lunatic.launcher.common
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.app.ComponentActivity
|
|
||||||
import bums.lunatic.launcher.R
|
|
||||||
import bums.lunatic.launcher.apps.SearchMenu
|
import bums.lunatic.launcher.apps.SearchMenu
|
||||||
import bums.lunatic.launcher.helpers.PrefBoolean
|
import bums.lunatic.launcher.helpers.PrefBoolean
|
||||||
import bums.lunatic.launcher.helpers.PrefHelper
|
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
import bums.lunatic.launcher.workers.LocationUpdateService
|
import bums.lunatic.launcher.workers.LocationUpdateService
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.reflect.TypeToken
|
import com.google.gson.reflect.TypeToken
|
||||||
import org.json.JSONArray
|
|
||||||
import org.json.JSONObject
|
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
@ -26,7 +19,6 @@ import java.io.InputStream
|
|||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.io.OutputStreamWriter
|
import java.io.OutputStreamWriter
|
||||||
import java.util.Base64
|
import java.util.Base64
|
||||||
import kotlin.system.exitProcess
|
|
||||||
|
|
||||||
|
|
||||||
abstract class CommonActivity : AppCompatActivity() {
|
abstract class CommonActivity : AppCompatActivity() {
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import android.media.AudioManager
|
|||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
import java.util.Timer
|
import java.util.Timer
|
||||||
import java.util.TimerTask
|
|
||||||
|
|
||||||
|
|
||||||
class HeadsetActionButtonReceiver : BroadcastReceiver() {
|
class HeadsetActionButtonReceiver : BroadcastReceiver() {
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
package bums.lunatic.launcher.helpers
|
package bums.lunatic.launcher.helpers
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import bums.lunatic.launcher.model.RssDataType
|
import bums.lunatic.launcher.model.RssDataType
|
||||||
import bums.lunatic.launcher.utils.Blog
|
|
||||||
import kr.lunaticbum.utils.preferences.PrefJsonConvert
|
|
||||||
import kr.lunaticbum.utils.preferences.PrefKey
|
import kr.lunaticbum.utils.preferences.PrefKey
|
||||||
import kr.lunaticbum.utils.preferences.PreferencesHelper
|
import kr.lunaticbum.utils.preferences.PreferencesHelper
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
|
|||||||
@ -16,8 +16,12 @@ import android.view.KeyEvent.KEYCODE_BUTTON_X
|
|||||||
import android.view.KeyEvent.KEYCODE_BUTTON_Y
|
import android.view.KeyEvent.KEYCODE_BUTTON_Y
|
||||||
import android.view.KeyEvent.KEYCODE_DPAD_DOWN
|
import android.view.KeyEvent.KEYCODE_DPAD_DOWN
|
||||||
import android.view.KeyEvent.KEYCODE_DPAD_UP
|
import android.view.KeyEvent.KEYCODE_DPAD_UP
|
||||||
|
import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime
|
||||||
|
import bums.lunatic.launcher.tokiz.view.BWebview
|
||||||
|
import bums.lunatic.launcher.tokiz.view.JxEvent
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.mozilla.gecko.util.ThreadUtils
|
import org.mozilla.gecko.util.ThreadUtils
|
||||||
import org.mozilla.geckoview.ExperimentDelegate
|
import org.mozilla.geckoview.ExperimentDelegate
|
||||||
@ -33,33 +37,47 @@ import org.mozilla.geckoview.WebExtension.PortDelegate
|
|||||||
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
|
import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate
|
||||||
import org.mozilla.geckoview.WebRequestError
|
import org.mozilla.geckoview.WebRequestError
|
||||||
|
|
||||||
class GeckoWeb : GeckoView {
|
class GeckoWeb : BWebview {
|
||||||
constructor(context: Context?) : super(context) {
|
constructor(context: Context?) : super(context) {
|
||||||
initWithContext(context)
|
buildWeb()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||||
initWithContext(context)
|
buildWeb()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadUrl(url: String) {
|
val mPortNam = "browser"
|
||||||
Blog.LOGE("url >>>> ${url}")
|
val extPath = "resource://android/assets/extensions/my_extension/"
|
||||||
if (url.split("//").size > 1) {
|
val extId = "messaging@booktoki468.com"
|
||||||
url.replace("//","/").replace("https:/","https://").let {
|
private fun buildWeb() {
|
||||||
Blog.LOGE("url >> ${url} , it >>> ${it}")
|
getRuntime()?.let {
|
||||||
this.session?.loadUri(url)
|
val session: GeckoSession = GeckoSession()
|
||||||
}
|
session.open(it)
|
||||||
} else {
|
this.setSession(session)
|
||||||
this.session?.loadUri(url)
|
session.contentDelegate = contentDelegate
|
||||||
}
|
session.progressDelegate = progressDelegate
|
||||||
|
session.navigationDelegate = navigationDelegate
|
||||||
currentRetryCount = 0;
|
it.webExtensionController.setAddonManagerDelegate(addonManagerDelegate)
|
||||||
}
|
session.mediaDelegate = mediaDelegate
|
||||||
val handle = object : Handler(Looper.getMainLooper()) {
|
session.mediaSessionDelegate = mediaSessionDelegate
|
||||||
override fun handleMessage(msg: Message) {
|
it.webExtensionController
|
||||||
if (msg.what == 0) {
|
.ensureBuiltIn(extPath, extId)
|
||||||
(msg.obj as? ReaderConfig)?.let {
|
.accept( // Register message delegate for background script
|
||||||
}
|
{ extension: WebExtension? ->
|
||||||
}
|
ThreadUtils.runOnUiThread(
|
||||||
|
Runnable {
|
||||||
|
if (extension != null) {
|
||||||
|
session.webExtensionController.setMessageDelegate(
|
||||||
|
extension,
|
||||||
|
messageDelegate,
|
||||||
|
mPortNam
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{ e: Throwable? -> Log.e("MessageDelegate", "Error registering WebExtension", e) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +90,17 @@ class GeckoWeb : GeckoView {
|
|||||||
val extPath = "resource://android/assets/extensions/my_extension/"
|
val extPath = "resource://android/assets/extensions/my_extension/"
|
||||||
val extId = "messaging@booktoki468.com"
|
val extId = "messaging@booktoki468.com"
|
||||||
}
|
}
|
||||||
|
fun sendScrollDown(isUp: Boolean) {
|
||||||
|
val message: JSONObject = JSONObject()
|
||||||
|
try {
|
||||||
|
message.put("type", "scrollDown")
|
||||||
|
message.put("isUpDown", if (isUp) +1 else -1)
|
||||||
|
} catch (ex: JSONException) {
|
||||||
|
throw RuntimeException(ex)
|
||||||
|
}
|
||||||
|
Blog.LOGE(Gson().toJson(message))
|
||||||
|
mPort?.postMessage(message)
|
||||||
|
}
|
||||||
|
|
||||||
var mExtension: WebExtension? = null
|
var mExtension: WebExtension? = null
|
||||||
var mSession: GeckoSession? = null
|
var mSession: GeckoSession? = null
|
||||||
@ -91,32 +120,7 @@ class GeckoWeb : GeckoView {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun initWithContext(context: Context?) {
|
|
||||||
context?.let { context ->
|
|
||||||
initGeckoRuntime(context)
|
|
||||||
mSession = GeckoSession()
|
|
||||||
mSession?.contentDelegate = contentDelegate
|
|
||||||
mSession?.progressDelegate = progressDelegate
|
|
||||||
mSession?.navigationDelegate = navigationDelegate
|
|
||||||
sRuntime?.apply {
|
|
||||||
webExtensionController.setAddonManagerDelegate(addonManagerDelegate)
|
|
||||||
webExtensionController.ensureBuiltIn(WebExtensionInfo.extPath, WebExtensionInfo.extId)
|
|
||||||
.accept( // Register message delegate for background script
|
|
||||||
{ extension: WebExtension? ->
|
|
||||||
ThreadUtils.runOnUiThread(Runnable { mSession?.let{session-> extension?.let { session.webExtensionController.setMessageDelegate(it,messageDelegate,WebExtensionInfo.mPortNam) }} })
|
|
||||||
},
|
|
||||||
{ e: Throwable? -> Log.e("MessageDelegate", "Error registering WebExtension", e) })
|
|
||||||
|
|
||||||
mSession?.mediaDelegate = mediaDelegate
|
|
||||||
mSession?.mediaSessionDelegate = mediaSessionDelegate
|
|
||||||
mSession?.open(sRuntime!!)
|
|
||||||
|
|
||||||
}.let {
|
|
||||||
this.setSession(mSession!!)
|
|
||||||
this.loadUrl("https://booktoki468.com") // Or any other URL...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val mediaDelegate = object : GeckoSession.MediaDelegate {
|
val mediaDelegate = object : GeckoSession.MediaDelegate {
|
||||||
override fun onRecordingStatusChanged(
|
override fun onRecordingStatusChanged(
|
||||||
session: GeckoSession,
|
session: GeckoSession,
|
||||||
@ -203,21 +207,6 @@ class GeckoWeb : GeckoView {
|
|||||||
super.onFullscreen(session, mediaSession, enabled, meta)
|
super.onFullscreen(session, mediaSession, enabled, meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun initGeckoRuntime(context : Context) {
|
|
||||||
if (sRuntime == null) {
|
|
||||||
try {
|
|
||||||
val settings: GeckoRuntimeSettings =
|
|
||||||
GeckoRuntimeSettings.Builder().extensionsProcessEnabled(true)
|
|
||||||
.extensionsWebAPIEnabled(true)
|
|
||||||
.experimentDelegate(experimentDelegate)
|
|
||||||
.remoteDebuggingEnabled(true).build()
|
|
||||||
|
|
||||||
sRuntime = GeckoRuntime.create(context, settings)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val experimentDelegate = object : ExperimentDelegate {
|
val experimentDelegate = object : ExperimentDelegate {
|
||||||
override fun onGetExperimentFeature(feature: String): GeckoResult<JSONObject?> {
|
override fun onGetExperimentFeature(feature: String): GeckoResult<JSONObject?> {
|
||||||
@ -261,12 +250,11 @@ class GeckoWeb : GeckoView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onPaintStatusReset(session: GeckoSession) {
|
override fun onPaintStatusReset(session: GeckoSession) {
|
||||||
Blog.LOGE("onPaintStatusReset")
|
|
||||||
super.onPaintStatusReset(session)
|
super.onPaintStatusReset(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFirstContentfulPaint(session: GeckoSession) {
|
override fun onFirstContentfulPaint(session: GeckoSession) {
|
||||||
Blog.LOGE("onFirstContentfulPaint")
|
|
||||||
super.onFirstContentfulPaint(session)
|
super.onFirstContentfulPaint(session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,13 +398,6 @@ class GeckoWeb : GeckoView {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun onDestroy() {
|
|
||||||
sRuntime = null
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun dispatchKeyEvent(ev: KeyEvent): Boolean {
|
override fun dispatchKeyEvent(ev: KeyEvent): Boolean {
|
||||||
Blog.LOGE("dispatch ev?.device?.name >>> ${ev?.device?.name}")
|
Blog.LOGE("dispatch ev?.device?.name >>> ${ev?.device?.name}")
|
||||||
if (ev?.device?.name?.contains("SM-031N Mouse") == true) {
|
if (ev?.device?.name?.contains("SM-031N Mouse") == true) {
|
||||||
@ -467,7 +448,6 @@ class GeckoWeb : GeckoView {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "DualScreenStatus"
|
private const val TAG = "DualScreenStatus"
|
||||||
var sRuntime: GeckoRuntime? = null
|
|
||||||
var currentRetryCount = 0
|
var currentRetryCount = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,107 +19,53 @@
|
|||||||
package bums.lunatic.launcher.home
|
package bums.lunatic.launcher.home
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Context.AUDIO_SERVICE
|
|
||||||
import android.content.DialogInterface
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.IntentFilter
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.PackageManager
|
import android.os.Build
|
||||||
import android.media.AudioManager
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.os.SystemClock
|
|
||||||
import android.provider.AlarmClock
|
|
||||||
import android.view.HapticFeedbackConstants
|
|
||||||
import android.view.KeyEvent
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.webkit.WebSettings.LOAD_NO_CACHE
|
|
||||||
import android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
|
|
||||||
import android.widget.CheckBox
|
|
||||||
import android.widget.EditText
|
|
||||||
import android.widget.TableRow
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.annotation.NonNull
|
import androidx.annotation.NonNull
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.biometric.BiometricPrompt
|
|
||||||
import androidx.core.view.children
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.viewpager2.widget.ViewPager2
|
|
||||||
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
||||||
import bums.lunatic.launcher.R
|
import bums.lunatic.launcher.R
|
||||||
import bums.lunatic.launcher.apps.AppsAdapter
|
|
||||||
import bums.lunatic.launcher.behavior.Behavior
|
|
||||||
import bums.lunatic.launcher.common.letTrue
|
import bums.lunatic.launcher.common.letTrue
|
||||||
import bums.lunatic.launcher.databinding.LauncherHomeBinding
|
import bums.lunatic.launcher.databinding.LauncherHomeBinding
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.BOTTOM_SHEET_TAG
|
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_LOCK_METHOD
|
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
||||||
import bums.lunatic.launcher.helpers.PrefBoolean
|
|
||||||
import bums.lunatic.launcher.helpers.UniUtils.Companion.expandNotificationPanel
|
|
||||||
import bums.lunatic.launcher.helpers.UniUtils.Companion.lockMethod
|
|
||||||
import bums.lunatic.launcher.home.adapters.NotificationItemAdapter
|
|
||||||
import bums.lunatic.launcher.home.adapters.RecentCallsAdapter
|
|
||||||
import bums.lunatic.launcher.home.adapters.RssItemAdapter
|
import bums.lunatic.launcher.home.adapters.RssItemAdapter
|
||||||
import bums.lunatic.launcher.home.adapters.SmsLogsAdapter
|
import bums.lunatic.launcher.home.adapters.RssItemAdapter.Companion.rssList
|
||||||
import bums.lunatic.launcher.home.adapters.SwipeToDeleteCallback
|
import bums.lunatic.launcher.home.adapters.SwipeToDeleteCallback
|
||||||
import bums.lunatic.launcher.home.adapters.WeatherAdapter
|
|
||||||
import bums.lunatic.launcher.home.adapters.WeatherDressAdatper
|
|
||||||
import bums.lunatic.launcher.home.adapters.WeatherHourlyAdapter
|
|
||||||
import bums.lunatic.launcher.model.AppInfo
|
|
||||||
import bums.lunatic.launcher.model.CurrentPlayItem
|
|
||||||
import bums.lunatic.launcher.model.Hour
|
|
||||||
import bums.lunatic.launcher.model.NotificationItem
|
|
||||||
import bums.lunatic.launcher.model.RssData
|
import bums.lunatic.launcher.model.RssData
|
||||||
import bums.lunatic.launcher.model.RssDataInterface
|
|
||||||
import bums.lunatic.launcher.model.RssDataType
|
import bums.lunatic.launcher.model.RssDataType
|
||||||
import bums.lunatic.launcher.model.WeatherForcast
|
import bums.lunatic.launcher.model.WeatherForcast
|
||||||
import bums.lunatic.launcher.model.WeatherInfoManager
|
import bums.lunatic.launcher.openClient
|
||||||
import bums.lunatic.launcher.qaccess.QuickAccess
|
import bums.lunatic.launcher.openReddit
|
||||||
import bums.lunatic.launcher.settings.SettingsActivity
|
import bums.lunatic.launcher.openYouTube
|
||||||
|
import bums.lunatic.launcher.tokiz.view.JxEvent
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
import bums.lunatic.launcher.utils.BitmapConverter
|
|
||||||
import bums.lunatic.launcher.utils.SimpleFingerGestures
|
import bums.lunatic.launcher.utils.SimpleFingerGestures
|
||||||
import bums.lunatic.launcher.utils.USAGT
|
|
||||||
import bums.lunatic.launcher.utils.beforeDay
|
import bums.lunatic.launcher.utils.beforeDay
|
||||||
import bums.lunatic.launcher.utils.beforeOneDay
|
import bums.lunatic.launcher.utils.beforeOneDay
|
||||||
import bums.lunatic.launcher.view.TableRadioGroup
|
|
||||||
import bums.lunatic.launcher.workers.LocationGetter
|
|
||||||
import bums.lunatic.launcher.workers.RecentCall
|
|
||||||
import bums.lunatic.launcher.workers.RecentSms
|
|
||||||
import bums.lunatic.launcher.workers.WorkersDb
|
import bums.lunatic.launcher.workers.WorkersDb
|
||||||
import bums.lunatic.launcher.workers.latitudeRange
|
import com.google.android.material.imageview.ShapeableImageView
|
||||||
import bums.lunatic.launcher.workers.longitudeRange
|
|
||||||
import io.realm.kotlin.UpdatePolicy
|
import io.realm.kotlin.UpdatePolicy
|
||||||
import io.realm.kotlin.ext.query
|
import io.realm.kotlin.ext.query
|
||||||
import io.realm.kotlin.notifications.InitialResults
|
|
||||||
import io.realm.kotlin.notifications.ResultsChange
|
import io.realm.kotlin.notifications.ResultsChange
|
||||||
import io.realm.kotlin.notifications.UpdatedResults
|
|
||||||
import io.realm.kotlin.query.RealmQuery
|
import io.realm.kotlin.query.RealmQuery
|
||||||
import io.realm.kotlin.query.RealmResults
|
import io.realm.kotlin.query.RealmResults
|
||||||
import io.realm.kotlin.query.Sort
|
import io.realm.kotlin.query.Sort
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.cancellable
|
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import okhttp3.Dns
|
|
||||||
import org.json.JSONArray
|
|
||||||
import org.json.JSONObject
|
|
||||||
import java.math.BigDecimal
|
|
||||||
import java.math.RoundingMode
|
|
||||||
import java.net.URLEncoder
|
|
||||||
import java.util.Calendar
|
|
||||||
import kotlin.jvm.java
|
|
||||||
|
|
||||||
|
|
||||||
internal class LauncherHome : Fragment() {
|
internal class LauncherHome : Fragment() {
|
||||||
@ -143,15 +89,164 @@ internal class LauncherHome : Fragment() {
|
|||||||
fun rssStateVote() = (lasted?.filter { it.vote == true }?.size ?: -1) == (lasted?.size ?: 0)
|
fun rssStateVote() = (lasted?.filter { it.vote == true }?.size ?: -1) == (lasted?.size ?: 0)
|
||||||
var lasted: List<RssData>? = null
|
var lasted: List<RssData>? = null
|
||||||
var infosJob: Job? = null
|
var infosJob: Job? = null
|
||||||
|
var rssId = ""
|
||||||
lateinit var mRssAdapter: RssItemAdapter
|
lateinit var mRssAdapter: RssItemAdapter
|
||||||
|
|
||||||
var mRssDataResult: RealmResults<RssData>? = null
|
var mRssDataResult: RealmResults<RssData>? = null
|
||||||
|
|
||||||
|
val mSimpleFingerGestures = SimpleFingerGestures(omfgl = object : SimpleFingerGestures.OnFingerGestureListener{
|
||||||
|
|
||||||
|
override fun onSwipeUp(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeDown(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeLeft(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeRight(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPinch(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("onPinch")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUnpinch(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDoubleTap(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLongPress(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("onLongPress")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("onClick")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
home = this
|
home = this
|
||||||
}
|
}
|
||||||
|
var targetList = arrayListOf<String>()
|
||||||
|
val dateViewClick = View.OnClickListener { v ->
|
||||||
|
Blog.LOGE("click view >> ${v}")
|
||||||
|
(v?.tag as? RssData)?.let { rss ->
|
||||||
|
WorkersDb.getRealm().apply {
|
||||||
|
writeBlocking {
|
||||||
|
rss.read = rss.read + 1
|
||||||
|
if(rss.getCho()?.length ?: 0 < 1) {
|
||||||
|
rss.chosung = rss.title
|
||||||
|
}
|
||||||
|
copyToRealm(rss,UpdatePolicy.ALL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
when(rss.category()) {
|
||||||
|
RssDataType.GURU,RssDataType.MOST,RssDataType.REDDIT_NSFW -> {
|
||||||
|
v.findViewById<ShapeableImageView>(R.id.circle_preview)?.let {
|
||||||
|
if (it.visibility == View.GONE) {
|
||||||
|
it.visibility = View.VISIBLE
|
||||||
|
it.postDelayed({
|
||||||
|
it.visibility = View.GONE
|
||||||
|
}, 2000L)
|
||||||
|
} else {
|
||||||
|
if (RssDataType.REDDIT_NSFW.equals(rss.category())) {
|
||||||
|
openReddit(rss.originPage())
|
||||||
|
} else {
|
||||||
|
openGecko(rss.originPage())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RssDataType.REDDIT -> {
|
||||||
|
openReddit(rss.originPage())
|
||||||
|
}
|
||||||
|
RssDataType.DOTAX -> {
|
||||||
|
openGecko(rss.originPage())
|
||||||
|
}
|
||||||
|
RssDataType.YOUTUBE -> { openYouTube(rss.originPage())
|
||||||
|
}
|
||||||
|
RssDataType.CLIEN -> {
|
||||||
|
openGecko(rss.originPage())
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
openGecko(rss.originPage())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun openGecko(originPage: String) {
|
||||||
|
rssId = originPage
|
||||||
|
targetList.clear()
|
||||||
|
|
||||||
|
var setString = hashSetOf<String>()
|
||||||
|
setString.addAll(rssList)
|
||||||
|
setString.removeAll { it.equals(rssId) }
|
||||||
|
|
||||||
|
targetList.addAll(setString)
|
||||||
|
binding.geckoWeb.loadUrl(rssId)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
@ -160,15 +255,75 @@ internal class LauncherHome : Fragment() {
|
|||||||
binding = LauncherHomeBinding.inflate(inflater, container, false)
|
binding = LauncherHomeBinding.inflate(inflater, container, false)
|
||||||
fragManager = lActivity!!.supportFragmentManager
|
fragManager = lActivity!!.supportFragmentManager
|
||||||
settingsPrefs = requireContext().getSharedPreferences(PREFS_SETTINGS, 0)
|
settingsPrefs = requireContext().getSharedPreferences(PREFS_SETTINGS, 0)
|
||||||
mRssAdapter = RssItemAdapter(requireContext())
|
mRssAdapter = RssItemAdapter(requireContext(),dateViewClick)
|
||||||
val decoration = DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL)
|
val decoration = DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL)
|
||||||
binding.infoList.addItemDecoration(decoration)
|
binding.infoList.addItemDecoration(decoration)
|
||||||
binding.infoList.visibility = View.VISIBLE
|
binding.infoList.visibility = View.VISIBLE
|
||||||
binding.infoList.adapter = mRssAdapter
|
binding.infoList.adapter = mRssAdapter
|
||||||
|
binding.infoList.setOnTouchListener { v,e ->
|
||||||
|
if (e.device.name?.contains("JX-12",true) == true) {
|
||||||
|
Blog.LOGE("touchEvent -> ${e}")
|
||||||
|
return@setOnTouchListener mSimpleFingerGestures.onTouch(v,e)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return@setOnTouchListener false
|
||||||
|
}
|
||||||
|
}
|
||||||
queryInfos()
|
queryInfos()
|
||||||
|
binding.geckoWeb.jxInteface = { jxEvent ->
|
||||||
|
when(jxEvent) {
|
||||||
|
JxEvent.SCROLL_UP -> binding.geckoWeb.sendScrollDown(false)
|
||||||
|
JxEvent.SCROLL_DOWN -> binding.geckoWeb.sendScrollDown(true)
|
||||||
|
JxEvent.ON_CLICK -> {
|
||||||
|
binding.geckoWeb.visibility = View.GONE
|
||||||
|
}
|
||||||
|
JxEvent.SWIPE_LEFT -> {
|
||||||
|
doNextPage()
|
||||||
|
}
|
||||||
|
JxEvent.SWIPE_RIGHT -> {
|
||||||
|
vote()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun vote(){
|
||||||
|
Blog.LOGE("Arrow Center Click")
|
||||||
|
WorkersDb.getRealm().apply {
|
||||||
|
writeBlocking {
|
||||||
|
val result = query<RssData>().query("originPage == $0", rssId).find()
|
||||||
|
if (result.size > 0) {
|
||||||
|
result.forEach { it.vote = true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doNextPage()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
|
fun doNextPage() {
|
||||||
|
WorkersDb.getRealm().apply {
|
||||||
|
writeBlocking {
|
||||||
|
val result = query<RssData>().query("originPage == $0", rssId).find()
|
||||||
|
if (result.size > 0) {
|
||||||
|
result.forEach {
|
||||||
|
it.read = it.read + nomoreShowCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
targetList.removeAll { it.equals(rssId) }
|
||||||
|
if (targetList.size > 0) {
|
||||||
|
rssId = targetList.removeFirst()
|
||||||
|
binding.geckoWeb.loadUrl(rssId)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(requireContext(), "없어 끄자", Toast.LENGTH_LONG).show()
|
||||||
|
binding.geckoWeb.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun clearJob(job : Job?) {
|
fun clearJob(job : Job?) {
|
||||||
try { job?.cancel() } catch (e: Exception) { e.printStackTrace() }
|
try { job?.cancel() } catch (e: Exception) { e.printStackTrace() }
|
||||||
try { System.gc() } catch (e: Exception) { e.printStackTrace() }
|
try { System.gc() } catch (e: Exception) { e.printStackTrace() }
|
||||||
@ -258,6 +413,7 @@ internal class LauncherHome : Fragment() {
|
|||||||
private fun enableSwipeToDeleteAndUndo() {
|
private fun enableSwipeToDeleteAndUndo() {
|
||||||
val swipeToDeleteCallback: SwipeToDeleteCallback =
|
val swipeToDeleteCallback: SwipeToDeleteCallback =
|
||||||
object : SwipeToDeleteCallback(requireContext()) {
|
object : SwipeToDeleteCallback(requireContext()) {
|
||||||
|
|
||||||
override fun onSwiped(@NonNull viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
override fun onSwiped(@NonNull viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||||
Blog.LOGE("onSwiped direction >>>> $direction")
|
Blog.LOGE("onSwiped direction >>>> $direction")
|
||||||
(viewHolder.itemView.tag as? RssData)?.let { rss ->
|
(viewHolder.itemView.tag as? RssData)?.let { rss ->
|
||||||
@ -290,7 +446,9 @@ internal class LauncherHome : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {}
|
else -> {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
binding.infoList.post { mRssAdapter.refresh() }
|
binding.infoList.post { mRssAdapter.refresh() }
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -2,15 +2,11 @@ package bums.lunatic.launcher.home
|
|||||||
|
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.print.PDFPrint
|
import android.print.PDFPrint
|
||||||
import android.provider.AlarmClock
|
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import android.view.HapticFeedbackConstants
|
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.KeyEvent.ACTION_UP
|
import android.view.KeyEvent.ACTION_UP
|
||||||
import android.view.KeyEvent.KEYCODE_BUTTON_A
|
import android.view.KeyEvent.KEYCODE_BUTTON_A
|
||||||
@ -29,28 +25,15 @@ import android.view.View
|
|||||||
import android.webkit.CookieManager
|
import android.webkit.CookieManager
|
||||||
import android.webkit.CookieSyncManager
|
import android.webkit.CookieSyncManager
|
||||||
import android.webkit.JavascriptInterface
|
import android.webkit.JavascriptInterface
|
||||||
import android.webkit.ValueCallback
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.core.view.postDelayed
|
import androidx.core.view.postDelayed
|
||||||
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
|
||||||
import bums.lunatic.launcher.behavior.Behavior
|
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.BOTTOM_SHEET_TAG
|
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_LOCK_METHOD
|
|
||||||
import bums.lunatic.launcher.helpers.UniUtils.Companion.expandNotificationPanel
|
|
||||||
import bums.lunatic.launcher.helpers.UniUtils.Companion.lockMethod
|
|
||||||
import bums.lunatic.launcher.model.CiliMagnet
|
import bums.lunatic.launcher.model.CiliMagnet
|
||||||
import bums.lunatic.launcher.model.RssData
|
import bums.lunatic.launcher.model.RssData
|
||||||
import bums.lunatic.launcher.qaccess.QuickAccess
|
|
||||||
import bums.lunatic.launcher.settings.SettingsActivity
|
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
import bums.lunatic.launcher.utils.SimpleFingerGestures
|
|
||||||
import bums.lunatic.launcher.workers.WorkersDb
|
import bums.lunatic.launcher.workers.WorkersDb
|
||||||
import com.google.gson.Gson
|
|
||||||
import io.realm.kotlin.UpdatePolicy
|
|
||||||
import io.realm.kotlin.ext.query
|
import io.realm.kotlin.ext.query
|
||||||
import io.realm.kotlin.ext.realmListOf
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|||||||
@ -21,6 +21,7 @@ package bums.lunatic.launcher.home.adapters
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
@ -36,19 +37,17 @@ import bums.lunatic.launcher.model.RssData
|
|||||||
import bums.lunatic.launcher.model.RssDataInterface
|
import bums.lunatic.launcher.model.RssDataInterface
|
||||||
import bums.lunatic.launcher.model.RssDataType
|
import bums.lunatic.launcher.model.RssDataType
|
||||||
import bums.lunatic.launcher.openClient
|
import bums.lunatic.launcher.openClient
|
||||||
import bums.lunatic.launcher.openDotax
|
|
||||||
import bums.lunatic.launcher.openReddit
|
import bums.lunatic.launcher.openReddit
|
||||||
import bums.lunatic.launcher.openYouTube
|
import bums.lunatic.launcher.openYouTube
|
||||||
|
import bums.lunatic.launcher.tokiz.view.JxEvent
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
|
import bums.lunatic.launcher.utils.SimpleFingerGestures
|
||||||
import bums.lunatic.launcher.workers.WorkersDb
|
import bums.lunatic.launcher.workers.WorkersDb
|
||||||
import com.google.android.material.imageview.ShapeableImageView
|
import com.google.android.material.imageview.ShapeableImageView
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
import kr.lunaticbum.awesomewebview.AwesomeWebView
|
|
||||||
import io.realm.kotlin.UpdatePolicy
|
import io.realm.kotlin.UpdatePolicy
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kr.lunaticbum.awesomewebview.listeners.WebViewListener
|
import kr.lunaticbum.awesomewebview.listeners.WebViewListener
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
@ -56,7 +55,8 @@ import java.util.Date
|
|||||||
|
|
||||||
|
|
||||||
internal class RssItemAdapter (
|
internal class RssItemAdapter (
|
||||||
private val context: Context) : RecyclerView.Adapter<RssHolder>() {
|
private val context: Context,
|
||||||
|
private val dateViewClick : View.OnClickListener) : RecyclerView.Adapter<RssHolder>() {
|
||||||
companion object {
|
companion object {
|
||||||
@SuppressLint("SimpleDateFormat")
|
@SuppressLint("SimpleDateFormat")
|
||||||
val dateFormat = SimpleDateFormat("a HH:mm / yy - MM - dd")
|
val dateFormat = SimpleDateFormat("a HH:mm / yy - MM - dd")
|
||||||
@ -70,75 +70,7 @@ internal class RssItemAdapter (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val dateViewClick = View.OnClickListener { v ->
|
|
||||||
(v?.tag as? RssData)?.let { rss ->
|
|
||||||
WorkersDb.getRealm().apply {
|
|
||||||
writeBlocking {
|
|
||||||
rss.read = rss.read + 1
|
|
||||||
if(rss.getCho()?.length ?: 0 < 1) {
|
|
||||||
rss.chosung = rss.title
|
|
||||||
}
|
|
||||||
copyToRealm(rss,UpdatePolicy.ALL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
when(rss.category()) {
|
|
||||||
RssDataType.GURU,RssDataType.MOST,RssDataType.REDDIT_NSFW -> {
|
|
||||||
v.findViewById<ShapeableImageView>(R.id.circle_preview)?.let {
|
|
||||||
if (it.visibility == View.GONE) {
|
|
||||||
it.visibility = View.VISIBLE
|
|
||||||
it.postDelayed({
|
|
||||||
it.visibility = View.GONE
|
|
||||||
}, 2000L)
|
|
||||||
} else {
|
|
||||||
if (RssDataType.REDDIT_NSFW.equals(rss.category())) {
|
|
||||||
openReddit(rss.originPage())
|
|
||||||
} else {
|
|
||||||
RssViewBuilder(lActivity!!)
|
|
||||||
.setRssList(arrayListOf<String>().apply {
|
|
||||||
var jjjj = hashSetOf<String>()
|
|
||||||
jjjj.addAll(rssList)
|
|
||||||
this.addAll(jjjj)
|
|
||||||
})
|
|
||||||
.setRssId(rss.originPage())
|
|
||||||
.showIconClose(true).showIconBack(false).showProgressBar(true).backPressToClose(false).webViewMixedContentMode(1)
|
|
||||||
.show(rss.originPage!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RssDataType.REDDIT -> {
|
|
||||||
openReddit(rss.originPage())
|
|
||||||
}
|
|
||||||
RssDataType.DOTAX -> {
|
|
||||||
RssViewBuilder(lActivity!!)
|
|
||||||
.setRssList(arrayListOf<String>().apply {
|
|
||||||
var jjjj = hashSetOf<String>()
|
|
||||||
jjjj.addAll(rssList)
|
|
||||||
this.addAll(jjjj)
|
|
||||||
})
|
|
||||||
.setRssId(rss.originPage())
|
|
||||||
.showIconClose(true).showIconBack(false).showProgressBar(true).webViewMixedContentMode(0)
|
|
||||||
.show(rss.originPage!!)
|
|
||||||
}
|
|
||||||
RssDataType.YOUTUBE -> { openYouTube(rss.originPage())
|
|
||||||
}
|
|
||||||
RssDataType.CLIEN -> {
|
|
||||||
openClient(rss.originPage())
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
RssViewBuilder(lActivity!!)
|
|
||||||
.setRssList(arrayListOf<String>().apply {
|
|
||||||
var jjjj = hashSetOf<String>()
|
|
||||||
jjjj.addAll(rssList)
|
|
||||||
this.addAll(jjjj)
|
|
||||||
})
|
|
||||||
.setRssId(rss.originPage())
|
|
||||||
.showIconClose(true).showIconBack(false).showProgressBar(true).webViewMixedContentMode(0)
|
|
||||||
.show(rss.originPage!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private var rssDataItemLis: ArrayList<RssData> = arrayListOf()
|
private var rssDataItemLis: ArrayList<RssData> = arrayListOf()
|
||||||
val mLongClickListener = View.OnLongClickListener { v ->
|
val mLongClickListener = View.OnLongClickListener { v ->
|
||||||
(v?.tag as? RssData)?.let { rss ->
|
(v?.tag as? RssData)?.let { rss ->
|
||||||
@ -166,8 +98,95 @@ internal class RssItemAdapter (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val mSimpleFingerGestures = SimpleFingerGestures(omfgl = object : SimpleFingerGestures.OnFingerGestureListener{
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
override fun onSwipeUp(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeDown(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeLeft(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeRight(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPinch(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("onPinch")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUnpinch(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDoubleTap(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLongPress(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("onLongPress")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("onClick")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n", "ClickableViewAccessibility")
|
||||||
override fun onBindViewHolder(holder: RssHolder, position: Int) {
|
override fun onBindViewHolder(holder: RssHolder, position: Int) {
|
||||||
val rssData = rssDataItemLis[position]
|
val rssData = rssDataItemLis[position]
|
||||||
if (rssData.pubDate() > 1000L) {
|
if (rssData.pubDate() > 1000L) {
|
||||||
@ -176,9 +195,6 @@ internal class RssItemAdapter (
|
|||||||
holder.view.date.text = emptyDate
|
holder.view.date.text = emptyDate
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(RssDataType.NEWSFEED.equals(rssData.category())) {
|
|
||||||
// Blog.LOGE("rssData >>>> ${rssData.thumbnailUrl()}")
|
|
||||||
// }
|
|
||||||
|
|
||||||
holder.view.title.text = "".plus(if(rssData.vote) " * " else "").plus(rssData.title().plus("[R:${rssData.read}]"))
|
holder.view.title.text = "".plus(if(rssData.vote) " * " else "").plus(rssData.title().plus("[R:${rssData.read}]"))
|
||||||
holder.view.desc.text = rssData.description()
|
holder.view.desc.text = rssData.description()
|
||||||
@ -198,6 +214,19 @@ internal class RssItemAdapter (
|
|||||||
|
|
||||||
holder.itemView.tag = rssData
|
holder.itemView.tag = rssData
|
||||||
holder.itemView.setOnClickListener(dateViewClick)
|
holder.itemView.setOnClickListener(dateViewClick)
|
||||||
|
holder.itemView.setOnTouchListener(object : View.OnTouchListener{
|
||||||
|
override fun onTouch(
|
||||||
|
v: View,
|
||||||
|
event: MotionEvent
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("event.device.name >>> ${event.device.name}")
|
||||||
|
if (event.device.name?.contains("JX-12",true) == true) {
|
||||||
|
return true//mSimpleFingerGestures.onTouch(v,event)
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
// v.setOnLongClickListener {
|
// v.setOnLongClickListener {
|
||||||
// WorkersDb.getRealm().apply {
|
// WorkersDb.getRealm().apply {
|
||||||
// copyFromRealm(rss)
|
// copyFromRealm(rss)
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
import bums.lunatic.launcher.databinding.ItemHourlyWeatherBinding
|
import bums.lunatic.launcher.databinding.ItemHourlyWeatherBinding
|
||||||
import bums.lunatic.launcher.model.Hour
|
import bums.lunatic.launcher.model.Hour
|
||||||
import bums.lunatic.launcher.model.WeatherInfoManager
|
import bums.lunatic.launcher.model.WeatherInfoManager
|
||||||
import bums.lunatic.launcher.utils.Blog
|
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
|
||||||
class WeatherHourlyAdapter(private val dataSet: ArrayList<Hour>): RecyclerView.Adapter<WeatherHourlyAdapter.ViewHolder>() {
|
class WeatherHourlyAdapter(private val dataSet: ArrayList<Hour>): RecyclerView.Adapter<WeatherHourlyAdapter.ViewHolder>() {
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
package bums.lunatic.launcher.model
|
package bums.lunatic.launcher.model
|
||||||
|
|
||||||
import bums.lunatic.launcher.beforeDay
|
|
||||||
import bums.lunatic.launcher.utils.JamoUtils
|
import bums.lunatic.launcher.utils.JamoUtils
|
||||||
import java.util.Date
|
|
||||||
|
|
||||||
|
|
||||||
class MostItem : JGuru , RssDataInterface {
|
class MostItem : JGuru , RssDataInterface {
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
package bums.lunatic.launcher.model
|
package bums.lunatic.launcher.model
|
||||||
|
|
||||||
import com.ibm.icu.util.ChineseCalendar
|
|
||||||
import io.realm.kotlin.types.RealmObject
|
import io.realm.kotlin.types.RealmObject
|
||||||
import java.util.Calendar
|
|
||||||
import java.util.Date
|
|
||||||
|
|
||||||
class UserActionModel: RealmObject {
|
class UserActionModel: RealmObject {
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,6 @@ import androidx.annotation.RequiresApi
|
|||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import bums.lunatic.launcher.model.CurrentPlayItem
|
import bums.lunatic.launcher.model.CurrentPlayItem
|
||||||
import bums.lunatic.launcher.model.NotificationItem
|
import bums.lunatic.launcher.model.NotificationItem
|
||||||
import bums.lunatic.launcher.utils.Blog
|
|
||||||
import bums.lunatic.launcher.utils.BitmapConverter
|
import bums.lunatic.launcher.utils.BitmapConverter
|
||||||
import bums.lunatic.launcher.workers.WorkersDb
|
import bums.lunatic.launcher.workers.WorkersDb
|
||||||
import io.realm.kotlin.UpdatePolicy
|
import io.realm.kotlin.UpdatePolicy
|
||||||
|
|||||||
@ -28,7 +28,6 @@ import android.view.ViewGroup
|
|||||||
import bums.lunatic.launcher.R
|
import bums.lunatic.launcher.R
|
||||||
import bums.lunatic.launcher.databinding.SettingsAppsBinding
|
import bums.lunatic.launcher.databinding.SettingsAppsBinding
|
||||||
import bums.lunatic.launcher.helpers.PrefBoolean
|
import bums.lunatic.launcher.helpers.PrefBoolean
|
||||||
import bums.lunatic.launcher.helpers.PrefHelper
|
|
||||||
import bums.lunatic.launcher.helpers.PrefLong
|
import bums.lunatic.launcher.helpers.PrefLong
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
|
|||||||
@ -26,17 +26,11 @@ import android.view.ViewGroup
|
|||||||
import androidx.core.widget.doOnTextChanged
|
import androidx.core.widget.doOnTextChanged
|
||||||
import bums.lunatic.launcher.R
|
import bums.lunatic.launcher.R
|
||||||
import bums.lunatic.launcher.databinding.SettingsWeatherBinding
|
import bums.lunatic.launcher.databinding.SettingsWeatherBinding
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_CITY_NAME
|
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_OWM_API
|
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_SHOW_CITY
|
|
||||||
import bums.lunatic.launcher.helpers.Constants.Companion.KEY_TEMP_UNIT
|
|
||||||
import bums.lunatic.launcher.helpers.PrefBoolean
|
import bums.lunatic.launcher.helpers.PrefBoolean
|
||||||
import bums.lunatic.launcher.helpers.PrefString
|
import bums.lunatic.launcher.helpers.PrefString
|
||||||
import bums.lunatic.launcher.settings.SettingsActivity.Companion.settingsPrefs
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import java.util.Objects
|
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
open class SettingChild : BottomSheetDialogFragment() {
|
open class SettingChild : BottomSheetDialogFragment() {
|
||||||
|
|||||||
1336
app/src/main/kotlin/bums/lunatic/launcher/tokiz/Novels.kt
Normal file
1336
app/src/main/kotlin/bums/lunatic/launcher/tokiz/Novels.kt
Normal file
File diff suppressed because it is too large
Load Diff
130
app/src/main/kotlin/bums/lunatic/launcher/tokiz/Settings.kt
Normal file
130
app/src/main/kotlin/bums/lunatic/launcher/tokiz/Settings.kt
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz
|
||||||
|
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.databinding.DataBindingUtil
|
||||||
|
import bums.lunatic.launcher.R
|
||||||
|
import bums.lunatic.launcher.tokiz.common.PairArray
|
||||||
|
import bums.lunatic.launcher.tokiz.common.colorz
|
||||||
|
import bums.lunatic.launcher.tokiz.common.getIndex
|
||||||
|
import bums.lunatic.launcher.tokiz.common.typesfacez
|
||||||
|
import bums.lunatic.launcher.tokiz.data.HistoryManager
|
||||||
|
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
|
||||||
|
import bums.lunatic.launcher.common.CommonActivity
|
||||||
|
import bums.lunatic.launcher.databinding.SettingsBinding
|
||||||
|
import io.realm.kotlin.UpdatePolicy
|
||||||
|
import io.realm.kotlin.ext.query
|
||||||
|
import kotlin.collections.first
|
||||||
|
import kotlin.collections.last
|
||||||
|
import kotlin.collections.map
|
||||||
|
import kotlin.collections.toTypedArray
|
||||||
|
import kotlin.let
|
||||||
|
|
||||||
|
class Settings : CommonActivity() {
|
||||||
|
|
||||||
|
lateinit var binding : SettingsBinding
|
||||||
|
var readerConfig : ReaderConfig? = null
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = DataBindingUtil.setContentView(this, R.layout.settings)
|
||||||
|
// setContentView(R.layout.settings)
|
||||||
|
var realm = HistoryManager.openRealm
|
||||||
|
realm.writeBlocking {
|
||||||
|
this.query<ReaderConfig>()?.find()?.let {
|
||||||
|
if (it.size > 0) {
|
||||||
|
readerConfig = copyFromRealm(it.first())
|
||||||
|
} else {
|
||||||
|
readerConfig = ReaderConfig()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
binding.textSize.displayFormat = "글자 크기 : %d"
|
||||||
|
binding.textSize.value = readerConfig?.textSize ?: 14
|
||||||
|
binding.textSize.mValueChange = {
|
||||||
|
binding.preview.textSize = it.toFloat() ;
|
||||||
|
if (readerConfig?.textSize != it) {
|
||||||
|
readerConfig?.textSize = it
|
||||||
|
configSave()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
binding.pagePadding.displayFormat = "페이지 여백 : %d"
|
||||||
|
binding.pagePadding.value = readerConfig?.padding ?: 5
|
||||||
|
binding.pagePadding.mValueChange = {
|
||||||
|
binding.preview.setPadding(it,it,it,it) ;
|
||||||
|
if (readerConfig?.padding != it) {
|
||||||
|
readerConfig?.padding = it
|
||||||
|
configSave()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
binding.letterSpace.displayFormat = "자간 : %d"
|
||||||
|
binding.letterSpace.value = readerConfig?.letterSpace ?: 1
|
||||||
|
binding.letterSpace.mValueChange = {
|
||||||
|
binding.preview.letterSpacing = it.times(0.01).toFloat() ;
|
||||||
|
if (readerConfig?.letterSpace != it) {
|
||||||
|
readerConfig?.letterSpace = it
|
||||||
|
configSave()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
binding.lineSpace.displayFormat = "행간 : %d"
|
||||||
|
binding.lineSpace.value = readerConfig?.lineSpace ?: 1
|
||||||
|
binding.lineSpace.mValueChange = {
|
||||||
|
|
||||||
|
binding.preview.setLineSpacing(1f, 1f.plus(it.times(0.01f))) ;
|
||||||
|
if (readerConfig?.lineSpace != it) {
|
||||||
|
readerConfig?.lineSpace = it
|
||||||
|
configSave()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
binding.pageTypesface.displayFormat = "폰트 : %s"
|
||||||
|
binding.pageTypesface.titleArray = typesfacez.map { it.first }.toTypedArray()
|
||||||
|
binding.pageTypesface.value = getIndex(typesfacez as PairArray<Any>,readerConfig?.font ?: "")
|
||||||
|
binding.pageTypesface.mValueChange = {
|
||||||
|
val pair = typesfacez.get(it)
|
||||||
|
binding.preview.setTypeface(resources.getFont(pair.second))
|
||||||
|
if (readerConfig?.font != pair.first) {
|
||||||
|
readerConfig?.font = pair.first ?: ""
|
||||||
|
configSave()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.pageStyle.displayFormat = "스타일 : %s"
|
||||||
|
binding.pageStyle.titleArray = colorz.map { it.first }.toTypedArray()
|
||||||
|
binding.pageStyle.value = readerConfig?.style ?: 0
|
||||||
|
binding.pageStyle.mValueChange = {
|
||||||
|
val pair = colorz.get(it)
|
||||||
|
binding.preview.setBackgroundColor(Color.parseColor(pair.second.last()))
|
||||||
|
binding.preview.setTextColor(Color.parseColor(pair.second.first()))
|
||||||
|
if (readerConfig?.style != it) {
|
||||||
|
readerConfig?.style = it ?: 0
|
||||||
|
configSave()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun configSave() {
|
||||||
|
var realm = HistoryManager.openRealm
|
||||||
|
realm.writeBlocking {
|
||||||
|
copyToRealm(readerConfig!!, UpdatePolicy.ALL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.common
|
||||||
|
|
||||||
|
import bums.lunatic.launcher.R
|
||||||
|
|
||||||
|
|
||||||
|
typealias PairArray<T> = Array<Pair<String,T>>
|
||||||
|
val colorz : PairArray<Array<String>> = arrayOf<Pair<String,Array<String>>>(
|
||||||
|
Pair("color set 01",arrayOf<String>("#E1F5FE", "#263238")),
|
||||||
|
Pair("color set 02",arrayOf<String>("#F0F4C3", "#37474F")),
|
||||||
|
Pair("color set 03",arrayOf<String>("#ECEFF1", "#455A64")),
|
||||||
|
Pair("color set 04",arrayOf<String>("#E0F7FA", "#263238")),
|
||||||
|
Pair("color set 05",arrayOf<String>("#F5F5F5", "#263238")),
|
||||||
|
Pair("color set 06",arrayOf<String>("#ECEFF1", "#263238")),
|
||||||
|
Pair("color set 07",arrayOf<String>("#F8BBD0", "#263238")),
|
||||||
|
Pair("color set 08",arrayOf<String>("#E6EE9C", "#455A64")),
|
||||||
|
Pair("color set 09",arrayOf<String>("#CFD8DC", "#455A64")),
|
||||||
|
Pair("color set 10",arrayOf<String>("#FFF59D", "#37474F")),
|
||||||
|
Pair("color set 21",arrayOf<String>("#263238","#E1F5FE")),
|
||||||
|
Pair("color set 22",arrayOf<String>("#37474F","#F0F4C3")),
|
||||||
|
Pair("color set 23",arrayOf<String>("#455A64","#ECEFF1")),
|
||||||
|
Pair("color set 24",arrayOf<String>("#263238","#E0F7FA")),
|
||||||
|
Pair("color set 25",arrayOf<String>("#263238","#F5F5F5")),
|
||||||
|
Pair("color set 26",arrayOf<String>("#263238","#ECEFF1")),
|
||||||
|
Pair("color set 27",arrayOf<String>("#263238","#F8BBD0")),
|
||||||
|
Pair("color set 28",arrayOf<String>("#455A64","#E6EE9C")),
|
||||||
|
Pair("color set 29",arrayOf<String>("#455A64","#CFD8DC")),
|
||||||
|
Pair("color set 30",arrayOf<String>("#37474F","#FFF59D")),
|
||||||
|
Pair("color set 31",arrayOf<String>("#FFFFFF","#1C1B1B")),
|
||||||
|
Pair("color set 32",arrayOf<String>("#272727","#FFFFFF")),
|
||||||
|
Pair("color set 33",arrayOf<String>("#1C1B1B","#FFFFFF")),
|
||||||
|
Pair("color set 34",arrayOf<String>("#FFFFFF","#272727"))
|
||||||
|
)
|
||||||
|
val typesfacez : PairArray<Int> = arrayOf<Pair<String,Int>>(
|
||||||
|
Pair("정선 아리랑 혼", R.font.jsarirang_hon),
|
||||||
|
Pair("정선 아리랑 뿌리", R.font.jsarirang_ppuri),
|
||||||
|
Pair("정선 동강 레귤러", R.font.jsdongkang_regular),
|
||||||
|
Pair("손기정체", R.font.kcc_sonkeechung),
|
||||||
|
Pair("교보 손글씨", R.font.kyobo_handwriting_2021sjy),
|
||||||
|
Pair("태백 은하수", R.font.taebaek_milkyway),
|
||||||
|
Pair("taebaek_milkyway",R.font.taebaek_milkyway),
|
||||||
|
Pair("kccahnjunggeun",R.font.kccahnjunggeun),
|
||||||
|
Pair("kotra_songeulssi",R.font.kotra_songeulssi),
|
||||||
|
Pair("kotra_bold",R.font.kotra_bold),
|
||||||
|
Pair("cafe24oneprettynight",R.font.cafe24oneprettynight),
|
||||||
|
Pair("nnsgc_wsjidyp",R.font.nnsgc_wsjidyp),
|
||||||
|
Pair("nnsgc_yjc",R.font.nnsgc_yjc),
|
||||||
|
Pair("nnsgc_brhp",R.font.nnsgc_brhp),
|
||||||
|
Pair("nnsgc_md",R.font.nnsgc_md),
|
||||||
|
Pair("nnsgc_gd_an_gd",R.font.nnsgc_gd_an_gd),
|
||||||
|
Pair("dovemayo",R.font.dovemayo),
|
||||||
|
Pair("gabia_solmee",R.font.gabia_solmee),
|
||||||
|
Pair("ylee_mortal_heart_immortal_memory",R.font.ylee_mortal_heart_immortal_memory),
|
||||||
|
Pair("kcc_kimhoon",R.font.kcc_kimhoon),
|
||||||
|
Pair("taefont_tsthlml",R.font.taefont_tsthlml),
|
||||||
|
Pair("ssshinb7",R.font.ssshinb7),
|
||||||
|
Pair("godomaum",R.font.godomaum),
|
||||||
|
Pair("tvn_jguiyg_medium",R.font.tvn_jguiyg_medium),
|
||||||
|
Pair("tvn_jguiyg_light",R.font.tvn_jguiyg_light),
|
||||||
|
Pair("on_jsuhr",R.font.on_jsuhr),
|
||||||
|
Pair("on_jsuhl",R.font.on_jsuhl),
|
||||||
|
Pair("on_ychyuhr",R.font.on_ychyuhr),
|
||||||
|
Pair("on_ychyuhl",R.font.on_ychyuhl),
|
||||||
|
Pair("on_treeususimgul_r",R.font.on_treeususimgul_r),
|
||||||
|
Pair("on_treeususimgul",R.font.on_treeususimgul),
|
||||||
|
Pair("on_wibsr",R.font.on_wibsr),
|
||||||
|
Pair("on_wisbl",R.font.on_wisbl),
|
||||||
|
Pair("on_sbsjl",R.font.on_sbsjl),
|
||||||
|
Pair("on_sbsjr",R.font.on_sbsjr),
|
||||||
|
Pair("wandohoper",R.font.wandohoper),
|
||||||
|
Pair("ebs_r",R.font.ebs_r),
|
||||||
|
)
|
||||||
|
|
||||||
|
@JvmName("getIndexAny")
|
||||||
|
fun PairArray<Any>.getIndex(key : String) = getIndex(this, key)
|
||||||
|
fun getIndex(collection : PairArray<Any>, key : String) : Int {
|
||||||
|
var index = 0
|
||||||
|
var returns = 0
|
||||||
|
for (item in collection) {
|
||||||
|
if(item.first.equals(key)) {
|
||||||
|
returns = index
|
||||||
|
}
|
||||||
|
index = index.inc()
|
||||||
|
}
|
||||||
|
return returns
|
||||||
|
}
|
||||||
|
enum class TouchArea {
|
||||||
|
Left,Center,Right, DoubleLeft, DoubleRight
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.common
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import bums.lunatic.launcher.tokiz.webcontents.contentsinfo.BooktokiStruct
|
||||||
|
import bums.lunatic.launcher.utils.Blog
|
||||||
|
|
||||||
|
object PrefManager {
|
||||||
|
private val mainName = "Main_Pref_"
|
||||||
|
private val domainKey = "Last_Domain_"
|
||||||
|
private lateinit var main : SharedPreferences
|
||||||
|
fun init(context: Context) {
|
||||||
|
main = context.getSharedPreferences(mainName,Context.MODE_PRIVATE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun save(key : String, value : String?) {
|
||||||
|
main.edit().putString(key,value).apply()
|
||||||
|
}
|
||||||
|
fun load(key : String) : String? {
|
||||||
|
return main.getString(key, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLastDomain() : String {
|
||||||
|
return main.getString(domainKey, BooktokiStruct.getLastedDoamin()) ?: BooktokiStruct.getLastedDoamin()
|
||||||
|
}
|
||||||
|
fun putLastDomain(domain : String) {
|
||||||
|
Blog.LOGE("domain >>> ${domain}")
|
||||||
|
main.edit().putString(domainKey,domain).apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,187 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.data
|
||||||
|
|
||||||
|
import bums.lunatic.launcher.tokiz.data.model.BookPageInfo
|
||||||
|
import bums.lunatic.launcher.tokiz.data.model.BookPageInfos
|
||||||
|
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
|
||||||
|
import bums.lunatic.launcher.tokiz.data.model.LastInfo
|
||||||
|
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
|
||||||
|
import bums.lunatic.launcher.utils.Blog
|
||||||
|
import bums.lunatic.launcher.workers.WorkersDb
|
||||||
|
import io.realm.kotlin.Realm
|
||||||
|
import io.realm.kotlin.UpdatePolicy
|
||||||
|
|
||||||
|
object HistoryManager {
|
||||||
|
|
||||||
|
|
||||||
|
val openRealm : Realm = WorkersDb.getRealm()
|
||||||
|
|
||||||
|
fun save(lastInfo: LastInfo) {
|
||||||
|
openRealm.apply{
|
||||||
|
this.writeBlocking {
|
||||||
|
copyToRealm(lastInfo, UpdatePolicy.ALL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun save(historyItem: HistoryItem) {
|
||||||
|
openRealm.apply{
|
||||||
|
this.writeBlocking {
|
||||||
|
copyToRealm(historyItem, UpdatePolicy.ALL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun requestLastInfo(callback : (LastInfo)->Unit) {
|
||||||
|
openRealm.apply{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun save(config : ReaderConfig) {
|
||||||
|
openRealm.apply{
|
||||||
|
this.writeBlocking {
|
||||||
|
copyToRealm(config,UpdatePolicy.ALL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBookInfos(aUrl : String, callback : (BookPageInfos?)->Unit) {
|
||||||
|
var url : String = aUrl
|
||||||
|
Blog.LOGE("aUrl >>> ${aUrl}")
|
||||||
|
openRealm.apply{
|
||||||
|
if (url.startsWith("//")) {
|
||||||
|
while (url.startsWith("//")) {
|
||||||
|
url = url.replace("//","/").trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Blog.LOGE("aUrl >>> ${url}")
|
||||||
|
var bookPageInfo = this.query(BookPageInfo::class).query("pathUrl == $0 || bookPageUrl == $0","${url}").find()
|
||||||
|
if (bookPageInfo != null && bookPageInfo.count() > 0) {
|
||||||
|
Blog.LOGE("get ${bookPageInfo}" )
|
||||||
|
var pgs = this.query(BookPageInfos::class,"bookPageUrl == $0", bookPageInfo.first().bookPageUrl).find()
|
||||||
|
if (pgs.size > 0) {
|
||||||
|
pgs.first().let {
|
||||||
|
Blog.LOGE("get ${it} , ${it?.pages}")
|
||||||
|
callback.invoke(this.copyFromRealm(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback.invoke(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBookPageInfo(aUrl : String, callback : (BookPageInfo?)->Unit) {
|
||||||
|
var url : String = aUrl
|
||||||
|
openRealm.apply{
|
||||||
|
if (url.startsWith("//")) {
|
||||||
|
while (url.startsWith("//")) {
|
||||||
|
url = url.replace("//","/").trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var result = this.query(BookPageInfo::class).query("pathUrl == $0","${url}").find()
|
||||||
|
if (result.size > 0) {
|
||||||
|
var bookPageInfo = result?.first()
|
||||||
|
if (bookPageInfo != null) {
|
||||||
|
callback.invoke(bookPageInfo)
|
||||||
|
} else {
|
||||||
|
callback.invoke(null)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback.invoke(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setBookPageInfo(aUrl : String, page :Int) {
|
||||||
|
var url : String = aUrl
|
||||||
|
openRealm.writeBlocking {
|
||||||
|
if (url.startsWith("//")) {
|
||||||
|
while (url.startsWith("//")) {
|
||||||
|
url = url.replace("//","/").trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var result = this.query(BookPageInfo::class).query("pathUrl == $0","${url}").find()
|
||||||
|
if (result.size > 0) {
|
||||||
|
var bookPageInfo = result?.first()
|
||||||
|
if (bookPageInfo != null) {
|
||||||
|
bookPageInfo.lastPage = page
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBooPageInfoContentsSave(aUrl : String, contents : String) {
|
||||||
|
var url : String = if (aUrl.startsWith("//") || aUrl.startsWith("///") || aUrl.startsWith("////")) {
|
||||||
|
aUrl.replace("////","/").replace("///","/").replace("//","/")
|
||||||
|
} else aUrl
|
||||||
|
openRealm.writeBlocking {
|
||||||
|
Blog.LOGE("getBooPageInfoContentsSave ${url}")
|
||||||
|
val result = query(BookPageInfo::class).query("pathUrl == $0", "${url}").find()
|
||||||
|
if (result.size > 0) {
|
||||||
|
result.first().contents = contents
|
||||||
|
copyToRealm(result.first(), UpdatePolicy.ALL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun getNextPage(aUrl : String ,callback : (BookPageInfo?)->Unit) {
|
||||||
|
var url : String = aUrl
|
||||||
|
openRealm.apply{
|
||||||
|
if (url.startsWith("//")) {
|
||||||
|
while (url.startsWith("//")) {
|
||||||
|
url = url.replace("//","/").trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var bookPageInfo =
|
||||||
|
this.query(BookPageInfo::class).query("pathUrl == $0", url).find()
|
||||||
|
if (bookPageInfo.size > 0) {
|
||||||
|
Blog.LOGE("getNextPage 2 => chapterNum : ${bookPageInfo.first().chapterNum} , bookPageInfo.bookPageUrl : ${bookPageInfo.first().bookPageUrl}" )
|
||||||
|
var results = this.query(BookPageInfo::class).query("chapterNum == $0",bookPageInfo.first().chapterNum + 1).query("bookPageUrl == $0","${bookPageInfo.first().bookPageUrl}").find()
|
||||||
|
if(results.size > 0) {
|
||||||
|
results.first().let {
|
||||||
|
Blog.LOGE("getNextPage 2 nextBook pathUrl : ${it.pathUrl}" )
|
||||||
|
callback.invoke(it)
|
||||||
|
}
|
||||||
|
} else {callback.invoke(null)}
|
||||||
|
} else {callback.invoke(null)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun getPrevPage(aUrl : String ,callback : (BookPageInfo?)->Unit) {
|
||||||
|
var url : String = aUrl
|
||||||
|
openRealm.apply{
|
||||||
|
Blog.LOGE("getPrevPage ${url}" )
|
||||||
|
if (url.startsWith("//")) {
|
||||||
|
while (url.startsWith("//")) {
|
||||||
|
url = url.replace("//","/").trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Blog.LOGE("getPrevPage ${url}" )
|
||||||
|
var bookPageInfo =
|
||||||
|
this.query(BookPageInfo::class).query("pathUrl == $0", url).find()
|
||||||
|
Blog.LOGE("getPrevPage ${bookPageInfo}" )
|
||||||
|
if (bookPageInfo.size > 0) {
|
||||||
|
Blog.LOGE("getPrevPage 2 ${bookPageInfo?.first()?.chapterNum}" )
|
||||||
|
Blog.LOGE("getPrevPage 2 ${bookPageInfo?.first()?.bookPageUrl}" )
|
||||||
|
var results = this.query(BookPageInfo::class).query("chapterNum == $0",bookPageInfo.first().chapterNum - 1).query("bookPageUrl == $0","${bookPageInfo.first().bookPageUrl}").find()
|
||||||
|
if(results.size > 0) {
|
||||||
|
results.first()?.let {
|
||||||
|
Blog.LOGE("getPrevPage 2 ${it.bookPageUrl}" )
|
||||||
|
Blog.LOGE("getPrevPage 2 ${it.pathUrl}" )
|
||||||
|
callback.invoke(it)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback.invoke(null)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback.invoke(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,131 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.data.model
|
||||||
|
|
||||||
|
import io.realm.kotlin.ext.realmListOf
|
||||||
|
import io.realm.kotlin.types.RealmList
|
||||||
|
import io.realm.kotlin.types.RealmObject
|
||||||
|
import io.realm.kotlin.types.annotations.PrimaryKey
|
||||||
|
|
||||||
|
class PortMessage {
|
||||||
|
var type : String? = ""
|
||||||
|
var bookInfos : BookPageInfosJ? = null
|
||||||
|
var book : BookContents? = null
|
||||||
|
var msg : String? = null
|
||||||
|
}
|
||||||
|
class BookContents {
|
||||||
|
var chapterTitle : String? = null
|
||||||
|
var bookContents : String? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
class BookPageInfosJ {
|
||||||
|
var bookTitle : String = ""
|
||||||
|
var bookPageUrl : String = ""
|
||||||
|
|
||||||
|
var pages : ArrayList<BookPageInfoJ> = arrayListOf<BookPageInfoJ>()
|
||||||
|
|
||||||
|
fun getTitleArray() : ArrayList<String> {
|
||||||
|
var arrayList = ArrayList<String>()
|
||||||
|
pages.forEach { arrayList.add(it.bookTitle ?: "") }
|
||||||
|
return arrayList
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getR() : BookPageInfos{
|
||||||
|
var r = BookPageInfos()
|
||||||
|
r.bookTitle = this.bookTitle
|
||||||
|
r.bookPageUrl = this.bookPageUrl
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class BookPageInfoJ {
|
||||||
|
var chapterID : Int = 0
|
||||||
|
var contents : String? = ""
|
||||||
|
var bookPageUrl : String? = ""
|
||||||
|
var chapterTitle : String? = ""
|
||||||
|
var bookTitle : String? = ""
|
||||||
|
var chapterNum : Int = 0
|
||||||
|
var lastPage : Int? = 0
|
||||||
|
var pathUrl : String? = ""
|
||||||
|
|
||||||
|
fun getRealm() : BookPageInfo {
|
||||||
|
var r = BookPageInfo()
|
||||||
|
r.chapterID = this.chapterID
|
||||||
|
r.contents = this.contents
|
||||||
|
r.bookPageUrl = this.bookPageUrl ?: ""
|
||||||
|
r.chapterTitle = this.chapterTitle
|
||||||
|
r.bookTitle = this.bookTitle ?: ""
|
||||||
|
r.chapterNum = this.chapterNum
|
||||||
|
r.lastPage = this.lastPage
|
||||||
|
r.pathUrl = this.pathUrl?.replace("'","")
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class BookPageInfos : RealmObject {
|
||||||
|
|
||||||
|
var bookTitle : String = ""
|
||||||
|
|
||||||
|
@PrimaryKey
|
||||||
|
var bookPageUrl : String? = ""
|
||||||
|
var pages : RealmList<BookPageInfo> = realmListOf()
|
||||||
|
|
||||||
|
fun getTitleArray() : ArrayList<String> {
|
||||||
|
var arrayList = ArrayList<String>()
|
||||||
|
pages.forEach {
|
||||||
|
arrayList.add(it.getTitleItem())}
|
||||||
|
return arrayList
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sort() {
|
||||||
|
val comparator : Comparator<BookPageInfo> = compareBy { it.chapterID }
|
||||||
|
pages.sortWith(comparator)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hasItem(item: BookPageInfo) : Boolean {
|
||||||
|
var hasItem = false
|
||||||
|
for (c in pages) {
|
||||||
|
if (!hasItem) {
|
||||||
|
hasItem = c.pathUrl.equals(item.pathUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasItem
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
class BookPageInfo : RealmObject {
|
||||||
|
|
||||||
|
var chapterID : Int = 0
|
||||||
|
var contents : String? = ""
|
||||||
|
|
||||||
|
var bookPageUrl : String? = ""
|
||||||
|
var chapterTitle : String? = ""
|
||||||
|
var bookTitle : String? = ""
|
||||||
|
var chapterNum : Int = 0
|
||||||
|
var lastPage : Int? = 0
|
||||||
|
|
||||||
|
fun isValidBook() = (pathUrl?.length ?: 0) > 1
|
||||||
|
|
||||||
|
@PrimaryKey
|
||||||
|
var pathUrl : String? = ""
|
||||||
|
|
||||||
|
fun getTitleItem() : String {
|
||||||
|
var result = StringBuilder()
|
||||||
|
result.append(if ((contents?.length ?: 0) > 10) {
|
||||||
|
"S:[0] "
|
||||||
|
} else {
|
||||||
|
"[X] "
|
||||||
|
})
|
||||||
|
|
||||||
|
result.append(chapterTitle?: "")
|
||||||
|
|
||||||
|
result.append(if ((lastPage ?: 0) > 0) {
|
||||||
|
" [0] "
|
||||||
|
} else {
|
||||||
|
" [X] "
|
||||||
|
})
|
||||||
|
|
||||||
|
return result.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.data.model
|
||||||
|
|
||||||
|
import android.content.pm.ActivityInfo
|
||||||
|
import io.realm.kotlin.types.RealmObject
|
||||||
|
import io.realm.kotlin.types.annotations.PrimaryKey
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
|
||||||
|
class LastInfo : RealmObject {
|
||||||
|
@PrimaryKey
|
||||||
|
var _id : String = "UniqLastId"
|
||||||
|
var pageUrl : String = ""
|
||||||
|
var title : String = ""
|
||||||
|
var chapter : Int = 0
|
||||||
|
var pageIndex : Int = 0
|
||||||
|
var contentsName : String = ""
|
||||||
|
var displayOrientation : Int = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||||
|
|
||||||
|
fun makeHistoryItem() : HistoryItem = HistoryItem().apply {
|
||||||
|
title = this@LastInfo.title
|
||||||
|
pageUrl = this@LastInfo.pageUrl
|
||||||
|
chapter = this@LastInfo.chapter
|
||||||
|
pageIndex = this@LastInfo.pageIndex
|
||||||
|
contentsName = this@LastInfo.contentsName
|
||||||
|
displayOrientation = this@LastInfo.displayOrientation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class HistoryItem : RealmObject {
|
||||||
|
@PrimaryKey
|
||||||
|
var title : String = ""
|
||||||
|
var pageUrl : String = ""
|
||||||
|
var chapter : Int = 0
|
||||||
|
var pageIndex : Int = 0
|
||||||
|
var contentsName : String = ""
|
||||||
|
var displayOrientation : Int = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||||
|
|
||||||
|
fun makeLastInfo() = LastInfo().apply{
|
||||||
|
_id = "UniqLastId"
|
||||||
|
title = this@HistoryItem.title
|
||||||
|
pageUrl = this@HistoryItem.pageUrl
|
||||||
|
chapter = this@HistoryItem.chapter
|
||||||
|
pageIndex = this@HistoryItem.pageIndex
|
||||||
|
contentsName = this@HistoryItem.contentsName
|
||||||
|
displayOrientation = this@HistoryItem.displayOrientation
|
||||||
|
}
|
||||||
|
fun putHistory(bookPageInfo: BookPageInfo? , currentPath : String) : HistoryItem {
|
||||||
|
title = bookPageInfo?.bookTitle ?: SimpleDateFormat("YY-mm-DD-HH:mm").format(Date())
|
||||||
|
pageUrl = bookPageInfo?.pathUrl ?: currentPath
|
||||||
|
chapter = bookPageInfo?.chapterNum ?: 0
|
||||||
|
pageIndex = bookPageInfo?.lastPage ?: 0
|
||||||
|
contentsName = bookPageInfo?.chapterTitle ?: ""
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Bookmark() : RealmObject {
|
||||||
|
@PrimaryKey
|
||||||
|
var pageUrl : String = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.data.model
|
||||||
|
|
||||||
|
import io.realm.kotlin.types.RealmObject
|
||||||
|
import io.realm.kotlin.types.annotations.PrimaryKey
|
||||||
|
|
||||||
|
class ReaderConfig : RealmObject {
|
||||||
|
@PrimaryKey
|
||||||
|
var id : String? = "ReaderConfig"
|
||||||
|
var textSize : Int? = 14
|
||||||
|
var textColor : String? = "#FFFFFF"
|
||||||
|
var bgColor : String? = "#000000"
|
||||||
|
var style : Int? = 0
|
||||||
|
var lineSpace : Int? = 1
|
||||||
|
var letterSpace : Int? = 1
|
||||||
|
var font : String? = ""
|
||||||
|
var padding : Int? = 5
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.dialog
|
||||||
|
|
||||||
|
import android.R
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import bums.lunatic.launcher.tokiz.data.model.BookPageInfo
|
||||||
|
|
||||||
|
object DefaultList {
|
||||||
|
fun showDefaultList(context: Context, title : String, items : Collection<BookPageInfo>, firstPosition : Int, choosedTitle : (Int)->String, chooedPositive : (Int)->Unit, saveCalback : (Int)->Unit ) {
|
||||||
|
val builderSingle: AlertDialog.Builder = AlertDialog.Builder(context)
|
||||||
|
builderSingle.setTitle(title)
|
||||||
|
val arrayAdapter =
|
||||||
|
ArrayAdapter<String>(context, R.layout.select_dialog_singlechoice)
|
||||||
|
for (item in items) {
|
||||||
|
arrayAdapter.add(item.getTitleItem())
|
||||||
|
}
|
||||||
|
builderSingle.setNeutralButton("전체 저장") { dialog, which ->
|
||||||
|
saveCalback.invoke(-1)
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
builderSingle.setNegativeButton("닫기",
|
||||||
|
DialogInterface.OnClickListener { dialog, which ->
|
||||||
|
dialog.dismiss() })
|
||||||
|
builderSingle.setAdapter(arrayAdapter,
|
||||||
|
DialogInterface.OnClickListener { dialog, position ->
|
||||||
|
val strName = arrayAdapter.getItem(position)
|
||||||
|
val builderInner: AlertDialog.Builder = AlertDialog.Builder(context)
|
||||||
|
builderInner.setMessage(strName)
|
||||||
|
builderInner.setTitle(choosedTitle.invoke(position))
|
||||||
|
builderInner.setNegativeButton("닫기") { dialog, which ->
|
||||||
|
|
||||||
|
}
|
||||||
|
// builderInner.setNeutralButton("자동 저장") { dialog, which ->
|
||||||
|
// saveCalback.invoke(position)
|
||||||
|
// }
|
||||||
|
builderInner.setPositiveButton("이동"){ dialog, which ->
|
||||||
|
chooedPositive.invoke(position)
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
builderInner.show().apply {
|
||||||
|
DialogManager.add(this)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
builderSingle.create()?.apply{
|
||||||
|
setOnShowListener { d->
|
||||||
|
(d as? AlertDialog)?.let{
|
||||||
|
it.listView?.setSelection(firstPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DialogManager.add(this)
|
||||||
|
}?.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.dialog
|
||||||
|
|
||||||
|
import androidx.activity.ComponentDialog
|
||||||
|
|
||||||
|
object DialogManager {
|
||||||
|
val dialogs = arrayListOf<ComponentDialog>()
|
||||||
|
fun add(item : ComponentDialog) = dialogs.add(item)
|
||||||
|
fun closeAll() {
|
||||||
|
for (dialog in dialogs) {
|
||||||
|
try {
|
||||||
|
dialog?.dismiss()
|
||||||
|
} catch(e : Exception) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.dialog//package com.mime.dualscreenview.dialog
|
||||||
|
//
|
||||||
|
//import android.app.Dialog
|
||||||
|
//import android.content.Context
|
||||||
|
//import android.content.DialogInterface
|
||||||
|
//import android.graphics.Color
|
||||||
|
//import android.os.Bundle
|
||||||
|
//import android.view.LayoutInflater
|
||||||
|
//import android.view.View
|
||||||
|
//import android.view.ViewGroup
|
||||||
|
//import android.view.Window
|
||||||
|
//import android.widget.TextView
|
||||||
|
//import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
//import androidx.recyclerview.widget.RecyclerView
|
||||||
|
//import com.mime.dualscreenview.R
|
||||||
|
//import kotlin.random.Random
|
||||||
|
//
|
||||||
|
//interface StyleSelectInterface {
|
||||||
|
// fun onSelectStyle(bgColor : String, textColor : String)
|
||||||
|
//}
|
||||||
|
//class Stylez : Dialog {
|
||||||
|
// constructor(context: Context) : super(context) {initView(context)}
|
||||||
|
// constructor(context: Context, themeResId: Int) : super(context, themeResId) {initView(context)}
|
||||||
|
// constructor(
|
||||||
|
// context: Context,
|
||||||
|
// cancelable: Boolean,
|
||||||
|
// cancelListener: DialogInterface.OnCancelListener?
|
||||||
|
// ) : super(context, cancelable, cancelListener) {initView(context)}
|
||||||
|
//
|
||||||
|
// var styleSelectInterface : StyleSelectInterface? = null
|
||||||
|
//
|
||||||
|
// fun initView(context: Context) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
// super.onCreate(savedInstanceState)
|
||||||
|
// this.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
|
// setCancelable(true)
|
||||||
|
// setContentView(R.layout.dialog_stylesz)
|
||||||
|
// val recyclerView: RecyclerView = findViewById(R.id.stylez_recyclerview)
|
||||||
|
// val adapterRe = AdapterRe(context, colorz)
|
||||||
|
// recyclerView.adapter = adapterRe
|
||||||
|
// recyclerView.layoutManager =
|
||||||
|
// GridLayoutManager(context, 2, GridLayoutManager.VERTICAL, false)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// inner class AdapterRe(ctx: Context, myImageNameList: Array<Array<String>>) :
|
||||||
|
// RecyclerView.Adapter<StylezViewHolder>() {
|
||||||
|
// private val inflater: LayoutInflater
|
||||||
|
// private val myImageNameList: Array<Array<String>>
|
||||||
|
// private val ctx : Context
|
||||||
|
// init {
|
||||||
|
// inflater = LayoutInflater.from(ctx)
|
||||||
|
// this.ctx = ctx
|
||||||
|
// this.myImageNameList = myImageNameList
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun onCreateViewHolder (
|
||||||
|
// parent: ViewGroup,
|
||||||
|
// viewType: Int
|
||||||
|
// ): StylezViewHolder {
|
||||||
|
// val view: View = inflater.inflate(R.layout.item_colorz, parent, false)
|
||||||
|
// return StylezViewHolder(view)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun onBindViewHolder(holder: StylezViewHolder, position: Int) {
|
||||||
|
// var colorz = myImageNameList.get(position)
|
||||||
|
// var sampleTextz = ctx.resources.getStringArray(R.array.sample_textz)
|
||||||
|
// holder?.setStyle(bgColor = colorz.get(1), textColor = colorz.get(0),sampleTextz.get(Random.nextInt(9876) % sampleTextz.size))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// override fun getItemCount(): Int {
|
||||||
|
// return myImageNameList.size
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// inner class StylezViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
|
// var textView: TextView
|
||||||
|
// var bg : View
|
||||||
|
// init {
|
||||||
|
// textView = itemView.findViewById(R.id.textview_sample)
|
||||||
|
// bg = itemView.findViewById(R.id.bg_sample)
|
||||||
|
// }
|
||||||
|
// fun setStyle(bgColor : String, textColor : String, sampleText : String ) {
|
||||||
|
// bg.setBackgroundColor(Color.parseColor(bgColor))
|
||||||
|
// textView.setTextColor(Color.parseColor(textColor))
|
||||||
|
// textView.text = sampleText
|
||||||
|
// itemView?.setOnClickListener { v ->
|
||||||
|
// styleSelectInterface?.onSelectStyle(bgColor,textColor)
|
||||||
|
// dismiss()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
218
app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/BWebview.kt
Normal file
218
app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/BWebview.kt
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.view
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.view.View
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import bums.lunatic.launcher.tokiz.common.TouchArea
|
||||||
|
import bums.lunatic.launcher.tokiz.webcontents.contentsinfo.BooktokiStruct
|
||||||
|
import bums.lunatic.launcher.utils.Blog
|
||||||
|
import bums.lunatic.launcher.utils.SimpleFingerGestures
|
||||||
|
import org.mozilla.geckoview.GeckoView
|
||||||
|
|
||||||
|
enum class JxEvent {
|
||||||
|
SCROLL_UP,
|
||||||
|
SCROLL_DOWN,
|
||||||
|
SWIPE_LEFT,
|
||||||
|
SWIPE_RIGHT,
|
||||||
|
ON_CLICK,
|
||||||
|
}
|
||||||
|
typealias JxInteface = (JxEvent)->Unit
|
||||||
|
open class BWebview : GeckoView {
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
constructor(context: Context?) : super(context) {
|
||||||
|
this.setOnTouchListener { v,e ->
|
||||||
|
if (e.device.name.contains("JX-12",true) == true) {
|
||||||
|
return@setOnTouchListener mSimpleFingerGestures.onTouch(v,e)
|
||||||
|
} else {
|
||||||
|
return@setOnTouchListener super.onTouchEvent(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||||
|
this.setOnTouchListener { v,e ->
|
||||||
|
if (e.device.name.contains("JX-12",true) == true) {
|
||||||
|
return@setOnTouchListener mSimpleFingerGestures.onTouch(v,e)
|
||||||
|
} else {
|
||||||
|
return@setOnTouchListener super.onTouchEvent(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val mSimpleFingerGestures = SimpleFingerGestures(omfgl = object : SimpleFingerGestures.OnFingerGestureListener{
|
||||||
|
|
||||||
|
override fun onSwipeUp(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
jxInteface?.invoke(JxEvent.SCROLL_UP )
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeDown(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
jxInteface?.invoke(JxEvent.SCROLL_DOWN)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeLeft(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
jxInteface?.invoke(JxEvent.SWIPE_LEFT)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeRight(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
jxInteface?.invoke(JxEvent.SWIPE_RIGHT)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPinch(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("onPinch")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUnpinch(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDoubleTap(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLongPress(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("onLongPress")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("onClick")
|
||||||
|
jxInteface?.invoke(JxEvent.ON_CLICK)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
companion object {
|
||||||
|
var currentRetryCount = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var jxInteface : JxInteface? = null
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun loadUrl(url: String) {
|
||||||
|
if (this.isVisible == false) {
|
||||||
|
this.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
Blog.LOGE("url >>>> ${url}")
|
||||||
|
var nUrl = url
|
||||||
|
if (url.startsWith("http") == false) {
|
||||||
|
nUrl = BooktokiStruct.getLastedDoamin().plus(url)
|
||||||
|
}
|
||||||
|
nUrl?.let { url ->
|
||||||
|
if (url.split("//").size > 1) {
|
||||||
|
url.replace("//","/").replace("https:/","https://").let {
|
||||||
|
Blog.LOGE("url >> ${url} , it >>> ${it}")
|
||||||
|
this.session?.loadUri(it)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.session?.loadUri(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentRetryCount = 0;
|
||||||
|
}
|
||||||
|
private var lastX = 0f
|
||||||
|
private var lastY = 0f
|
||||||
|
|
||||||
|
|
||||||
|
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||||
|
Blog.LOGE("event.device.name >>> ${event.device.name}")
|
||||||
|
if (event.device.name.contains("JX-12", true)) {
|
||||||
|
Blog.LOGE("BWebview onTouchEvent $event")
|
||||||
|
when (event.action) {
|
||||||
|
MotionEvent.ACTION_DOWN -> {
|
||||||
|
lastX = event.x
|
||||||
|
lastY = event.y
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
MotionEvent.ACTION_MOVE -> {
|
||||||
|
val deltaX = event.x - lastX
|
||||||
|
val deltaY = event.y - lastY
|
||||||
|
// 상하 이동이 더 크면(즉, 거의 수직 이동이면)만 처리
|
||||||
|
if (Math.abs(deltaY) > Math.abs(deltaX)) {
|
||||||
|
// 원하는 감도 적용
|
||||||
|
val scrollFactor = 0.1f
|
||||||
|
// scrollBy(0, (-deltaY * scrollFactor).toInt())
|
||||||
|
|
||||||
|
jxInteface?.invoke(if ((-deltaY * scrollFactor).toInt() > 0){
|
||||||
|
JxEvent.SCROLL_DOWN
|
||||||
|
} else {
|
||||||
|
JxEvent.SCROLL_UP
|
||||||
|
})
|
||||||
|
lastY = event.y
|
||||||
|
lastX = event.x
|
||||||
|
Blog.LOGE("return true for scroll")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// 좌우 이동은 무시
|
||||||
|
lastY = event.y
|
||||||
|
lastX = event.x
|
||||||
|
Blog.LOGE("return false")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
Blog.LOGE("call super")
|
||||||
|
return super.onTouchEvent(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return super.onTouchEvent(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.view
|
||||||
|
|
||||||
|
interface PagedTextGenerateInterface {
|
||||||
|
fun completePagination(pageList: ArrayList<CharSequence>)
|
||||||
|
}
|
||||||
@ -0,0 +1,316 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.view
|
||||||
|
|
||||||
|
import android.annotation.TargetApi
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Handler
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.constraintlayout.widget.Guideline
|
||||||
|
import bums.lunatic.launcher.R
|
||||||
|
import bums.lunatic.launcher.tokiz.common.TouchArea
|
||||||
|
import bums.lunatic.launcher.utils.Blog
|
||||||
|
import bums.lunatic.launcher.utils.SimpleFingerGestures
|
||||||
|
|
||||||
|
class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
|
||||||
|
constructor(context: Context) : super(context) {initView(context)}
|
||||||
|
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {initView(context)}
|
||||||
|
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||||
|
context,
|
||||||
|
attrs,
|
||||||
|
defStyleAttr
|
||||||
|
) {initView(context)}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet?,
|
||||||
|
defStyleAttr: Int,
|
||||||
|
defStyleRes: Int
|
||||||
|
) : super(context, attrs, defStyleAttr, defStyleRes) {initView(context)}
|
||||||
|
var mainTextView : TextView? = null
|
||||||
|
var sencondTextView : TextView? = null
|
||||||
|
var demp : View? = null
|
||||||
|
var hiddenTextView : PagedTextView? = null
|
||||||
|
var guideLine : Guideline? = null
|
||||||
|
var pageList: ArrayList<CharSequence>? = null
|
||||||
|
var summaryText : String = ""
|
||||||
|
var text : String = ""
|
||||||
|
set(new) {
|
||||||
|
// Blog.LOGE("field >> ${field}")
|
||||||
|
// Blog.LOGE("new >> ${new}")
|
||||||
|
field = new
|
||||||
|
val summary = new.replace(" " ,"").replace("\n" ,"").substring(0,Math.min(30,new.length))
|
||||||
|
if (summary.equals(summaryText)) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Blog.LOGE("field >> ${field}")
|
||||||
|
hiddenTextView?.setTxtF(field)
|
||||||
|
hiddenTextView?.visibility = VISIBLE
|
||||||
|
}
|
||||||
|
summaryText = summary
|
||||||
|
}
|
||||||
|
|
||||||
|
private val hanler = Handler()
|
||||||
|
var mPagedTextViewInterface : PagedTextViewInterface? = null
|
||||||
|
val touchTimeover = Runnable {
|
||||||
|
mPagedTextViewInterface?.onTimeoverTouch()
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentPageTextView : TextView? = null
|
||||||
|
fun initView(context: Context) {
|
||||||
|
inflate(context, R.layout.layout_textviewer, this)
|
||||||
|
mainTextView = findViewById(R.id.first_view)
|
||||||
|
sencondTextView = findViewById(R.id.sencond_view)
|
||||||
|
demp = findViewById(R.id.demp)
|
||||||
|
currentPageTextView = findViewById(R.id.current_page)
|
||||||
|
|
||||||
|
hiddenTextView = findViewById(R.id.hidden_view)
|
||||||
|
hiddenTextView?.mPagedTextGenerateInterface = this
|
||||||
|
currentPageTextView?.text = ""
|
||||||
|
hanler.removeCallbacks(touchTimeover)
|
||||||
|
setOnLongClickListener { v ->
|
||||||
|
mPagedTextViewInterface?.onLongClick()
|
||||||
|
return@setOnLongClickListener false
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnTouchListener(SimpleFingerGestures(omfgl = object : SimpleFingerGestures.OnFingerGestureListener{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
override fun onSwipeUp(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
mPagedTextViewInterface?.onSwipeUp(fingers)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeDown(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
mPagedTextViewInterface?.onSwipeDown(fingers)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeLeft(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
mPagedTextViewInterface?.onSwipeLeft(fingers)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeRight(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
mPagedTextViewInterface?.onSwipeRight(fingers)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPinch(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("onPinch")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUnpinch(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int,
|
||||||
|
gestureDuration: Long,
|
||||||
|
gestureDistance: Double
|
||||||
|
): Boolean {
|
||||||
|
mPagedTextViewInterface?.onLongClick()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDoubleTap(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int
|
||||||
|
): Boolean {
|
||||||
|
hanler.removeCallbacks(touchTimeover)
|
||||||
|
mPagedTextViewInterface?.onLongClick()
|
||||||
|
hanler?.postDelayed(touchTimeover, 3000L)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLongPress(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("onLongPress")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(
|
||||||
|
targetView: View,
|
||||||
|
fingers: Int
|
||||||
|
): Boolean {
|
||||||
|
Blog.LOGE("onClick")
|
||||||
|
mPagedTextViewInterface?.onTouch(TouchArea.Center)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun layoutChange(needDualPage: Boolean) {
|
||||||
|
Blog.LOGD(log = "layoutChange>> ${this::class.java.name}")
|
||||||
|
if (needDualPage) {
|
||||||
|
sencondTextView?.visibility = VISIBLE
|
||||||
|
demp?.visibility = VISIBLE
|
||||||
|
} else {
|
||||||
|
sencondTextView?.visibility = GONE
|
||||||
|
demp?.visibility = GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
||||||
|
super.onLayout(changed, left, top, right, bottom)
|
||||||
|
Blog.LOGD(log = "onLayout>> ${this::class.java.name} changed >> ${changed}")
|
||||||
|
if(changed) {
|
||||||
|
hiddenTextView?.text = text
|
||||||
|
forceUpdateUI()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||||
|
super.onSizeChanged(w, h, oldw, oldh)
|
||||||
|
Blog.LOGD(log = "onSizeChanged>> ${this::class.java.name}")
|
||||||
|
if (w != oldw || oldh != h) {
|
||||||
|
postDelayed(Runnable {
|
||||||
|
layoutChange(w > (h * 0.7f))
|
||||||
|
|
||||||
|
},20)
|
||||||
|
}else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var currentPage = 0
|
||||||
|
override fun completePagination(pageList: ArrayList<CharSequence>) {
|
||||||
|
// Blog.LOGD(log = "completePagination>> ${this::class.java.name} >> pageList ${pageList}")
|
||||||
|
if(text.length > 0 && pageList!= null && pageList.size == 0) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.pageList = pageList
|
||||||
|
setPageBy(0)
|
||||||
|
}
|
||||||
|
hiddenTextView?.visibility = GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setColorStyle(colors : Array<String>) {
|
||||||
|
setBackgroundColor(Color.parseColor(colors.get(1)))
|
||||||
|
mainTextView?.setBackgroundColor(Color.parseColor(colors.get(1)))
|
||||||
|
sencondTextView?.setBackgroundColor(Color.parseColor(colors.get(1)))
|
||||||
|
mainTextView?.setTextColor(Color.parseColor(colors.get(0)))
|
||||||
|
sencondTextView?.setTextColor(Color.parseColor(colors.get(0)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// fun setPagedTextViewInterface(pagedTextViewInterface: PagedTextViewInterface) = hiddenTextView?.setPagedTextViewInterface(pagedTextViewInterface)
|
||||||
|
// fun setText(replace: String) = hiddenTextView?.setText(replace)
|
||||||
|
|
||||||
|
fun setTextSize(fl: Float) {
|
||||||
|
hiddenTextView?.setTextSize(fl)
|
||||||
|
mainTextView?.setTextSize(fl)
|
||||||
|
sencondTextView?.setTextSize(fl)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun next(page : Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isDualPage() : Boolean {
|
||||||
|
return sencondTextView?.visibility == VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setPageBy(num : Int) {
|
||||||
|
currentPage = num
|
||||||
|
var realPage = if(isDualPage()) currentPage * 2 else currentPage
|
||||||
|
Blog.LOGE("realPage = if(${pageList?.size} ?: 0 > ${realPage}) { realPage} else { ${(pageList?.size ?: 0) - 1 }}")
|
||||||
|
realPage = if(pageList?.size ?: 0 > realPage) { realPage} else { (pageList?.size ?: 0) - 1 }
|
||||||
|
currentPageTextView?.text = "${realPage + 1 }/${ pageList?.size ?: 0 + 1}"
|
||||||
|
|
||||||
|
mainTextView?.text = pageList?.get(realPage) ?: "NONE"
|
||||||
|
if(isDualPage()) {
|
||||||
|
realPage = realPage.inc()
|
||||||
|
sencondTextView?.text = if(pageList?.size ?: 0 > realPage) { pageList?.get(realPage)} else { "끝"}
|
||||||
|
} else {
|
||||||
|
sencondTextView?.text = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun size(): Int = if(isDualPage()) Math.round((hiddenTextView?.size() ?:0) * 0.5f) else hiddenTextView?.size() ?: 0
|
||||||
|
fun getFastPageCount() = if(isDualPage()) 3 else 6
|
||||||
|
fun current(): Int = currentPage
|
||||||
|
fun doNext(fast : Boolean = false) {
|
||||||
|
if (fast) {
|
||||||
|
setPageBy(if((currentPage + getFastPageCount()) >= 0) {
|
||||||
|
currentPage + getFastPageCount()
|
||||||
|
} else {size()})
|
||||||
|
} else {
|
||||||
|
setPageBy(currentPage.inc())
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doPrev(fast : Boolean = false) {
|
||||||
|
if (fast) {
|
||||||
|
setPageBy(if((currentPage - getFastPageCount()) >= 0) {
|
||||||
|
currentPage - getFastPageCount()
|
||||||
|
} else {0})
|
||||||
|
} else {
|
||||||
|
setPageBy(if(currentPage > 0 )currentPage.dec() else 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun forceUpdateUI() {
|
||||||
|
hiddenTextView?.doUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
|
||||||
|
hiddenTextView?.setPadding(left,top,right, bottom)
|
||||||
|
mainTextView?.setPadding(left,top,right, bottom)
|
||||||
|
sencondTextView?.setPadding(left,top,right, bottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun setTypeface(tf: Typeface?) {
|
||||||
|
hiddenTextView?.setTypeface(tf)
|
||||||
|
mainTextView?.setTypeface(tf)
|
||||||
|
sencondTextView?.setTypeface(tf)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
fun setLetterSpacing(letterSpacing: Float) {
|
||||||
|
hiddenTextView?.letterSpacing = letterSpacing.times(0.01f)
|
||||||
|
mainTextView?.letterSpacing = letterSpacing.times(0.01f)
|
||||||
|
sencondTextView?.letterSpacing = letterSpacing.times(0.01f)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun setLineSpacing(mult: Float) {
|
||||||
|
hiddenTextView?.setLineSpacing(1f, 1f.plus(mult.times(0.01f)))
|
||||||
|
mainTextView?.setLineSpacing(1f, 1f.plus(mult.times(0.01f)))
|
||||||
|
sencondTextView?.setLineSpacing(1f, 1f.plus(mult.times(0.01f)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,263 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.view
|
||||||
|
|
||||||
|
import android.annotation.TargetApi
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.os.Build
|
||||||
|
import android.text.Layout
|
||||||
|
import android.text.StaticLayout
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.util.TypedValue
|
||||||
|
import androidx.appcompat.widget.AppCompatTextView
|
||||||
|
import androidx.core.view.marginBottom
|
||||||
|
import androidx.core.view.marginLeft
|
||||||
|
import androidx.core.view.marginRight
|
||||||
|
import androidx.core.view.marginTop
|
||||||
|
import bums.lunatic.launcher.utils.Blog
|
||||||
|
import kotlinx.coroutines.MainScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class PagedTextView : AppCompatTextView {
|
||||||
|
|
||||||
|
private var needPaginate = false
|
||||||
|
private var isPaginating = false
|
||||||
|
private val pageList = arrayListOf<CharSequence>()
|
||||||
|
private var pageIndex: Int = 0
|
||||||
|
private var pageHeight: Int = 0
|
||||||
|
private var originalText: CharSequence = ""
|
||||||
|
|
||||||
|
var mPagedTextGenerateInterface : PagedTextGenerateInterface? = null
|
||||||
|
|
||||||
|
|
||||||
|
constructor(context: Context?) : super(context!!){initView(context)}
|
||||||
|
|
||||||
|
constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs){initView(context)}
|
||||||
|
|
||||||
|
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context!!, attrs, defStyleAttr){initView(context)}
|
||||||
|
|
||||||
|
fun initView(context: Context?){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun size(): Int = pageList.size
|
||||||
|
fun current() : Int = pageIndex
|
||||||
|
|
||||||
|
fun doPrev() {
|
||||||
|
if (pageIndex > 0 )
|
||||||
|
pageIndex = pageIndex - 1
|
||||||
|
setPageText()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doNext() {
|
||||||
|
if (pageIndex < pageList.size)
|
||||||
|
pageIndex = pageIndex + 1
|
||||||
|
setPageText()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun next(index: Int) {
|
||||||
|
pageIndex = index
|
||||||
|
setPageText()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setPageText() {
|
||||||
|
if(pageList.size > 0) {
|
||||||
|
isPaginating = true
|
||||||
|
text = pageList[pageIndex]
|
||||||
|
isPaginating = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setTxtF(text: CharSequence?) {
|
||||||
|
needPaginate = true
|
||||||
|
this.setText(text , null)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setText(text: CharSequence?, type: BufferType?) {
|
||||||
|
if (!isPaginating) {
|
||||||
|
needPaginate = true
|
||||||
|
originalText = text ?: ""
|
||||||
|
}
|
||||||
|
super.setText(text, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
override fun setTextSize(size: Float) {
|
||||||
|
setTextSize(TypedValue.COMPLEX_UNIT_SP, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setTextSize(unit: Int, size: Float) {
|
||||||
|
super.setTextSize(unit, size)
|
||||||
|
paint.textSize = TypedValue.applyDimension(unit, size, context.resources.getDisplayMetrics())
|
||||||
|
needPaginate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
|
||||||
|
super.setPadding(left, top, right, bottom)
|
||||||
|
needPaginate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setPaddingRelative(start: Int, top: Int, end: Int, bottom: Int) {
|
||||||
|
super.setPaddingRelative(start, top, end, bottom)
|
||||||
|
needPaginate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setTextScaleX(size: Float) {
|
||||||
|
if (size != textScaleX) {
|
||||||
|
needPaginate = true
|
||||||
|
}
|
||||||
|
super.setTextScaleX(size)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setTypeface(tf: Typeface?) {
|
||||||
|
if (typeface != null && tf != typeface) {
|
||||||
|
needPaginate = true
|
||||||
|
paint.typeface = tf
|
||||||
|
}
|
||||||
|
super.setTypeface(tf)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
override fun setLetterSpacing(letterSpacing: Float) {
|
||||||
|
if (letterSpacing != this.letterSpacing) {
|
||||||
|
needPaginate = true
|
||||||
|
}
|
||||||
|
super.setLetterSpacing(letterSpacing)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setHorizontallyScrolling(whether: Boolean) {
|
||||||
|
super.setHorizontallyScrolling(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setLineSpacing(add: Float, mult: Float) {
|
||||||
|
if (add != lineSpacingExtra || mult != lineSpacingMultiplier) {
|
||||||
|
needPaginate = true
|
||||||
|
}
|
||||||
|
super.setLineSpacing(add, mult)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setMaxLines(maxLines: Int) {
|
||||||
|
if (maxLines != this.maxLines) {
|
||||||
|
needPaginate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
super.setMaxLines(maxLines)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setLines(lines: Int) {
|
||||||
|
super.setLines(lines)
|
||||||
|
|
||||||
|
if (lines != this.lineCount) {
|
||||||
|
needPaginate = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||||
|
super.onSizeChanged(w, h, oldw, oldh)
|
||||||
|
Blog.LOGD(log = "onSizeChanged>> ${this::class.java.name}")
|
||||||
|
pageHeight = ((h - (marginTop + marginBottom + paddingTop + paddingBottom)) * 1f).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
||||||
|
super.onLayout(changed, left, top, right, bottom)
|
||||||
|
Blog.LOGD(log = "onLayout>> ${this::class.java.name} changed >> ${changed}")
|
||||||
|
if (changed || needPaginate) {
|
||||||
|
paginate()
|
||||||
|
setPageText()
|
||||||
|
needPaginate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
fun doUpdate() {
|
||||||
|
if (needPaginate && layout != null) {
|
||||||
|
paginate()
|
||||||
|
setPageText()
|
||||||
|
needPaginate = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private fun paginate() {
|
||||||
|
if (layout != null) {
|
||||||
|
MainScope().launch {
|
||||||
|
pageList.clear()
|
||||||
|
// Blog.LOGD(log = "paginate>> ${this::class.java.name} && ${layout.text}")
|
||||||
|
val layout = from(layout)
|
||||||
|
val lines = if(min(maxLines, layout.lineCount) > 10) {min(maxLines, layout.lineCount) - 1} else {min(maxLines, layout.lineCount)}
|
||||||
|
var startOffset = 0
|
||||||
|
val heightWithoutPaddings = pageHeight //- (marginTop + marginBottom + paddingTop + paddingBottom)
|
||||||
|
var height = heightWithoutPaddings
|
||||||
|
|
||||||
|
for (i in 0 until lines) {
|
||||||
|
if (height < layout.getLineBottom(i)) {
|
||||||
|
pageList.add(
|
||||||
|
layout.text.subSequence(startOffset, layout.getLineStart(i))
|
||||||
|
)
|
||||||
|
startOffset = layout.getLineStart(i)
|
||||||
|
height = layout.getLineTop(i) + heightWithoutPaddings
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == lines - 1) {
|
||||||
|
pageList.add(
|
||||||
|
if(layout.lineCount > i) {
|
||||||
|
layout.text.subSequence(startOffset, layout.getLineEnd(i + 1))
|
||||||
|
} else {
|
||||||
|
layout.text.subSequence(startOffset, layout.getLineEnd(i))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mPagedTextGenerateInterface?.completePagination(pageList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun from(layout: Layout): Layout =
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
(StaticLayout(
|
||||||
|
originalText,
|
||||||
|
paint,
|
||||||
|
layout.width,
|
||||||
|
layout.alignment,
|
||||||
|
lineSpacingMultiplier,
|
||||||
|
lineSpacingExtra,
|
||||||
|
includeFontPadding
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
StaticLayout.Builder
|
||||||
|
.obtain(originalText, 0, originalText.length, paint, ((layout.width - (paddingLeft + paddingRight + marginLeft + marginRight) * 0.85f)).toInt())
|
||||||
|
.setAlignment(layout.alignment)
|
||||||
|
.setLineSpacing(lineSpacingExtra, lineSpacingMultiplier)
|
||||||
|
.setIncludePad(includeFontPadding)
|
||||||
|
.setUseLineSpacingFromFallbacks()
|
||||||
|
.setBreakStrategy(breakStrategy)
|
||||||
|
.setHyphenationFrequency(hyphenationFrequency)
|
||||||
|
// .setJustificationMode()
|
||||||
|
.setMaxLines(maxLines)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun StaticLayout.Builder.setUseLineSpacingFromFallbacks(): StaticLayout.Builder {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
|
this.setUseLineSpacingFromFallbacks(isFallbackLineSpacing)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun StaticLayout.Builder.setJustificationMode(): StaticLayout.Builder {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
this.setJustificationMode(justificationMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.view
|
||||||
|
|
||||||
|
import bums.lunatic.launcher.tokiz.common.TouchArea
|
||||||
|
|
||||||
|
interface PagedTextViewInterface {
|
||||||
|
fun onTouch(touchArea: TouchArea)
|
||||||
|
fun onTimeoverTouch()
|
||||||
|
fun onSwipeLeft(touchCount : Int)
|
||||||
|
fun onSwipeRight(touchCount : Int)
|
||||||
|
fun onSwipeDown(touchCount : Int)
|
||||||
|
fun onSwipeUp(touchCount : Int)
|
||||||
|
fun onLongClick()
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.view
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
|
||||||
|
class ScopeEditor: SideButtonTextView {
|
||||||
|
constructor(context: Context) : super(context)
|
||||||
|
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
||||||
|
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||||
|
context,
|
||||||
|
attrs,
|
||||||
|
defStyleAttr
|
||||||
|
)
|
||||||
|
var titleArray : Array<String>? = null
|
||||||
|
set(value) {
|
||||||
|
if(value != null && value.size < 1) {
|
||||||
|
Error("titleArray는 최소 한개 이상이여야됨.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
field = value
|
||||||
|
maxValue = field!!.size
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxValue : Int = 1
|
||||||
|
set(value) {
|
||||||
|
if (value < 1) {
|
||||||
|
Error("maxValue는 무조건 0보다 커야하눈뎅....")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override var value : Int = 14
|
||||||
|
set(newValue) {
|
||||||
|
field = newValue
|
||||||
|
text_value?.text = displayFormat.format(titleArray?.get(field) ?:"defulat")
|
||||||
|
mValueChange?.invoke(field)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet?,
|
||||||
|
defStyleAttr: Int,
|
||||||
|
defStyleRes: Int
|
||||||
|
) : super(context, attrs, defStyleAttr, defStyleRes)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
// super.i
|
||||||
|
// inflate(context, R.layout.layout_steps_editor,this)
|
||||||
|
btn_decrement?.setOnClickListener { value = Math.abs(value.dec()).rem(maxValue) }
|
||||||
|
btn_increment?.setOnClickListener { value = value.inc().rem(maxValue) }
|
||||||
|
leftButtonTitle = "<"
|
||||||
|
rightButtonTitle = ">"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.view
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.appcompat.widget.AppCompatButton
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import bums.lunatic.launcher.R
|
||||||
|
|
||||||
|
open class SideButtonTextView : ConstraintLayout {
|
||||||
|
constructor(context: Context) : super(context)
|
||||||
|
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
||||||
|
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||||
|
context,
|
||||||
|
attrs,
|
||||||
|
defStyleAttr
|
||||||
|
)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet?,
|
||||||
|
defStyleAttr: Int,
|
||||||
|
defStyleRes: Int
|
||||||
|
) : super(context, attrs, defStyleAttr, defStyleRes)
|
||||||
|
|
||||||
|
var leftButtonTitle : String = ""
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
btn_decrement?.text = field
|
||||||
|
}
|
||||||
|
|
||||||
|
var rightButtonTitle : String = ""
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
btn_increment?.text = field
|
||||||
|
}
|
||||||
|
|
||||||
|
open var value : Int = 14
|
||||||
|
set(newValue) {
|
||||||
|
field = newValue
|
||||||
|
text_value?.text = displayFormat.format(field)
|
||||||
|
mValueChange?.invoke(field)
|
||||||
|
}
|
||||||
|
|
||||||
|
var displayFormat = "글자 크기 : %d"
|
||||||
|
set(newValue) {
|
||||||
|
field = newValue
|
||||||
|
try {
|
||||||
|
text_value?.text = displayFormat.format(value)
|
||||||
|
} catch (e : Exception) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var mValueChange : ValueChange? = null
|
||||||
|
set(newValue) {
|
||||||
|
field = newValue
|
||||||
|
if (newValue != null) {
|
||||||
|
newValue(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var btn_decrement : AppCompatButton? = null
|
||||||
|
var btn_increment : AppCompatButton? = null
|
||||||
|
var text_value : TextView? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
inflate(context, R.layout.layout_steps_editor,this)
|
||||||
|
btn_increment = findViewById(R.id.btn_increment)
|
||||||
|
btn_decrement = findViewById(R.id.btn_decrement)
|
||||||
|
text_value = findViewById(R.id.text_value)
|
||||||
|
btn_decrement?.setOnClickListener { value = value.dec() }
|
||||||
|
btn_increment?.setOnClickListener { value = value.inc() }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.view
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
|
||||||
|
typealias ValueChange = (Int)->Unit
|
||||||
|
|
||||||
|
class StepsEditor : SideButtonTextView {
|
||||||
|
constructor(context: Context) : super(context)
|
||||||
|
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
||||||
|
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||||
|
context,
|
||||||
|
attrs,
|
||||||
|
defStyleAttr
|
||||||
|
)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet?,
|
||||||
|
defStyleAttr: Int,
|
||||||
|
defStyleRes: Int
|
||||||
|
) : super(context, attrs, defStyleAttr, defStyleRes)
|
||||||
|
|
||||||
|
init {
|
||||||
|
// inflate(context, R.layout.layout_steps_editor,this)
|
||||||
|
btn_decrement?.setOnClickListener { value = value.dec() }
|
||||||
|
btn_increment?.setOnClickListener { value = value.inc() }
|
||||||
|
leftButtonTitle = "-"
|
||||||
|
rightButtonTitle = "+"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,226 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.webcontents//package com.mime.dualscreenview.webcontents
|
||||||
|
//
|
||||||
|
//import android.annotation.SuppressLint
|
||||||
|
//import android.content.Context
|
||||||
|
//import android.graphics.Bitmap
|
||||||
|
//import android.net.http.SslError
|
||||||
|
//import android.os.Build
|
||||||
|
//import android.util.Log
|
||||||
|
//import android.webkit.SslErrorHandler
|
||||||
|
//import android.webkit.WebResourceRequest
|
||||||
|
//import android.webkit.WebResourceResponse
|
||||||
|
//import android.webkit.WebView
|
||||||
|
//import android.webkit.WebViewClient
|
||||||
|
//import androidx.core.net.toUri
|
||||||
|
//import com.mime.dualscreenview.common.Blog
|
||||||
|
//import com.mime.dualscreenview.common.PrefManager
|
||||||
|
//import com.mime.dualscreenview.data.model.LastInfo
|
||||||
|
//
|
||||||
|
//import okhttp3.ConnectionPool
|
||||||
|
//import okhttp3.Headers
|
||||||
|
//import okhttp3.Headers.Companion.toHeaders
|
||||||
|
//import okhttp3.Interceptor
|
||||||
|
//import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
|
//import okhttp3.OkHttpClient
|
||||||
|
//import okhttp3.Request
|
||||||
|
//import okhttp3.RequestBody
|
||||||
|
//import okhttp3.Response
|
||||||
|
//
|
||||||
|
//import java.io.IOException
|
||||||
|
//import java.net.SocketException
|
||||||
|
//import java.util.concurrent.TimeUnit
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//class BWebviewClient
|
||||||
|
// (
|
||||||
|
// private val mainControllInterface : MainControllInterface,
|
||||||
|
// private val context: Context, ) : WebViewClient() {
|
||||||
|
//
|
||||||
|
// var currentContentsProvider : BaseWebContents? = null
|
||||||
|
// // OkHttp 클라이언트 (싱글톤 권장)
|
||||||
|
// private val httpClient by lazy {
|
||||||
|
// OkHttpClient.Builder()
|
||||||
|
// .retryOnConnectionFailure(true)
|
||||||
|
// .connectionPool(ConnectionPool(5, 30, TimeUnit.SECONDS))
|
||||||
|
// .pingInterval(20, TimeUnit.SECONDS)
|
||||||
|
// .addInterceptor(RetryInterceptor(maxRetries = 3))
|
||||||
|
// .build()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun shouldInterceptRequest(
|
||||||
|
// view: WebView?,
|
||||||
|
// request: WebResourceRequest?
|
||||||
|
// ): WebResourceResponse? {
|
||||||
|
// request ?: return null
|
||||||
|
//
|
||||||
|
// // HTTPS/HTTP 요청만 처리
|
||||||
|
// if (request.url.scheme !in listOf("http", "https")) {
|
||||||
|
// return super.shouldInterceptRequest(view, request)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (request.method != "GET" ||
|
||||||
|
// request.url.scheme !in listOf("http", "https")) {
|
||||||
|
// return super.shouldInterceptRequest(view, request)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 웹뷰 요청을 OkHttp로 변환
|
||||||
|
// return try {
|
||||||
|
// val okHttpRequest = Request.Builder()
|
||||||
|
// .url(request.url.toString())
|
||||||
|
// .headers(request.requestHeaders.toHeaders())
|
||||||
|
// .get() // GET 요청으로 고정
|
||||||
|
// .build()
|
||||||
|
//
|
||||||
|
// val response = httpClient.newCall(okHttpRequest).execute()
|
||||||
|
// createWebResourceResponse(response)
|
||||||
|
//
|
||||||
|
// } catch (e: SocketException) {
|
||||||
|
// // Connection reset 오류 처리
|
||||||
|
// Log.e("WebViewClient", "SocketException: ${e.message}")
|
||||||
|
// null // WebView 기본 동작 사용
|
||||||
|
// } catch (e: IOException) {
|
||||||
|
// null // 오류 시 WebView 기본 동작
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//// private fun getRequestBody(request: WebResourceRequest): RequestBody? {
|
||||||
|
//// // POST 요청 바디 처리 (API 21+)
|
||||||
|
//// return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
|
||||||
|
//// request.method == "POST" &&
|
||||||
|
//// request.requestBody != null) {
|
||||||
|
////
|
||||||
|
//// val body = request.requestBody!!
|
||||||
|
//// RequestBody.create(
|
||||||
|
//// body.mimeType?.toMediaTypeOrNull(),
|
||||||
|
//// body.inputStream.readBytes()
|
||||||
|
//// )
|
||||||
|
//// } else {
|
||||||
|
//// null
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//
|
||||||
|
// private fun createWebResourceResponse(response: Response): WebResourceResponse {
|
||||||
|
// return WebResourceResponse(
|
||||||
|
// response.body?.contentType()?.type + "/" + response.body?.contentType()?.subtype,
|
||||||
|
// response.body?.contentType()?.charset()?.name(),
|
||||||
|
// response.code,
|
||||||
|
// response.message,
|
||||||
|
// response.headers.toMultimap().mapValues { it.value.joinToString(",") },
|
||||||
|
// response.body?.byteStream()
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Connection reset 재시도 인터셉터
|
||||||
|
// inner class RetryInterceptor(
|
||||||
|
// private val maxRetries: Int
|
||||||
|
// ) : Interceptor {
|
||||||
|
// override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
|
// var response: Response? = null
|
||||||
|
// var retryCount = 0
|
||||||
|
// var lastException: Exception? = null
|
||||||
|
//
|
||||||
|
// while (retryCount <= maxRetries) {
|
||||||
|
// try {
|
||||||
|
// response = chain.proceed(chain.request())
|
||||||
|
// if (response.isSuccessful) return response
|
||||||
|
// } catch (e: SocketException) {
|
||||||
|
// lastException = e
|
||||||
|
// if (e.message?.contains("Connection reset") == true) {
|
||||||
|
// Thread.sleep(1000L * (retryCount + 1))
|
||||||
|
// } else throw e
|
||||||
|
// } catch (e: IOException) {
|
||||||
|
// lastException = e
|
||||||
|
// }
|
||||||
|
// retryCount++
|
||||||
|
// }
|
||||||
|
// throw lastException ?: IOException("Max retries reached")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// override fun shouldOverrideUrlLoading(
|
||||||
|
// view: WebView?,
|
||||||
|
// request: WebResourceRequest?
|
||||||
|
// ): Boolean {
|
||||||
|
// Log.e("shouldOverrideUrlLoading", " >>>> ${request?.url?.toString()} ")
|
||||||
|
// return super.shouldOverrideUrlLoading(view, request)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
|
||||||
|
// super.onPageStarted(view, url, favicon)
|
||||||
|
// mainControllInterface?.onStartLoad()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @SuppressLint("WebViewClientOnReceivedSslError")
|
||||||
|
// override fun onReceivedSslError(
|
||||||
|
// view: WebView?,
|
||||||
|
// handler: SslErrorHandler?,
|
||||||
|
// error: SslError?
|
||||||
|
// ) {
|
||||||
|
//// super.onReceivedSslError(view, handler, error)
|
||||||
|
// Blog.LOGE(log= "onReceivedSslError >> ${error}")
|
||||||
|
// handler?.proceed()
|
||||||
|
// }
|
||||||
|
// override fun onReceivedHttpError(
|
||||||
|
// view: WebView?,
|
||||||
|
// request: WebResourceRequest?,
|
||||||
|
// errorResponse: WebResourceResponse?
|
||||||
|
// ) {
|
||||||
|
// Blog.LOGE(log= "onReceivedHttpError >> ${errorResponse?.reasonPhrase}")
|
||||||
|
//
|
||||||
|
// super.onReceivedHttpError(view, request, errorResponse)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// override fun onPageFinished(view: WebView?, url: String?) {
|
||||||
|
// super.onPageFinished(view, url)
|
||||||
|
// finishedUrl = url ?: ""
|
||||||
|
//
|
||||||
|
// view?.let {
|
||||||
|
// url?.toUri()?.let {
|
||||||
|
// PrefManager.putLastDomain(it.scheme.plus("::/").plus(it.host))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if(url?.contains("/list/") ?: false && url?.contains("agit") ?: false){
|
||||||
|
// findListItem {
|
||||||
|
// Blog.LOGE("onPageFinished", url ?: "")
|
||||||
|
// }
|
||||||
|
// } else if (url?.contains("booktoki") ?: false){
|
||||||
|
//// findListItem {
|
||||||
|
//// Blog.LOGE("onPageFinished", url ?: "")
|
||||||
|
//// }
|
||||||
|
// }
|
||||||
|
// view?.postDelayed({
|
||||||
|
// if (url?.contains("booktoki") ?: false){
|
||||||
|
// findListItem {
|
||||||
|
// Blog.LOGE("onPageFinished", url ?: "")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//// view?.evaluateJavascript(
|
||||||
|
//// "function getAll() {\n" +
|
||||||
|
//// " MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
|
||||||
|
//// " };getAll()"
|
||||||
|
//// ) { result ->
|
||||||
|
//// (result as? String)?.let {
|
||||||
|
////
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//
|
||||||
|
// }, 500L)
|
||||||
|
// currentContentsProvider?.doOnloaded(it , { result ->
|
||||||
|
// result?.let { mainControllInterface.onLoadedContents(it) }
|
||||||
|
// } , { complete ->
|
||||||
|
// if(complete) {
|
||||||
|
// mainControllInterface?.completePageLoad(LastInfo().apply {
|
||||||
|
// this.pageUrl = url?.toUri()?.path ?: currentContentsProvider?.getLastedDoamin() ?: ""
|
||||||
|
// this.contentsName = currentContentsProvider?.getWebcontentsName() ?: ""
|
||||||
|
// this.pageIndex = 0
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
@ -0,0 +1,416 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.webcontents
|
||||||
|
|
||||||
|
import org.jsoup.select.Elements
|
||||||
|
|
||||||
|
|
||||||
|
//open class BaseWebContentsViewer {
|
||||||
|
//
|
||||||
|
//// var currentContentsProvider : BaseWebContents? = null
|
||||||
|
//// lateinit var webview : BWebview
|
||||||
|
// lateinit var webview: BWebview
|
||||||
|
// lateinit var mainControllInterface : MainControllInterface
|
||||||
|
////
|
||||||
|
//// @JavascriptInterface
|
||||||
|
//// fun onBookInfo(jsonData : String) {
|
||||||
|
//// GlobalScope.launch {
|
||||||
|
//// try {
|
||||||
|
//// Blog.LOGE("BaseWebContentsViewer",jsonData)
|
||||||
|
//// val data: JSONObject = JSONObject(jsonData)
|
||||||
|
//// Blog.LOGE("BaseWebContentsViewer",data.toString())
|
||||||
|
//// mainControllInterface?.onBookInfos(jsonData)
|
||||||
|
//// } catch (e : Exception) {
|
||||||
|
////
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//
|
||||||
|
// fun getDeviceIpAddress(): String? {
|
||||||
|
// try {
|
||||||
|
// val en = NetworkInterface.getNetworkInterfaces()
|
||||||
|
// while (en.hasMoreElements()) {
|
||||||
|
// val intf = en.nextElement()
|
||||||
|
// val enumIpAddr = intf.inetAddresses
|
||||||
|
// while (enumIpAddr.hasMoreElements()) {
|
||||||
|
// val inetAddress = enumIpAddr.nextElement()
|
||||||
|
// if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {
|
||||||
|
// return inetAddress.getHostAddress()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (ex: SocketException) {
|
||||||
|
// ex.printStackTrace()
|
||||||
|
// }
|
||||||
|
// return null
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// constructor(geckoView: BWebview, mainControllInterface : MainControllInterface ) {
|
||||||
|
//// val wifiManager = webview.context.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||||
|
//// wifiManager.disconnect()
|
||||||
|
//// Thread.sleep(1000) // 잠시 대기
|
||||||
|
//// wifiManager.reconnect()
|
||||||
|
//
|
||||||
|
// this.webview = geckoView
|
||||||
|
//// this.mainControllInterface = mainControllInterface
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
////
|
||||||
|
////// @SuppressLint("JavascriptInterface", "SetJavaScriptEnabled")
|
||||||
|
////// constructor(webview : BWebview, mainControllInterface : MainControllInterface ) {
|
||||||
|
//////// val wifiManager = webview.context.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||||
|
//////// wifiManager.disconnect()
|
||||||
|
//////// Thread.sleep(1000) // 잠시 대기
|
||||||
|
//////// wifiManager.reconnect()
|
||||||
|
//////
|
||||||
|
////// this.webview = webview
|
||||||
|
////// this.mainControllInterface = mainControllInterface
|
||||||
|
////// //137.0.0.0
|
||||||
|
////// webview.clearHistory();
|
||||||
|
////// webview.clearSslPreferences();
|
||||||
|
////// WebView.setWebContentsDebuggingEnabled(true)
|
||||||
|
////// webview.clearCache(true) // 디스크와 메모리 캐시 모두 삭제
|
||||||
|
//////
|
||||||
|
////// val cookieManager = CookieManager.getInstance()
|
||||||
|
////// cookieManager.removeAllCookies(null) // 모든 쿠키 삭제
|
||||||
|
////// cookieManager.flush()
|
||||||
|
//////// webview.settings.userAgentString = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
|
||||||
|
//////// webview.settings.userAgentString ="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
|
||||||
|
//////// webview.settings.userAgentString ="Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36"
|
||||||
|
////// webview.webChromeClient = rootWebChromeClient
|
||||||
|
////// webview.webViewClient = rootWebViewClient
|
||||||
|
////// webview.settings.textZoom = 100
|
||||||
|
////// webview.addJavascriptInterface(this,"PAgit")
|
||||||
|
////// webview.settings.javaScriptEnabled = true
|
||||||
|
////// webview.settings.javaScriptCanOpenWindowsAutomatically = false
|
||||||
|
////// webview.settings.loadWithOverviewMode = true
|
||||||
|
////// webview.settings.setPluginState(WebSettings.PluginState.ON)
|
||||||
|
////// webview.settings.domStorageEnabled = true
|
||||||
|
////// webview.settings.allowContentAccess = true
|
||||||
|
////// webview.settings.mixedContentMode = 0
|
||||||
|
//////
|
||||||
|
////// webview.getSettings().setJavaScriptEnabled(true)
|
||||||
|
//////// webview.loadUrl(stringExtra)
|
||||||
|
//////// webview.setWebViewClient(WebViewClientClass())
|
||||||
|
////// webview.setScrollBarStyle(0)
|
||||||
|
////// webview.settings.safeBrowsingEnabled = false
|
||||||
|
////// webview.settings.loadsImagesAutomatically = true
|
||||||
|
////// webview.getSettings().setCacheMode(-1)
|
||||||
|
////// webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(false)
|
||||||
|
////// webview.getSettings().setLoadsImagesAutomatically(true)
|
||||||
|
////// webview.getSettings().setUseWideViewPort(true)
|
||||||
|
////// webview.getSettings().setDomStorageEnabled(true)
|
||||||
|
////// webview.getSettings().setAllowFileAccess(true)
|
||||||
|
//////
|
||||||
|
////// webview.getSettings()
|
||||||
|
////// .setUserAgentString("Mozilla/5.0 (Linux; Android 6.0; Android SDK built for x86 Build/MASTER; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.119 Mobile Safari/537.36")
|
||||||
|
////// webview.settings.userAgentString = "Mozilla/5.0 (Linux; Android 6.0; Android SDK built for x86 Build/MASTER; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.119 Mobile Safari/537.36"
|
||||||
|
////// webview.getSettings().setSupportZoom(true)
|
||||||
|
////// webview.getSettings().setBuiltInZoomControls(true)
|
||||||
|
////// webview.getSettings().setDisplayZoomControls(false)
|
||||||
|
////// val settings: WebSettings = webview.getSettings()
|
||||||
|
////// settings.javaScriptEnabled = true
|
||||||
|
////// settings.javaScriptCanOpenWindowsAutomatically = false
|
||||||
|
////// settings.setSupportMultipleWindows(false)
|
||||||
|
////// webview.clearCache(true);
|
||||||
|
//////
|
||||||
|
//////
|
||||||
|
//////
|
||||||
|
//////
|
||||||
|
////// try {
|
||||||
|
////// val settings: WebSettings =webview.getSettings()
|
||||||
|
//////// 네트워크 및 기능 관련
|
||||||
|
////// settings.javaScriptEnabled = true // 자바스크립트 활성화
|
||||||
|
////// settings.javaScriptCanOpenWindowsAutomatically = true // JS로 새창 열기 허용
|
||||||
|
////// settings.loadsImagesAutomatically = true // 이미지 자동 로드
|
||||||
|
////// settings.domStorageEnabled = true // DOM Storage 활성화
|
||||||
|
////// settings.databaseEnabled = true // DB 저장소 활성화
|
||||||
|
//////// settings.app
|
||||||
|
//////// settings.setAppCacheEnabled(true) // 앱 캐시 활성화 (deprecated, 참고용)
|
||||||
|
////// settings.allowFileAccess = true // 파일 접근 허용
|
||||||
|
////// settings.allowContentAccess = true // 컨텐츠 접근 허용
|
||||||
|
////// settings.allowFileAccessFromFileURLs = true // file://에서 file:// 접근 허용
|
||||||
|
////// settings.allowUniversalAccessFromFileURLs = true // file://에서 모든 도메인 접근 허용
|
||||||
|
////// settings.setSupportMultipleWindows(true) // 멀티 윈도우 지원
|
||||||
|
////// settings.useWideViewPort = true // 뷰포트 확대 지원
|
||||||
|
////// settings.loadWithOverviewMode = true // 화면에 맞게 컨텐츠 축소
|
||||||
|
////// settings.setSupportZoom(true) // 줌 지원
|
||||||
|
////// settings.builtInZoomControls = true // 기본 줌 컨트롤 활성화
|
||||||
|
////// settings.displayZoomControls = false // 줌 컨트롤 UI 숨김
|
||||||
|
//////
|
||||||
|
//////
|
||||||
|
//////// 보안 및 고급
|
||||||
|
////// settings.mixedContentMode =
|
||||||
|
////// WebSettings.MIXED_CONTENT_ALWAYS_ALLOW // HTTP/HTTPS 혼합 콘텐츠 허용
|
||||||
|
////// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
////// settings.safeBrowsingEnabled = true // Safe Browsing 활성화
|
||||||
|
////// }
|
||||||
|
////// settings.mediaPlaybackRequiresUserGesture = false // 미디어 자동재생 허용
|
||||||
|
//////
|
||||||
|
//////
|
||||||
|
//////// 기타
|
||||||
|
////// settings.cacheMode = WebSettings.LOAD_NO_CACHE // 기본 캐시 모드
|
||||||
|
//////// settings.setGeolocationEnabled(true) // 위치 정보 허용
|
||||||
|
////// webview.removeJavascriptInterface("MyJavaScriptInterface")
|
||||||
|
////// }catch (e :Exception){e.printStackTrace()}
|
||||||
|
////// webview.addJavascriptInterface( BookHelper(),"MyJavaScriptInterface")
|
||||||
|
////// }
|
||||||
|
////
|
||||||
|
//// constructor()
|
||||||
|
////
|
||||||
|
//// fun loadContents(url: String) {
|
||||||
|
//// webview.loadUrl(url)
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// val rootWebChromeClient = object : WebChromeClient() {
|
||||||
|
//// override fun onProgressChanged(view: WebView?, newProgress: Int) {
|
||||||
|
//// super.onProgressChanged(view, newProgress)
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// override fun onJsAlert(
|
||||||
|
//// view: WebView?,
|
||||||
|
//// url: String?,
|
||||||
|
//// message: String?,
|
||||||
|
//// result: JsResult?
|
||||||
|
//// ): Boolean {
|
||||||
|
//// Blog.LOGE("message")
|
||||||
|
//// result?.cancel()
|
||||||
|
//// return super.onJsAlert(view, url, message, result)
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// override fun onJsPrompt(
|
||||||
|
//// view: WebView?,
|
||||||
|
//// url: String?,
|
||||||
|
//// message: String?,
|
||||||
|
//// defaultValue: String?,
|
||||||
|
//// result: JsPromptResult?
|
||||||
|
//// ): Boolean {
|
||||||
|
//// Blog.LOGE("message")
|
||||||
|
//// result?.cancel()
|
||||||
|
//// return super.onJsPrompt(view, url, message, defaultValue, result)
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// override fun onJsConfirm(
|
||||||
|
//// view: WebView?,
|
||||||
|
//// url: String?,
|
||||||
|
//// message: String?,
|
||||||
|
//// result: JsResult?
|
||||||
|
//// ): Boolean {
|
||||||
|
//// Blog.LOGE("message")
|
||||||
|
//// result?.cancel()
|
||||||
|
//// return super.onJsConfirm(view, url, message, result)
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// fun findListItem(callBakItems : DidFindContents) {
|
||||||
|
////// currentContentsProvider?.findListItem(webview,callBakItems)
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
// fun loadLastInfo(lastInfo: LastInfo) {
|
||||||
|
// lastInfo?.let { last ->
|
||||||
|
// if (last.pageUrl.startsWith("https://")) {
|
||||||
|
// webview.loadUrl(last.pageUrl)
|
||||||
|
// } else {
|
||||||
|
// try {
|
||||||
|
// webview.loadUrl(PrefManager.getLastDomain().plus(last.pageUrl))
|
||||||
|
// } catch (e : Exception) {
|
||||||
|
// webview.loadUrl(PrefManager.getLastDomain())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
////
|
||||||
|
//// val rootWebViewClient = object : WebViewClient() {
|
||||||
|
//// override fun shouldOverrideUrlLoading(
|
||||||
|
//// view: WebView?,
|
||||||
|
//// request: WebResourceRequest?
|
||||||
|
//// ): Boolean {
|
||||||
|
//// Log.e("shouldOverrideUrlLoading", " >>>> ${request?.url?.toString()} ")
|
||||||
|
//// return super.shouldOverrideUrlLoading(view, request)
|
||||||
|
//// }
|
||||||
|
//// override fun shouldInterceptRequest(
|
||||||
|
//// view: WebView?,
|
||||||
|
//// request: WebResourceRequest?
|
||||||
|
//// ): WebResourceResponse? {
|
||||||
|
//// Log.e("shouldInterceptRequest", " >>>> ${request?.url?.toString()} , ${request?.url?.toString()?.contains("gif")}")
|
||||||
|
////
|
||||||
|
////// if(request?.url?.toString()?.contains("gif") ?: false) {
|
||||||
|
////// return WebResourceResponse("text/javascript", "UTF-8", null);
|
||||||
|
////// }
|
||||||
|
////// if(request?.url?.toString()?.contains(currentContentsProvider?.acccceptResourceKeyword() ?: "") == false && request?.url?.toString()?.contains(currentContentsProvider?.getLastedDoamin() ?: "") == false) {
|
||||||
|
////// return WebResourceResponse("text/javascript", "UTF-8", null);
|
||||||
|
////// }
|
||||||
|
//// return super.shouldInterceptRequest(view, request)
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
|
||||||
|
//// super.onPageStarted(view, url, favicon)
|
||||||
|
//// mainControllInterface?.onStartLoad()
|
||||||
|
//// try {
|
||||||
|
//// handler.removeCallbacks(reloadPostHandle)
|
||||||
|
//// }catch (e : Exception) {
|
||||||
|
////
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
////// @SuppressLint("WebViewClientOnReceivedSslError")
|
||||||
|
//// override fun onReceivedSslError(
|
||||||
|
//// view: WebView?,
|
||||||
|
//// handler: SslErrorHandler?,
|
||||||
|
//// error: SslError?
|
||||||
|
//// ) {
|
||||||
|
////// super.onReceivedSslError(view, handler, error)
|
||||||
|
//// Blog.LOGE(log= "onReceivedSslError >> ${error}")
|
||||||
|
//// handler?.cancel()
|
||||||
|
////
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// val maxRetryCount = 10;
|
||||||
|
//// var webView : WebView? = null
|
||||||
|
//// var reloadPostHandle = Runnable {
|
||||||
|
//// webView?.reload()
|
||||||
|
//// BWebview.currentRetryCount += 1
|
||||||
|
//// webView?.context?.let {
|
||||||
|
//// Toast.makeText(it,"retry reload currnent : ${BWebview.currentRetryCount}", Toast.LENGTH_SHORT).show()
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//// override fun onReceivedError(
|
||||||
|
//// view: WebView?,
|
||||||
|
//// request: WebResourceRequest?,
|
||||||
|
//// error: WebResourceError?
|
||||||
|
//// ) {
|
||||||
|
//// super.onReceivedError(view, request, error)
|
||||||
|
//// handler.removeCallbacks(reloadPostHandle)
|
||||||
|
//// if ((error!!.errorCode == ERROR_CONNECT || error!!.errorCode == ERROR_TIMEOUT) && BWebview.currentRetryCount < maxRetryCount) {
|
||||||
|
//// webView = view
|
||||||
|
////
|
||||||
|
//// handler.postDelayed(reloadPostHandle,5000)
|
||||||
|
//// } else {
|
||||||
|
//// view?.context?.let {
|
||||||
|
//// Toast.makeText(it,"fail load cause: ${error.description} : ${error.errorCode}", Toast.LENGTH_SHORT).show()
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// val handler : Handler = Handler(Looper.getMainLooper())
|
||||||
|
////// override fun onReceivedHttpError(
|
||||||
|
////// view: WebView?,
|
||||||
|
////// request: WebResourceRequest?,
|
||||||
|
////// errorResponse: WebResourceResponse?
|
||||||
|
////// ) {
|
||||||
|
////// Blog.LOGE(log= "onReceivedHttpError >> ${errorResponse?.reasonPhrase}")
|
||||||
|
//////
|
||||||
|
//////
|
||||||
|
////// }
|
||||||
|
////
|
||||||
|
////
|
||||||
|
//// override fun onPageFinished(view: WebView?, url: String?) {
|
||||||
|
//// super.onPageFinished(view, url)
|
||||||
|
//// finishedUrl = url ?: ""
|
||||||
|
////
|
||||||
|
//// view?.let {
|
||||||
|
//// url?.toUri()?.let {
|
||||||
|
//// PrefManager.putLastDomain(it.scheme.plus("::/").plus(it.host))
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// if(url?.contains("/list/") ?: false && url?.contains("agit") ?: false){
|
||||||
|
//// findListItem {
|
||||||
|
//// Blog.LOGE("onPageFinished", url ?: "")
|
||||||
|
//// }
|
||||||
|
//// } else if (url?.contains("booktoki") ?: false){
|
||||||
|
////// findListItem {
|
||||||
|
////// Blog.LOGE("onPageFinished", url ?: "")
|
||||||
|
////// }
|
||||||
|
//// }
|
||||||
|
//// view?.postDelayed({
|
||||||
|
//// if (url?.contains("booktoki") ?: false){
|
||||||
|
//// findListItem {
|
||||||
|
//// Blog.LOGE("onPageFinished", url ?: "")
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
////// view?.evaluateJavascript(
|
||||||
|
////// "function getAll() {\n" +
|
||||||
|
////// " MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
|
||||||
|
////// " };getAll()"
|
||||||
|
////// ) { result ->
|
||||||
|
////// (result as? String)?.let {
|
||||||
|
//////
|
||||||
|
////// }
|
||||||
|
////// }
|
||||||
|
////
|
||||||
|
//// }, 500L)
|
||||||
|
//// currentContentsProvider?.doOnloaded(it , { result ->
|
||||||
|
//// result?.let { mainControllInterface.onLoadedContents(it) }
|
||||||
|
//// } , { complete ->
|
||||||
|
//// if(complete) {
|
||||||
|
//// mainControllInterface?.completePageLoad(LastInfo().apply {
|
||||||
|
//// this.pageUrl = url?.toUri()?.path ?: currentContentsProvider?.getLastedDoamin() ?: ""
|
||||||
|
//// this.contentsName = currentContentsProvider?.getWebcontentsName() ?: ""
|
||||||
|
//// this.pageIndex = 0
|
||||||
|
//// })
|
||||||
|
//// }
|
||||||
|
//// })
|
||||||
|
////
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//// var finishedUrl : String = ""
|
||||||
|
//// inner class BookHelper {
|
||||||
|
//// @JavascriptInterface
|
||||||
|
//// fun sendValueFromHtml(string: String) {
|
||||||
|
////
|
||||||
|
//// Jsoup.parse(string)?.let { html ->
|
||||||
|
////
|
||||||
|
//// val toon_intro = html.getElementById("toon_intro")
|
||||||
|
//// val view_padding = html.getElementsByClass("view-padding")
|
||||||
|
//// if (toon_intro != null) {
|
||||||
|
////// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: ${html.title()}")
|
||||||
|
//// val bookPageInfos = BookPageInfos()
|
||||||
|
//// bookPageInfos.bookPageUrl = Uri.parse(finishedUrl).path
|
||||||
|
//// bookPageInfos.bookTitle = if (toon_intro.getElementsByTag("h3").size > 0) toon_intro.getElementsByTag("h3").get(0).text() else ""
|
||||||
|
//// bookPageInfos.pages = realmListOf<BookPageInfo>()
|
||||||
|
////// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: bookPageInfos >>>> ${Gson().toJson(bookPageInfos)}")
|
||||||
|
//// val listParent = html.getElementById("list_type")
|
||||||
|
//// if (listParent != null) {
|
||||||
|
//// listParent.getElementsByClass("row").forEach { bookitem ->
|
||||||
|
////// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: bookItemInfo ${bookitem}")
|
||||||
|
//// try {
|
||||||
|
//// val bookPageInfo = BookPageInfo()
|
||||||
|
//// bookPageInfo.bookTitle = bookPageInfos.bookTitle
|
||||||
|
//// bookPageInfo.chapterNum = bookitem.getElementsByClass("cell_num").getT().toInt()
|
||||||
|
//// bookPageInfo.chapterID = bookitem.getElementsByClass("cell_num").getT().toInt()
|
||||||
|
//// bookPageInfo.chapterTitle = bookitem.getElementsByTag("a").getT()
|
||||||
|
//// bookPageInfo.bookPageUrl = bookPageInfos.bookPageUrl
|
||||||
|
//// val href = bookitem.getElementsByTag("a").get(0).attr("href")
|
||||||
|
//// bookPageInfo.pathUrl = Uri.parse(href).path
|
||||||
|
//// bookPageInfos.pages.add(bookPageInfo)
|
||||||
|
//// }catch (nfe : NumberFormatException) {
|
||||||
|
//// nfe.printStackTrace()
|
||||||
|
//// }
|
||||||
|
//// }.apply {
|
||||||
|
////
|
||||||
|
//// HistoryManager.openRealm.writeBlocking {
|
||||||
|
//// copyToRealm(bookPageInfos, UpdatePolicy.ALL)
|
||||||
|
////// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: bookPageInfos saved >>>> ${bookPageInfos.bookPageUrl}")
|
||||||
|
//// }
|
||||||
|
//// mainControllInterface.onBookInfos(bookPageInfos)
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//// }else if (view_padding.size > 0){
|
||||||
|
////// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: ${html.title()}")
|
||||||
|
//// val contents = view_padding.get(0).children().html().replace("<p>"," ").replace("</p>","\n\n")
|
||||||
|
////// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: view_padding.get(0)\n${contents}")
|
||||||
|
//// if (contents.length > 20) {
|
||||||
|
//// Uri.parse(finishedUrl).path?.let {
|
||||||
|
//// HistoryManager.getBooPageInfoContentsSave(it, contents)
|
||||||
|
//// mainControllInterface.onLoadedContents(contents)
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//// } else {
|
||||||
|
//// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: ${html.title()}")
|
||||||
|
//// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: whole body ${html}")
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
fun Elements.getT() = if (size > 0) get(0).text() else ""
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.webcontents//package bums.lunatic.launcher.booktoki.webcontents
|
||||||
|
//
|
||||||
|
//typealias ActionByBool = (Boolean) -> Unit
|
||||||
|
//typealias DidFindContents = (String?) -> Unit
|
||||||
|
//typealias GotoSomeWhere = () -> Unit
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.webcontents//package bums.lunatic.launcher.booktoki.webcontents
|
||||||
|
//
|
||||||
|
//import com.mime.dualscreenview.data.model.BookPageInfos
|
||||||
|
//import com.mime.dualscreenview.data.model.LastInfo
|
||||||
|
//import com.mime.dualscreenview.webcontents.contentsinfo.GotoSomeWhere
|
||||||
|
//
|
||||||
|
//interface MainControllInterface {
|
||||||
|
// fun onStartLoad()
|
||||||
|
// fun completePageLoad(apply: LastInfo)
|
||||||
|
//
|
||||||
|
// fun showNextBtn(finnd : Boolean, onClickAction: GotoSomeWhere)
|
||||||
|
// fun showPrevBtn(finnd : Boolean,onClickAction: GotoSomeWhere)
|
||||||
|
//
|
||||||
|
// fun showAlert(alert :String)
|
||||||
|
//
|
||||||
|
// fun onLoadedContents(contents :String)
|
||||||
|
// fun onFindTitle(contents :String)
|
||||||
|
//
|
||||||
|
// fun onBookInfos(jsonString : String)
|
||||||
|
// fun onBookInfos(infos : BookPageInfos)
|
||||||
|
//
|
||||||
|
//}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.webcontents//package bums.lunatic.launcher.booktoki.webcontents
|
||||||
|
//
|
||||||
|
//import com.mime.dualscreenview.webcontents.contentsinfo.Agit
|
||||||
|
//import com.mime.dualscreenview.webcontents.contentsinfo.Booktoki
|
||||||
|
//import com.mime.dualscreenview.webcontents.contentsinfo.NewtokiOne
|
||||||
|
//
|
||||||
|
//object WebContentsManger {
|
||||||
|
// val allContentsList : ArrayList<BaseWebContents> = arrayListOf(Booktoki)
|
||||||
|
//
|
||||||
|
// fun getBaseWebContentsBy(name : String) : BaseWebContents {
|
||||||
|
// var correctContents : BaseWebContents = Booktoki
|
||||||
|
// for (contents in allContentsList) {
|
||||||
|
// if(name.equals(contents.getWebcontentsName())) {
|
||||||
|
// correctContents = contents
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return correctContents
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.webcontents.contentsinfo
|
||||||
|
|
||||||
|
abstract class BaseWebContents : ContentsInfoInterface {
|
||||||
|
open var lastNumber : Int = 221
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.webcontents.contentsinfo
|
||||||
|
|
||||||
|
|
||||||
|
object BooktokiStruct : BaseWebContents() {
|
||||||
|
|
||||||
|
override var lastNumber : Int = 468
|
||||||
|
|
||||||
|
override fun getWebcontentsName(): String {
|
||||||
|
return "Booktoki"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLastedDoamin(): String {
|
||||||
|
return String.format("https://booktoki%d.com", lastNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package bums.lunatic.launcher.tokiz.webcontents.contentsinfo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typealias ActionByBool = (Boolean) -> Unit
|
||||||
|
typealias DidFindContents = (String?) -> Unit
|
||||||
|
typealias GotoSomeWhere = () -> Unit
|
||||||
|
|
||||||
|
interface ContentsInfoInterface {
|
||||||
|
fun getWebcontentsName() : String
|
||||||
|
// fun getNextButtonJs() : String
|
||||||
|
// fun getPrevButtonJs() : String
|
||||||
|
// fun getTitleJs() : String
|
||||||
|
// fun getFindContentsJs() : String
|
||||||
|
// fun checkCorrectContents(contents: String) : String
|
||||||
|
fun getLastedDoamin() : String
|
||||||
|
// fun onLoadedJs() : String
|
||||||
|
// fun acccceptResourceKeyword() : String
|
||||||
|
// fun getContentsList() : String
|
||||||
|
}
|
||||||
@ -36,17 +36,27 @@ object Blog {
|
|||||||
LOG(BLogType.E,DEFAULT_TAG,log)
|
LOG(BLogType.E,DEFAULT_TAG,log)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LOG(type : BLogType, tag : String, log : String) {
|
inline fun LOG(type : BLogType, tag : String, log : String) {
|
||||||
|
val stackTrace = Thread.currentThread().stackTrace
|
||||||
|
val blogIndex = stackTrace.indexOfLast { it.className.contains("Blog") }
|
||||||
|
val callerInfo = if (blogIndex != -1 && blogIndex + 1 < stackTrace.size)
|
||||||
|
stackTrace[blogIndex + 1]
|
||||||
|
else null
|
||||||
|
val fileName = callerInfo?.fileName ?: "Unknown"
|
||||||
|
val className = callerInfo?.className ?: "Unknown"
|
||||||
|
val methodName = callerInfo?.methodName ?: "Unknown"
|
||||||
|
val lineNumber = callerInfo?.lineNumber ?: -1
|
||||||
|
|
||||||
if (BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.contains("debug")) {
|
if (BuildConfig.DEBUG || BuildConfig.BUILD_TYPE.contains("debug")) {
|
||||||
when(type) {
|
when(type) {
|
||||||
BLogType.D -> {
|
BLogType.D -> {
|
||||||
Log.d(tag,log)
|
Log.d(tag, ("${fileName}\n${className}\n${methodName} : ${lineNumber}\n" + log))
|
||||||
}
|
}
|
||||||
BLogType.I -> {
|
BLogType.I -> {
|
||||||
Log.i(tag,log)
|
Log.i(tag, ("${fileName}\n${className}\n${methodName} : ${lineNumber}\n" + log))
|
||||||
}
|
}
|
||||||
BLogType.E -> {
|
BLogType.E -> {
|
||||||
Log.e(tag,log)
|
Log.e(tag, ("${fileName}\n${className}\n${methodName} : ${lineNumber}\n" + log))
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,14 @@
|
|||||||
package bums.lunatic.launcher.view
|
package bums.lunatic.launcher.view
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.provider.AlarmClock
|
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
import android.text.SpannableStringBuilder
|
import android.text.SpannableStringBuilder
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import android.text.TextPaint
|
|
||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
import android.text.style.AbsoluteSizeSpan
|
import android.text.style.AbsoluteSizeSpan
|
||||||
import android.text.style.ClickableSpan
|
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.View
|
|
||||||
import androidx.appcompat.widget.AppCompatTextView
|
import androidx.appcompat.widget.AppCompatTextView
|
||||||
import bums.lunatic.launcher.R
|
import bums.lunatic.launcher.R
|
||||||
import bums.lunatic.launcher.helpers.PrefString
|
import bums.lunatic.launcher.helpers.PrefString
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package bums.lunatic.launcher.view
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.OnClickListener
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.RadioButton
|
import android.widget.RadioButton
|
||||||
import android.widget.TableLayout
|
import android.widget.TableLayout
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import android.content.pm.ResolveInfo
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import bums.lunatic.launcher.BuildConfig
|
import bums.lunatic.launcher.BuildConfig
|
||||||
import bums.lunatic.launcher.LauncherActivity
|
|
||||||
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
import bums.lunatic.launcher.LauncherActivity.Companion.lActivity
|
||||||
import bums.lunatic.launcher.apps.AppDrawer.Companion.appNamesPrefs
|
import bums.lunatic.launcher.apps.AppDrawer.Companion.appNamesPrefs
|
||||||
import bums.lunatic.launcher.model.AppInfo
|
import bums.lunatic.launcher.model.AppInfo
|
||||||
|
|||||||
@ -4,13 +4,10 @@ import android.annotation.SuppressLint
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import bums.lunatic.launcher.helpers.PrefHelper
|
|
||||||
import bums.lunatic.launcher.model.DcInside
|
import bums.lunatic.launcher.model.DcInside
|
||||||
import bums.lunatic.launcher.model.RssData
|
|
||||||
import bums.lunatic.launcher.model.RssDataInterface
|
import bums.lunatic.launcher.model.RssDataInterface
|
||||||
import bums.lunatic.launcher.model.RssDataType
|
import bums.lunatic.launcher.model.RssDataType
|
||||||
import bums.lunatic.launcher.model.getRssData
|
import bums.lunatic.launcher.model.getRssData
|
||||||
import bums.lunatic.launcher.utils.Blog
|
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import androidx.work.WorkerParameters
|
|||||||
import bums.lunatic.launcher.model.FmKorea
|
import bums.lunatic.launcher.model.FmKorea
|
||||||
import bums.lunatic.launcher.model.RssDataType
|
import bums.lunatic.launcher.model.RssDataType
|
||||||
import bums.lunatic.launcher.model.getRssData
|
import bums.lunatic.launcher.model.getRssData
|
||||||
import bums.lunatic.launcher.utils.Blog
|
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
|
|||||||
@ -4,10 +4,8 @@ import android.annotation.SuppressLint
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import bums.lunatic.launcher.LauncherActivity.Companion.runWeatherGetter
|
|
||||||
import bums.lunatic.launcher.common.letTrue
|
import bums.lunatic.launcher.common.letTrue
|
||||||
import bums.lunatic.launcher.helpers.PrefBoolean
|
import bums.lunatic.launcher.helpers.PrefBoolean
|
||||||
import bums.lunatic.launcher.utils.Blog
|
|
||||||
import bums.lunatic.launcher.workers.LocationUpdateService.Companion.pushLocation
|
import bums.lunatic.launcher.workers.LocationUpdateService.Companion.pushLocation
|
||||||
import com.google.android.gms.location.LocationServices
|
import com.google.android.gms.location.LocationServices
|
||||||
import com.google.android.gms.location.Priority
|
import com.google.android.gms.location.Priority
|
||||||
@ -33,7 +31,7 @@ class LocationGetter(context: Context, workerParams: WorkerParameters) : BaseGet
|
|||||||
// Blog.LOGE("Location >>> (latitude)${it.longitude}/(longitude)${it.latitude}")
|
// Blog.LOGE("Location >>> (latitude)${it.longitude}/(longitude)${it.latitude}")
|
||||||
longitude = it.longitude
|
longitude = it.longitude
|
||||||
latitude = it.latitude
|
latitude = it.latitude
|
||||||
runWeatherGetter()
|
// runWeatherGetter()
|
||||||
PrefBoolean.location.get().letTrue {
|
PrefBoolean.location.get().letTrue {
|
||||||
pushLocation(this.applicationContext,it.latitude, it.longitude)
|
pushLocation(this.applicationContext,it.latitude, it.longitude)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import android.location.LocationManager
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import bums.lunatic.launcher.LauncherActivity.Companion.runWeatherGetter
|
|
||||||
import bums.lunatic.launcher.common.letTrue
|
import bums.lunatic.launcher.common.letTrue
|
||||||
import bums.lunatic.launcher.helpers.PrefBoolean
|
import bums.lunatic.launcher.helpers.PrefBoolean
|
||||||
import bums.lunatic.launcher.helpers.PrefLong
|
import bums.lunatic.launcher.helpers.PrefLong
|
||||||
@ -141,7 +140,7 @@ class LocationUpdateService : Service(), LocationListener {
|
|||||||
PrefBoolean.location.get().letTrue {
|
PrefBoolean.location.get().letTrue {
|
||||||
longitude = p0.longitude
|
longitude = p0.longitude
|
||||||
latitude = p0.latitude
|
latitude = p0.latitude
|
||||||
runWeatherGetter()
|
// runWeatherGetter()
|
||||||
pushLocation(this.applicationContext, p0.latitude,p0.longitude)
|
pushLocation(this.applicationContext, p0.latitude,p0.longitude)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,7 +172,7 @@ class LocationUpdateService : Service(), LocationListener {
|
|||||||
).show()
|
).show()
|
||||||
longitude = location.longitude
|
longitude = location.longitude
|
||||||
latitude = location.latitude
|
latitude = location.latitude
|
||||||
runWeatherGetter()
|
// runWeatherGetter()
|
||||||
pushLocation(this.applicationContext, location.latitude, location.longitude)
|
pushLocation(this.applicationContext, location.latitude, location.longitude)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import androidx.work.WorkerParameters
|
|||||||
import bums.lunatic.launcher.model.RssDataType
|
import bums.lunatic.launcher.model.RssDataType
|
||||||
import bums.lunatic.launcher.model.RuliWeb
|
import bums.lunatic.launcher.model.RuliWeb
|
||||||
import bums.lunatic.launcher.model.getRssData
|
import bums.lunatic.launcher.model.getRssData
|
||||||
import bums.lunatic.launcher.utils.Blog
|
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
class RuliWebGetter : BaseGetter {
|
class RuliWebGetter : BaseGetter {
|
||||||
|
|||||||
@ -2,6 +2,11 @@ package bums.lunatic.launcher.workers
|
|||||||
|
|
||||||
import bums.lunatic.launcher.BuildConfig
|
import bums.lunatic.launcher.BuildConfig
|
||||||
import bums.lunatic.launcher.apps.SimpleContact
|
import bums.lunatic.launcher.apps.SimpleContact
|
||||||
|
import bums.lunatic.launcher.tokiz.data.model.BookPageInfo
|
||||||
|
import bums.lunatic.launcher.tokiz.data.model.BookPageInfos
|
||||||
|
import bums.lunatic.launcher.tokiz.data.model.HistoryItem
|
||||||
|
import bums.lunatic.launcher.tokiz.data.model.LastInfo
|
||||||
|
import bums.lunatic.launcher.tokiz.data.model.ReaderConfig
|
||||||
import bums.lunatic.launcher.common.letTrue
|
import bums.lunatic.launcher.common.letTrue
|
||||||
import bums.lunatic.launcher.model.AppInfo
|
import bums.lunatic.launcher.model.AppInfo
|
||||||
import bums.lunatic.launcher.model.Astro
|
import bums.lunatic.launcher.model.Astro
|
||||||
@ -18,13 +23,11 @@ import bums.lunatic.launcher.model.LocationLog
|
|||||||
import bums.lunatic.launcher.model.NotificationItem
|
import bums.lunatic.launcher.model.NotificationItem
|
||||||
import bums.lunatic.launcher.model.RssData
|
import bums.lunatic.launcher.model.RssData
|
||||||
import bums.lunatic.launcher.model.RssDataInterface
|
import bums.lunatic.launcher.model.RssDataInterface
|
||||||
import bums.lunatic.launcher.model.RssDataType
|
|
||||||
import bums.lunatic.launcher.model.TelegramBotUpdate
|
import bums.lunatic.launcher.model.TelegramBotUpdate
|
||||||
import bums.lunatic.launcher.model.TelegramChat
|
import bums.lunatic.launcher.model.TelegramChat
|
||||||
import bums.lunatic.launcher.model.TelegramData
|
import bums.lunatic.launcher.model.TelegramData
|
||||||
import bums.lunatic.launcher.model.TelegramFrom
|
import bums.lunatic.launcher.model.TelegramFrom
|
||||||
import bums.lunatic.launcher.model.TelegramMessage
|
import bums.lunatic.launcher.model.TelegramMessage
|
||||||
import bums.lunatic.launcher.model.UserActionModel
|
|
||||||
import bums.lunatic.launcher.model.WeatherForcast
|
import bums.lunatic.launcher.model.WeatherForcast
|
||||||
import bums.lunatic.launcher.utils.Blog
|
import bums.lunatic.launcher.utils.Blog
|
||||||
import bums.lunatic.launcher.utils.JamoUtils
|
import bums.lunatic.launcher.utils.JamoUtils
|
||||||
@ -63,11 +66,11 @@ object WorkersDb {
|
|||||||
// this.query<UserActionModel>().query("weekOfYear == $0 OR weekOfMonth == $1 OR dayOfWeek == $2").limit()
|
// this.query<UserActionModel>().query("weekOfYear == $0 OR weekOfMonth == $1 OR dayOfWeek == $2").limit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val clazz : Set<KClass<out BaseRealmObject>> = setOf(RssData::class, NotificationItem::class, AppInfo::class,SimpleContact::class, RecentCall::class, RecentSms::class, CurrentPlayItem::class,
|
val clazz : Set<KClass<out BaseRealmObject>> = setOf(RssData::class, NotificationItem::class, AppInfo::class,SimpleContact::class, RecentCall::class, RecentSms::class, CurrentPlayItem::class,
|
||||||
TelegramBotUpdate::class, TelegramData::class, TelegramMessage::class, TelegramChat::class, BotCommandEentitie::class, TelegramFrom::class,
|
TelegramBotUpdate::class, TelegramData::class, TelegramMessage::class, TelegramChat::class, BotCommandEentitie::class, TelegramFrom::class,
|
||||||
WeatherForcast::class, Location::class, Current::class, Forecast::class, Condition::class, Forecastday::class, Day::class, Astro::class, Hour::class,
|
WeatherForcast::class, Location::class, Current::class, Forecast::class, Condition::class, Forecastday::class, Day::class, Astro::class, Hour::class,
|
||||||
LocationLog::class
|
LocationLog::class,
|
||||||
|
LastInfo::class, HistoryItem::class, ReaderConfig::class, BookPageInfos::class, BookPageInfo::class
|
||||||
)
|
)
|
||||||
//,UserActionModel::class
|
//,UserActionModel::class
|
||||||
|
|
||||||
|
|||||||
5
app/src/main/res/color/tabs_black.xml
Normal file
5
app/src/main/res/color/tabs_black.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="@color/finestSilver" android:state_checked="true"></item>
|
||||||
|
<item android:color="@color/black" ></item>
|
||||||
|
</selector>
|
||||||
9
app/src/main/res/drawable/angle_left.xml
Normal file
9
app/src/main/res/drawable/angle_left.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="512dp"
|
||||||
|
android:height="512dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M17.921,1.505a1.5,1.5 0,0 1,-0.44 1.06L9.809,10.237a2.5,2.5 0,0 0,0 3.536l7.662,7.662a1.5,1.5 0,0 1,-2.121 2.121L7.688,15.9a5.506,5.506 0,0 1,0 -7.779L15.36,0.444a1.5,1.5 0,0 1,2.561 1.061Z"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/angle_right.xml
Normal file
9
app/src/main/res/drawable/angle_right.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="512dp"
|
||||||
|
android:height="512dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M6.079,22.5a1.5,1.5 0,0 1,0.44 -1.06l7.672,-7.672a2.5,2.5 0,0 0,0 -3.536L6.529,2.565A1.5,1.5 0,0 1,8.65 0.444l7.662,7.661a5.506,5.506 0,0 1,0 7.779L8.64,23.556A1.5,1.5 0,0 1,6.079 22.5Z"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/bookmark.xml
Normal file
9
app/src/main/res/drawable/bookmark.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="512dp"
|
||||||
|
android:height="512dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M2.849,23.55a2.954,2.954 0,0 0,3.266 -0.644L12,17.053l5.885,5.853a2.956,2.956 0,0 0,2.1 0.881,3.05 3.05,0 0,0 1.17,-0.237A2.953,2.953 0,0 0,23 20.779V5a5.006,5.006 0,0 0,-5 -5H6A5.006,5.006 0,0 0,1 5V20.779A2.953,2.953 0,0 0,2.849 23.55Z"/>
|
||||||
|
</vector>
|
||||||
27
app/src/main/res/drawable/circle_progressbar.xml
Normal file
27
app/src/main/res/drawable/circle_progressbar.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:id="@android:id/background">
|
||||||
|
<shape
|
||||||
|
android:innerRadiusRatio="2.71"
|
||||||
|
android:thicknessRatio="7.6"
|
||||||
|
android:shape="ring"
|
||||||
|
android:useLevel="false"
|
||||||
|
android:type="sweep">
|
||||||
|
<solid android:color="#9E9E9E" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:id="@android:id/progress">
|
||||||
|
<rotate
|
||||||
|
android:fromDegrees="270"
|
||||||
|
android:toDegrees="270">
|
||||||
|
<shape
|
||||||
|
android:innerRadiusRatio="2.71"
|
||||||
|
android:thicknessRatio="7.6"
|
||||||
|
android:shape="ring"
|
||||||
|
android:angle="0"
|
||||||
|
android:type="sweep">
|
||||||
|
</shape>
|
||||||
|
</rotate>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
||||||
BIN
app/src/main/res/drawable/history.png
Normal file
BIN
app/src/main/res/drawable/history.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
15
app/src/main/res/drawable/home.xml
Normal file
15
app/src/main/res/drawable/home.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="512dp"
|
||||||
|
android:height="512dp"
|
||||||
|
android:viewportWidth="512"
|
||||||
|
android:viewportHeight="512">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M256,319.84c-35.35,0 -64,28.65 -64,64v128h128v-128C320,348.49 291.35,319.84 256,319.84z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M362.67,383.84v128H448c35.35,0 64,-28.65 64,-64V253.26c0,-11.08 -4.3,-21.73 -12.01,-29.7l-181.29,-195.99c-31.99,-34.61 -85.98,-36.74 -120.59,-4.75c-1.64,1.52 -3.23,3.1 -4.75,4.75L12.4,223.5C4.45,231.5 -0,242.31 0,253.58v194.26c0,35.35 28.65,64 64,64h85.33v-128c0.4,-58.17 47.37,-105.68 104.07,-107.04C312.01,275.38 362.22,323.7 362.67,383.84z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M256,319.84c-35.35,0 -64,28.65 -64,64v128h128v-128C320,348.49 291.35,319.84 256,319.84z"/>
|
||||||
|
</vector>
|
||||||
BIN
app/src/main/res/drawable/invoice.png
Normal file
BIN
app/src/main/res/drawable/invoice.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
BIN
app/src/main/res/drawable/rotation.png
Normal file
BIN
app/src/main/res/drawable/rotation.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
15
app/src/main/res/drawable/saved.xml
Normal file
15
app/src/main/res/drawable/saved.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="512dp"
|
||||||
|
android:height="512dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M22.713,4.077A2.993,2.993 0,0 0,20.41 3H4.242L4.2,2.649A3,3 0,0 0,1.222 0H1A1,1 0,0 0,1 2h0.222a1,1 0,0 1,0.993 0.883l1.376,11.7A5,5 0,0 0,8.557 19H19a1,1 0,0 0,0 -2H8.557a3,3 0,0 1,-2.82 -2h11.92a5,5 0,0 0,4.921 -4.113l0.785,-4.354A2.994,2.994 0,0 0,22.713 4.077Z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M7,22m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M17,22m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/settings.xml
Normal file
9
app/src/main/res/drawable/settings.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="512dp"
|
||||||
|
android:height="512dp"
|
||||||
|
android:viewportWidth="512"
|
||||||
|
android:viewportHeight="512">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M34.28,384c17.65,30.63 56.78,41.15 87.4,23.5c0.02,-0.01 0.04,-0.02 0.06,-0.04l9.49,-5.48c17.92,15.33 38.52,27.22 60.76,35.07V448c0,35.35 28.65,64 64,64s64,-28.65 64,-64v-10.94c22.24,-7.86 42.84,-19.77 60.76,-35.12l9.54,5.5c30.63,17.67 69.79,7.17 87.47,-23.47c17.67,-30.63 7.17,-69.79 -23.47,-87.47l0,0l-9.47,-5.46c4.26,-23.2 4.26,-46.99 0,-70.19l9.47,-5.46c30.63,-17.67 41.14,-56.83 23.47,-87.47c-17.67,-30.63 -56.83,-41.14 -87.47,-23.47l-9.49,5.48C362.86,94.64 342.25,82.77 320,74.94V64c0,-35.35 -28.65,-64 -64,-64s-64,28.65 -64,64v10.94c-22.24,7.86 -42.84,19.77 -60.76,35.12l-9.54,-5.53C91.07,86.86 51.91,97.37 34.24,128s-7.17,69.79 23.47,87.47l0,0l9.47,5.46c-4.26,23.2 -4.26,46.99 0,70.19l-9.47,5.46C27.16,314.3 16.69,353.38 34.28,384zM256,170.67c47.13,0 85.33,38.21 85.33,85.33S303.13,341.33 256,341.33S170.67,303.13 170.67,256S208.87,170.67 256,170.67z"/>
|
||||||
|
</vector>
|
||||||
6
app/src/main/res/drawable/simple_bg.xml
Normal file
6
app/src/main/res/drawable/simple_bg.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
||||||
|
<corners android:radius="10dp"/>
|
||||||
|
<solid android:color="#44ffffff"/>
|
||||||
|
<stroke android:color="@color/white" android:width="1dp"/>
|
||||||
|
</shape>
|
||||||
BIN
app/src/main/res/font/cafe24oneprettynight.ttf
Normal file
BIN
app/src/main/res/font/cafe24oneprettynight.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/dovemayo.otf
Normal file
BIN
app/src/main/res/font/dovemayo.otf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/ebs_r.ttf
Normal file
BIN
app/src/main/res/font/ebs_r.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/gabia_solmee.ttf
Normal file
BIN
app/src/main/res/font/gabia_solmee.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/godomaum.ttf
Normal file
BIN
app/src/main/res/font/godomaum.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/jsarirang_hon.otf
Normal file
BIN
app/src/main/res/font/jsarirang_hon.otf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/jsarirang_ppuri.otf
Normal file
BIN
app/src/main/res/font/jsarirang_ppuri.otf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/jsdongkang_regular.otf
Normal file
BIN
app/src/main/res/font/jsdongkang_regular.otf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/kcc_kimhoon.ttf
Normal file
BIN
app/src/main/res/font/kcc_kimhoon.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/kcc_sonkeechung.otf
Normal file
BIN
app/src/main/res/font/kcc_sonkeechung.otf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/kccahnjunggeun.ttf
Normal file
BIN
app/src/main/res/font/kccahnjunggeun.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/kotra_bold.ttf
Normal file
BIN
app/src/main/res/font/kotra_bold.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/kotra_songeulssi.ttf
Normal file
BIN
app/src/main/res/font/kotra_songeulssi.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/kyobo_handwriting_2021sjy.otf
Normal file
BIN
app/src/main/res/font/kyobo_handwriting_2021sjy.otf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/mapoagape.ttf
Normal file
BIN
app/src/main/res/font/mapoagape.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/mapobackpacking.ttf
Normal file
BIN
app/src/main/res/font/mapobackpacking.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/mapodacapo.ttf
Normal file
BIN
app/src/main/res/font/mapodacapo.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/mapodpp.ttf
Normal file
BIN
app/src/main/res/font/mapodpp.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/mapodpp_2.ttf
Normal file
BIN
app/src/main/res/font/mapodpp_2.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/mapoflowerisland.ttf
Normal file
BIN
app/src/main/res/font/mapoflowerisland.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/mapogoldenpier.ttf
Normal file
BIN
app/src/main/res/font/mapogoldenpier.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/mapomaponaru.ttf
Normal file
BIN
app/src/main/res/font/mapomaponaru.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/mapopeacefull.ttf
Normal file
BIN
app/src/main/res/font/mapopeacefull.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/nnsgc_brhp.ttf
Normal file
BIN
app/src/main/res/font/nnsgc_brhp.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/nnsgc_gd_an_gd.ttf
Normal file
BIN
app/src/main/res/font/nnsgc_gd_an_gd.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/nnsgc_md.ttf
Normal file
BIN
app/src/main/res/font/nnsgc_md.ttf
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user