diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b66effb4..7806479c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -14,7 +14,6 @@ android { defaultConfig { applicationId = "bums.lunatic.launcher" minSdk = 26 - targetSdk = 34 versionCode = 38 versionName = "2.8.2" multiDexEnabled = true diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0ed8988b..5e876b31 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -109,20 +109,14 @@ - - - - - + - - - + -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(); \ No newline at end of file diff --git a/app/src/main/assets/extensions/my_extension/manifest.json b/app/src/main/assets/extensions/my_extension/manifest.json new file mode 100644 index 00000000..bce7f3a4 --- /dev/null +++ b/app/src/main/assets/extensions/my_extension/manifest.json @@ -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": [""], + "js": ["messaging.js"] + } + ], + "permissions": [ + "nativeMessaging", + "nativeMessagingFromContent", + "geckoViewAddons", + "webRequest", + "webRequestBlocking", + "*://*/*.gif" + ] +} diff --git a/app/src/main/assets/extensions/my_extension/messaging.js b/app/src/main/assets/extensions/my_extension/messaging.js new file mode 100644 index 00000000..e4ad54dc --- /dev/null +++ b/app/src/main/assets/extensions/my_extension/messaging.js @@ -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() { + +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/LauncherActivity.kt b/app/src/main/kotlin/bums/lunatic/launcher/LauncherActivity.kt index 1270ccce..70a59af0 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/LauncherActivity.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/LauncherActivity.kt @@ -20,17 +20,12 @@ package bums.lunatic.launcher //import rasel.lunar.launcher.home.LauncherHome.Companion.rssSet -import android.Manifest - import android.annotation.SuppressLint import android.app.NotificationManager import android.appwidget.AppWidgetManager -import android.content.BroadcastReceiver import android.content.ComponentName -import android.content.Context import android.content.Intent import android.content.SharedPreferences -import android.content.pm.PackageManager import android.content.res.Configuration import android.graphics.Color import android.net.Uri @@ -40,8 +35,6 @@ import android.os.Environment.isExternalStorageManager import android.os.Handler import android.os.Looper import android.provider.Settings -import android.support.v4.media.MediaBrowserCompat -import android.telephony.TelephonyManager import android.view.KeyEvent import android.view.KeyEvent.ACTION_UP 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_Y 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.MotionEvent import android.view.View @@ -67,6 +58,7 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.ViewCompat import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat +import androidx.core.view.isVisible import androidx.core.view.updatePadding import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.OneTimeWorkRequest @@ -74,27 +66,26 @@ import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkManager import bums.lunatic.launcher.LauncherActivity.Companion.lActivity import bums.lunatic.launcher.apps.AppDrawer +import bums.lunatic.launcher.tokiz.Novels import bums.lunatic.launcher.common.CommonActivity import bums.lunatic.launcher.databinding.LauncherActivityBinding import bums.lunatic.launcher.feeds.WidgetHost import bums.lunatic.launcher.helpers.BluetoothManager 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.PREFS_FIRST_LAUNCH import bums.lunatic.launcher.helpers.Constants.Companion.PREFS_SETTINGS import bums.lunatic.launcher.helpers.Constants.Companion.widgetHostId import bums.lunatic.launcher.helpers.HeadsetActionButtonReceiver import bums.lunatic.launcher.helpers.PrefLong import bums.lunatic.launcher.home.LauncherHome 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.RssDataType import bums.lunatic.launcher.receiver.NLService import bums.lunatic.launcher.utils.Blog import bums.lunatic.launcher.utils.FeedParseManager import bums.lunatic.launcher.utils.getJ +import bums.lunatic.launcher.view.TableRadioGroup import bums.lunatic.launcher.workers.AppInfoGetter import bums.lunatic.launcher.workers.ArcaGetter 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.Companion.YT_WORK_TAG import com.google.android.material.color.DynamicColors -import com.google.android.material.dialog.MaterialAlertDialogBuilder import io.realm.kotlin.ext.query -import io.realm.kotlin.query.Sort import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch 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.Calendar import java.util.Date -import java.util.Locale import java.util.concurrent.Executors import java.util.concurrent.TimeUnit @@ -143,6 +135,12 @@ internal class LauncherActivity : CommonActivity() { // lateinit var viewPager: ViewPager2 companion object { + private var sRuntime: GeckoRuntime? = null + fun getRuntime() : GeckoRuntime? { + lActivity?.initGeckoRuntime() + return sRuntime + } + private var mWorkManager: WorkManager? = null var isOpendFold = false val qDayPeriod = 60L * 8L @@ -179,11 +177,11 @@ internal class LauncherActivity : CommonActivity() { } - fun runWeatherGetter() { - Executors.newSingleThreadScheduledExecutor().schedule({ - mWorkManager?.enqueue(OneTimeWorkRequest.from(OpenWeatherGetter::class.java)) - }, 200L, TimeUnit.MILLISECONDS) - } +// fun runWeatherGetter() { +// Executors.newSingleThreadScheduledExecutor().schedule({ +// mWorkManager?.enqueue(OneTimeWorkRequest.from(OpenWeatherGetter::class.java)) +// }, 200L, TimeUnit.MILLISECONDS) +// } fun getCal() { Executors.newSingleThreadScheduledExecutor().schedule({ @@ -276,6 +274,7 @@ internal class LauncherActivity : CommonActivity() { } + @SuppressLint("MissingSuperCall") override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) @@ -284,13 +283,30 @@ internal class LauncherActivity : CommonActivity() { Blog.LOGE("onConfigurationChanged newConfig?.screenWidthDp >> ${newConfig?.screenWidthDp}") Blog.LOGE("onConfigurationChanged newConfig?.screenHeightDp >> ${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 actionButtonPressY = 0f var onExit = false var lastAction = MotionEvent.ACTION_HOVER_EXIT override fun dispatchKeyEvent(ev: KeyEvent): Boolean { - Blog.LOGE("dispatch ev?.device?.name >>> ${ev?.device?.name}") if (ev?.device?.name?.contains("SM-031N Mouse") == true) { @@ -366,6 +382,25 @@ internal class LauncherActivity : CommonActivity() { } 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) } @@ -541,31 +576,68 @@ internal class LauncherActivity : CommonActivity() { // } super.onNewIntent(intent) } - lateinit var home : LauncherHome + var home : LauncherHome? = null + var novels : Novels? = null @SuppressLint("NewApi", "MissingPermission") override fun onCreate(savedInstanceState: Bundle?) { installSplashScreen() - + lActivity = this mWorkManager = WorkManager.getInstance(this) DynamicColors.applyToActivityIfAvailable(this) - lActivity = this + 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) - WindowCompat.setDecorFitsSystemWindows(window, false) + binding = LauncherActivityBinding.inflate(layoutInflater) setContentView(binding.root) appWidgetManager = AppWidgetManager.getInstance(applicationContext) appWidgetHost = WidgetHost(applicationContext, widgetHostId) appWidgetHost?.startListening() HeadsetActionButtonReceiver.register(this) -// MediaBrowserCompat.ConnectionCallback - /* if this is the first launch, - then remember the event and show the welcome dialog */ - home = binding.home.getFragment() + + binding.tabs.setOnCheckedChangeListener { g, id -> + when(id) { + R.id.feeds -> { + if(binding.feeds.isChecked) { + if (home == null) { + home = binding.home.getFragment() + } + binding.home.visibility = View.VISIBLE + binding.booktoki.visibility = View.GONE + } else { + binding.home.visibility = View.GONE + if (novels == null) { + novels = binding.booktoki.getFragment() + + } 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() + } else { + novels?.onResume() + } + binding.booktoki.visibility = View.VISIBLE + } else { + if (home == null) { + home = binding.home.getFragment() + } + binding.home.visibility = View.VISIBLE + binding.booktoki.visibility = View.GONE + } + } + else -> {} + } + } /* handle navigation back events */ handleBackPress() @@ -592,13 +664,38 @@ internal class LauncherActivity : CommonActivity() { } } 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() { - super.onDestroy() + + appWidgetHost?.stopListening() + try { + sRuntime?.shutdown() + sRuntime = null + } catch (e: Exception) {e.printStackTrace() + } + + super.onDestroy() } var blutoothManager : BluetoothManager? = null override fun onStart() { @@ -608,132 +705,19 @@ internal class LauncherActivity : CommonActivity() { blutoothManager?.initBluetoothAdapter() blutoothManager?.blueToothState() blutoothManager?.getPairedDevices() - Blog.LOGE("LauncherActivity onStart()") statusBarView() setBgColor() - welcomeDialog() } @RequiresApi(Build.VERSION_CODES.O_MR1) override fun onResume() { super.onResume() - + refreshFeeds() blutoothManager?.getPairedDevices() 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() } @@ -776,14 +760,10 @@ internal class LauncherActivity : CommonActivity() { private fun handleBackPress() { onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { - -// if (binding.feeds.visibility == View.VISIBLE) { -// switchFeeds() -// } else - if (binding.appDrawer.visibility == View.VISIBLE) { - switchAppDrawer() - } else if (binding.home.visibility == View.VISIBLE) { -// switchAppDrawer() + if (binding.booktoki.isVisible) { + finish() + } else { + finish() } } }) @@ -804,313 +784,33 @@ internal class LauncherActivity : CommonActivity() { } + val experimentDelegate = object : ExperimentDelegate { + override fun onGetExperimentFeature(feature: String): GeckoResult { + Blog.LOGE("onGetExperimentFeature $feature") + return super.onGetExperimentFeature(feature) + } - class EndCallReceiver : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - Blog.LOGE("EndCallReceiver >>> ${intent}") - val phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE) ?: return - if (phoneState == TelephonyManager.EXTRA_STATE_IDLE) { - refreshDeviceData() - } + override fun onRecordExposureEvent(feature: String): GeckoResult { + Blog.LOGE("onRecordExposureEvent $feature") + return super.onRecordExposureEvent(feature) + } + + override fun onRecordExperimentExposureEvent( + feature: String, + slug: String + ): GeckoResult { + Blog.LOGE("onRecordExperimentExposureEvent $feature , $slug") + return super.onRecordExperimentExposureEvent(feature, slug) + } + + override fun onRecordMalformedConfigurationEvent( + feature: String, + part: String + ): GeckoResult { + 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() -// 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() -// 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("",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("",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() -// 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()) } @@ -1127,18 +827,6 @@ fun beforeDay(date: Date): Long { 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){ val browserIntent = Intent( Intent.ACTION_VIEW, Uri.parse( @@ -1146,11 +834,9 @@ fun openClient(url : String){ ) ) 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) } + fun openYouTube(schemeString : String) { val gmmIntentUri = Uri.parse(schemeString) val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri) diff --git a/app/src/main/kotlin/bums/lunatic/launcher/LunaticLauncher.kt b/app/src/main/kotlin/bums/lunatic/launcher/LunaticLauncher.kt index 41ea9472..3a99a1d7 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/LunaticLauncher.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/LunaticLauncher.kt @@ -23,12 +23,19 @@ import android.content.ComponentCallbacks2 import android.content.Context import android.database.sqlite.SQLiteDatabase import bums.lunatic.launcher.helpers.PrefHelper +import bums.lunatic.launcher.utils.Blog 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() { companion object { - var appContext : Context? = null + var appContext : LunaticLauncher? = null + } override fun onCreate() { @@ -37,6 +44,8 @@ internal class LunaticLauncher : Application() { Base.initialize(this) PrefHelper.initialize(this) } + + override fun onTrimMemory(level: Int) { super.onTrimMemory(level) // Picasso. diff --git a/app/src/main/kotlin/bums/lunatic/launcher/apps/AppDrawer.kt b/app/src/main/kotlin/bums/lunatic/launcher/apps/AppDrawer.kt index 78b72ead..59ec2480 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/apps/AppDrawer.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/apps/AppDrawer.kt @@ -21,9 +21,7 @@ package bums.lunatic.launcher.apps import android.content.Context import android.content.Intent import android.content.SharedPreferences -import android.content.pm.ApplicationInfo import android.content.pm.PackageManager -import android.content.pm.ResolveInfo import android.net.Uri import android.os.Bundle import android.os.Handler @@ -35,7 +33,6 @@ import android.view.inputmethod.InputMethodManager import androidx.core.widget.doOnTextChanged import androidx.recyclerview.widget.GridLayoutManager import bums.lunatic.launcher.BuildConfig -import bums.lunatic.launcher.LauncherActivity import bums.lunatic.launcher.LauncherActivity.Companion.lActivity import bums.lunatic.launcher.common.CommonActivity 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.Sort import java.net.URLEncoder -import java.text.Normalizer import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import java.util.regex.Pattern diff --git a/app/src/main/kotlin/bums/lunatic/launcher/behavior/Behavior.kt b/app/src/main/kotlin/bums/lunatic/launcher/behavior/Behavior.kt index 37097f3b..15c394cd 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/behavior/Behavior.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/behavior/Behavior.kt @@ -1,9 +1,7 @@ package bums.lunatic.launcher.behavior -import android.content.Intent import android.graphics.Color import android.os.Bundle -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -13,12 +11,9 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.view.WindowCompat import androidx.recyclerview.widget.RecyclerView import bums.lunatic.launcher.R -import bums.lunatic.launcher.behavior.calendar.CalendarAdapter 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.CalendarUtil -import bums.lunatic.launcher.behavior.calendar.CalendarView import bums.lunatic.launcher.databinding.ItemCalendarBinding import com.google.android.material.appbar.AppBarLayout import java.util.Date diff --git a/app/src/main/kotlin/bums/lunatic/launcher/behavior/behaviorimpl/BehaviorRecT.kt b/app/src/main/kotlin/bums/lunatic/launcher/behavior/behaviorimpl/BehaviorRecT.kt index 9dfd8187..081c70e8 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/behavior/behaviorimpl/BehaviorRecT.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/behavior/behaviorimpl/BehaviorRecT.kt @@ -5,7 +5,6 @@ import android.util.AttributeSet import android.util.DisplayMetrics import android.util.TypedValue import android.view.View -import android.widget.TextView import androidx.annotation.NonNull import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.recyclerview.widget.RecyclerView diff --git a/app/src/main/kotlin/bums/lunatic/launcher/common/CommonActivity.kt b/app/src/main/kotlin/bums/lunatic/launcher/common/CommonActivity.kt index acb60ea7..eb09b956 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/common/CommonActivity.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/common/CommonActivity.kt @@ -3,19 +3,12 @@ package bums.lunatic.launcher.common import android.content.Intent import android.os.Environment 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.helpers.PrefBoolean -import bums.lunatic.launcher.helpers.PrefHelper import bums.lunatic.launcher.utils.Blog import bums.lunatic.launcher.workers.LocationUpdateService -import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.gson.Gson -import com.google.gson.JsonArray import com.google.gson.reflect.TypeToken -import org.json.JSONArray -import org.json.JSONObject import java.io.BufferedReader import java.io.File import java.io.FileInputStream @@ -26,7 +19,6 @@ import java.io.InputStream import java.io.InputStreamReader import java.io.OutputStreamWriter import java.util.Base64 -import kotlin.system.exitProcess abstract class CommonActivity : AppCompatActivity() { diff --git a/app/src/main/kotlin/bums/lunatic/launcher/helpers/HeadsetActionButtonReceiver.kt b/app/src/main/kotlin/bums/lunatic/launcher/helpers/HeadsetActionButtonReceiver.kt index 461f2418..f75a758c 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/helpers/HeadsetActionButtonReceiver.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/helpers/HeadsetActionButtonReceiver.kt @@ -8,7 +8,6 @@ import android.media.AudioManager import android.view.KeyEvent import bums.lunatic.launcher.utils.Blog import java.util.Timer -import java.util.TimerTask class HeadsetActionButtonReceiver : BroadcastReceiver() { diff --git a/app/src/main/kotlin/bums/lunatic/launcher/helpers/PrefHelper.kt b/app/src/main/kotlin/bums/lunatic/launcher/helpers/PrefHelper.kt index 1eb63ccf..ecd98da5 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/helpers/PrefHelper.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/helpers/PrefHelper.kt @@ -1,9 +1,6 @@ package bums.lunatic.launcher.helpers -import android.content.SharedPreferences 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.PreferencesHelper import java.math.BigDecimal diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt index 81c53d8c..d5758390 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt @@ -16,8 +16,12 @@ import android.view.KeyEvent.KEYCODE_BUTTON_X import android.view.KeyEvent.KEYCODE_BUTTON_Y import android.view.KeyEvent.KEYCODE_DPAD_DOWN 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 com.google.gson.Gson +import org.json.JSONException import org.json.JSONObject import org.mozilla.gecko.util.ThreadUtils 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.WebRequestError -class GeckoWeb : GeckoView { +class GeckoWeb : BWebview { constructor(context: Context?) : super(context) { - initWithContext(context) + buildWeb() } + + + constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) { - initWithContext(context) + buildWeb() } - fun loadUrl(url: String) { - Blog.LOGE("url >>>> ${url}") - if (url.split("//").size > 1) { - url.replace("//","/").replace("https:/","https://").let { - Blog.LOGE("url >> ${url} , it >>> ${it}") - this.session?.loadUri(url) - } - } else { - this.session?.loadUri(url) - } - - currentRetryCount = 0; - } - val handle = object : Handler(Looper.getMainLooper()) { - override fun handleMessage(msg: Message) { - if (msg.what == 0) { - (msg.obj as? ReaderConfig)?.let { - } - } + val mPortNam = "browser" + val extPath = "resource://android/assets/extensions/my_extension/" + val extId = "messaging@booktoki468.com" + private fun buildWeb() { + getRuntime()?.let { + val session: GeckoSession = GeckoSession() + session.open(it) + this.setSession(session) + session.contentDelegate = contentDelegate + session.progressDelegate = progressDelegate + session.navigationDelegate = navigationDelegate + it.webExtensionController.setAddonManagerDelegate(addonManagerDelegate) + session.mediaDelegate = mediaDelegate + session.mediaSessionDelegate = mediaSessionDelegate + it.webExtensionController + .ensureBuiltIn(extPath, extId) + .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 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 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 { override fun onRecordingStatusChanged( session: GeckoSession, @@ -203,21 +207,6 @@ class GeckoWeb : GeckoView { 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 { override fun onGetExperimentFeature(feature: String): GeckoResult { @@ -261,12 +250,11 @@ class GeckoWeb : GeckoView { } override fun onPaintStatusReset(session: GeckoSession) { - Blog.LOGE("onPaintStatusReset") super.onPaintStatusReset(session) } override fun onFirstContentfulPaint(session: GeckoSession) { - Blog.LOGE("onFirstContentfulPaint") + super.onFirstContentfulPaint(session) } } @@ -410,13 +398,6 @@ class GeckoWeb : GeckoView { } - - fun onDestroy() { - sRuntime = null - } - - - override fun dispatchKeyEvent(ev: KeyEvent): Boolean { Blog.LOGE("dispatch ev?.device?.name >>> ${ev?.device?.name}") if (ev?.device?.name?.contains("SM-031N Mouse") == true) { @@ -467,7 +448,6 @@ class GeckoWeb : GeckoView { companion object { private const val TAG = "DualScreenStatus" - var sRuntime: GeckoRuntime? = null var currentRetryCount = 0 } } \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/LauncherHome.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/LauncherHome.kt index d34dc06c..07385aa9 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/LauncherHome.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/LauncherHome.kt @@ -19,107 +19,53 @@ package bums.lunatic.launcher.home 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.pm.PackageManager -import android.media.AudioManager -import android.net.Uri +import android.os.Build import android.os.Bundle import android.os.Handler 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.View 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 androidx.annotation.NonNull -import androidx.appcompat.app.AlertDialog -import androidx.biometric.BiometricPrompt -import androidx.core.view.children +import androidx.annotation.RequiresApi import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView -import androidx.viewpager2.widget.ViewPager2 import bums.lunatic.launcher.LauncherActivity.Companion.lActivity 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.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.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.SmsLogsAdapter +import bums.lunatic.launcher.home.adapters.RssItemAdapter.Companion.rssList 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.RssDataInterface import bums.lunatic.launcher.model.RssDataType import bums.lunatic.launcher.model.WeatherForcast -import bums.lunatic.launcher.model.WeatherInfoManager -import bums.lunatic.launcher.qaccess.QuickAccess -import bums.lunatic.launcher.settings.SettingsActivity +import bums.lunatic.launcher.openClient +import bums.lunatic.launcher.openReddit +import bums.lunatic.launcher.openYouTube +import bums.lunatic.launcher.tokiz.view.JxEvent import bums.lunatic.launcher.utils.Blog -import bums.lunatic.launcher.utils.BitmapConverter import bums.lunatic.launcher.utils.SimpleFingerGestures -import bums.lunatic.launcher.utils.USAGT import bums.lunatic.launcher.utils.beforeDay 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.latitudeRange -import bums.lunatic.launcher.workers.longitudeRange +import com.google.android.material.imageview.ShapeableImageView import io.realm.kotlin.UpdatePolicy import io.realm.kotlin.ext.query -import io.realm.kotlin.notifications.InitialResults import io.realm.kotlin.notifications.ResultsChange -import io.realm.kotlin.notifications.UpdatedResults import io.realm.kotlin.query.RealmQuery import io.realm.kotlin.query.RealmResults import io.realm.kotlin.query.Sort import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.cancellable -import kotlinx.coroutines.flow.collect 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() { @@ -143,15 +89,164 @@ internal class LauncherHome : Fragment() { fun rssStateVote() = (lasted?.filter { it.vote == true }?.size ?: -1) == (lasted?.size ?: 0) var lasted: List? = null var infosJob: Job? = null + var rssId = "" lateinit var mRssAdapter: RssItemAdapter var mRssDataResult: RealmResults? = 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?) { super.onCreate(savedInstanceState) home = this } + var targetList = arrayListOf() + 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(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() + setString.addAll(rssList) + setString.removeAll { it.equals(rssId) } + + targetList.addAll(setString) + binding.geckoWeb.loadUrl(rssId) + } + + @SuppressLint("ClickableViewAccessibility") override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -160,15 +255,75 @@ internal class LauncherHome : Fragment() { binding = LauncherHomeBinding.inflate(inflater, container, false) fragManager = lActivity!!.supportFragmentManager settingsPrefs = requireContext().getSharedPreferences(PREFS_SETTINGS, 0) - mRssAdapter = RssItemAdapter(requireContext()) + mRssAdapter = RssItemAdapter(requireContext(),dateViewClick) val decoration = DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL) binding.infoList.addItemDecoration(decoration) binding.infoList.visibility = View.VISIBLE 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() + 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 } + fun vote(){ + Blog.LOGE("Arrow Center Click") + WorkersDb.getRealm().apply { + writeBlocking { + val result = query().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().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?) { try { job?.cancel() } catch (e: Exception) { e.printStackTrace() } try { System.gc() } catch (e: Exception) { e.printStackTrace() } @@ -258,6 +413,7 @@ internal class LauncherHome : Fragment() { private fun enableSwipeToDeleteAndUndo() { val swipeToDeleteCallback: SwipeToDeleteCallback = object : SwipeToDeleteCallback(requireContext()) { + override fun onSwiped(@NonNull viewHolder: RecyclerView.ViewHolder, direction: Int) { Blog.LOGE("onSwiped direction >>>> $direction") (viewHolder.itemView.tag as? RssData)?.let { rss -> @@ -290,7 +446,9 @@ internal class LauncherHome : Fragment() { } } - else -> {} + else -> { + + } } binding.infoList.post { mRssAdapter.refresh() } } diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/LauncherHome_old.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/LauncherHome_old.kt index 52532362..8b7cecef 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/LauncherHome_old.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/LauncherHome_old.kt @@ -1,1328 +1,1321 @@ -/* - * Lunar Launcher - * Copyright (C) 2022 Md Rasel Hossain - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package bums.lunatic.launcher.home - -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.pm.PackageManager -import android.media.AudioManager -import android.net.Uri -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.os.SystemClock -import android.provider.AlarmClock -import android.provider.Settings -import android.view.HapticFeedbackConstants -import android.view.KeyEvent -import android.view.LayoutInflater -import android.view.View -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 androidx.annotation.NonNull -import androidx.appcompat.app.AlertDialog -import androidx.biometric.BiometricPrompt -import androidx.core.view.children -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentManager -import androidx.recyclerview.widget.DividerItemDecoration -import androidx.recyclerview.widget.ItemTouchHelper -import androidx.recyclerview.widget.RecyclerView -import androidx.viewpager2.widget.ViewPager2 -import bums.lunatic.launcher.LauncherActivity.Companion.lActivity -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.databinding.LauncherHomeBinding -import bums.lunatic.launcher.databinding.LauncherHomeOldBinding -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.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.SmsLogsAdapter -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.RssDataInterface -import bums.lunatic.launcher.model.RssDataType -import bums.lunatic.launcher.model.WeatherForcast -import bums.lunatic.launcher.model.WeatherInfoManager -import bums.lunatic.launcher.qaccess.QuickAccess -import bums.lunatic.launcher.settings.SettingsActivity -import bums.lunatic.launcher.utils.Blog -import bums.lunatic.launcher.utils.BitmapConverter -import bums.lunatic.launcher.utils.SimpleFingerGestures -import bums.lunatic.launcher.utils.USAGT -import bums.lunatic.launcher.utils.beforeDay -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.latitudeRange -import bums.lunatic.launcher.workers.longitudeRange -import io.realm.kotlin.UpdatePolicy -import io.realm.kotlin.ext.query -import io.realm.kotlin.notifications.InitialResults -import io.realm.kotlin.notifications.ResultsChange -import io.realm.kotlin.notifications.UpdatedResults -import io.realm.kotlin.query.RealmQuery -import io.realm.kotlin.query.RealmResults -import io.realm.kotlin.query.Sort -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.cancellable -import kotlinx.coroutines.flow.collect -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_old : Fragment() { - - lateinit var binding: LauncherHomeOldBinding - private lateinit var fragManager: FragmentManager - private lateinit var settingsPrefs: SharedPreferences - private lateinit var batteryReceiver: BatteryReceiver - private var shouldResume = true - - companion object { - var home: LauncherHome_old? = null - var lastedFinishedPageUrl: String = "" - var listTags = arrayListOf() - } - - val UPDATE_DELAY = 5L - val commandHandler = Handler(Looper.getMainLooper()) - - val infoUpdate = Runnable { chooseAdpater() } - val notiUpdate = Runnable { chooseAdpater() } - - var weatherJob: Job? = null - var result: RealmResults? = null - val hideListViewTime = 1000L * 60L * 15L - val hideListView = { -// binding.notiList.visibility = View.GONE -// binding.mainList.visibility = View.GONE -// binding.infoList.visibility = View.GONE +///* +// * Lunar Launcher +// * Copyright (C) 2022 Md Rasel Hossain +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see . +// */ +// +//package bums.lunatic.launcher.home +// +//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.pm.PackageManager +//import android.media.AudioManager +//import android.net.Uri +//import android.os.Bundle +//import android.os.Handler +//import android.os.Looper +//import android.os.SystemClock +//import android.provider.AlarmClock +//import android.provider.Settings +//import android.view.HapticFeedbackConstants +//import android.view.KeyEvent +//import android.view.LayoutInflater +//import android.view.View +//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 androidx.annotation.NonNull +//import androidx.appcompat.app.AlertDialog +//import androidx.biometric.BiometricPrompt +//import androidx.core.view.children +//import androidx.fragment.app.Fragment +//import androidx.fragment.app.FragmentManager +//import androidx.recyclerview.widget.DividerItemDecoration +//import androidx.recyclerview.widget.ItemTouchHelper +//import androidx.recyclerview.widget.RecyclerView +//import androidx.viewpager2.widget.ViewPager2 +//import bums.lunatic.launcher.LauncherActivity.Companion.lActivity +//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.databinding.LauncherHomeOldBinding +//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.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.SmsLogsAdapter +//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.RssDataInterface +//import bums.lunatic.launcher.model.RssDataType +//import bums.lunatic.launcher.model.WeatherForcast +//import bums.lunatic.launcher.model.WeatherInfoManager +//import bums.lunatic.launcher.qaccess.QuickAccess +//import bums.lunatic.launcher.settings.SettingsActivity +//import bums.lunatic.launcher.utils.BitmapConverter +//import bums.lunatic.launcher.utils.Blog +//import bums.lunatic.launcher.utils.SimpleFingerGestures +//import bums.lunatic.launcher.utils.USAGT +//import bums.lunatic.launcher.utils.beforeDay +//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.latitudeRange +//import bums.lunatic.launcher.workers.longitudeRange +//import io.realm.kotlin.ext.query +//import io.realm.kotlin.notifications.ResultsChange +//import io.realm.kotlin.notifications.UpdatedResults +//import io.realm.kotlin.query.RealmQuery +//import io.realm.kotlin.query.RealmResults +//import io.realm.kotlin.query.Sort +//import kotlinx.coroutines.CoroutineScope +//import kotlinx.coroutines.Dispatchers +//import kotlinx.coroutines.Job +//import kotlinx.coroutines.launch +//import org.json.JSONArray +//import org.json.JSONObject +//import java.math.BigDecimal +//import java.math.RoundingMode +//import java.net.URLEncoder +//import java.util.Calendar +// +// +//internal class LauncherHome_old : Fragment() { +// +// lateinit var binding: LauncherHomeOldBinding +// private lateinit var fragManager: FragmentManager +// private lateinit var settingsPrefs: SharedPreferences +// private lateinit var batteryReceiver: BatteryReceiver +// private var shouldResume = true +// +// companion object { +// var home: LauncherHome_old? = null +// var lastedFinishedPageUrl: String = "" +// var listTags = arrayListOf() +// } +// +// val UPDATE_DELAY = 5L +// val commandHandler = Handler(Looper.getMainLooper()) +// +// val infoUpdate = Runnable { chooseAdpater() } +// val notiUpdate = Runnable { chooseAdpater() } +// +// var weatherJob: Job? = null +// var result: RealmResults? = null +// val hideListViewTime = 1000L * 60L * 15L +// val hideListView = { +//// binding.notiList.visibility = View.GONE +//// binding.mainList.visibility = View.GONE +//// binding.infoList.visibility = View.GONE +//// binding.smsList.visibility = View.GONE +//// binding.otherCheck.isSelected = false +//// binding.recentSms.isSelected = false +//// binding.missedCalls.isSelected = false +//// binding.notice.isSelected = false +// } +// +// val nomoreShowCount = 5 +// fun rssStateVote() = (lasted?.filter { it.vote == true }?.size ?: -1) == (lasted?.size ?: 0) +// +// var lasted: List? = null +// var lastedNoti: List? = null +// var infosJob: Job? = null +// var noticeJob: Job? = null +// +// lateinit var mRecentCallsAdapter: RecentCallsAdapter +// lateinit var mSmsLogsAdapter: SmsLogsAdapter +// lateinit var mRssAdapter: RssItemAdapter +// lateinit var mNotiAdapter: NotificationItemAdapter +// lateinit var mAppsAdapter: AppsAdapter +// var mWeatherAdapter: WeatherAdapter? = null +// var weatherDressAdapter: WeatherDressAdatper? = null +// var weatherHourlyAdapter: WeatherHourlyAdapter? = null +// var mRssDataResult: RealmResults? = null +// var mNotificationResult: RealmResults? = null +// +// override fun onCreate(savedInstanceState: Bundle?) { +// super.onCreate(savedInstanceState) +// home = this +// } +// +// var musicJob: Job? = null +// override fun onCreateView( +// inflater: LayoutInflater, +// container: ViewGroup?, +// savedInstanceState: Bundle? +// ): View { +// binding = LauncherHomeOldBinding.inflate(inflater, container, false) +// fragManager = lActivity!!.supportFragmentManager +// settingsPrefs = requireContext().getSharedPreferences(PREFS_SETTINGS, 0) +// batteryReceiver = BatteryReceiver(binding.batteryProgress) +// mRecentCallsAdapter = RecentCallsAdapter(arrayListOf(), requireContext()) +// mSmsLogsAdapter = SmsLogsAdapter(arrayListOf(), requireContext()) +// mNotiAdapter = NotificationItemAdapter(requireContext()) +// mAppsAdapter = AppsAdapter(requireContext().packageManager , fragManager, null) +// mRssAdapter = RssItemAdapter(requireContext()) +// +// weatherDressAdapter = WeatherDressAdatper(arrayListOf()) +// weatherHourlyAdapter = WeatherHourlyAdapter(arrayListOf()) +// +// +// var weatherPages = arrayListOf() +// var weatherAdapter = arrayListOf?>() +// (PrefBoolean.weatherDress.get(false) || PrefBoolean.weatherState.get(false)).letTrue { +// PrefBoolean.weatherDress.get(false).letTrue { weatherPages.add(R.layout.hourly_weather); weatherAdapter.add(weatherDressAdapter!!) } +// PrefBoolean.weatherState.get(false).letTrue { weatherPages.add(R.layout.recommended_hourly_dress); weatherAdapter.add(weatherHourlyAdapter!!) } +// binding.weathers.root.visibility = View.VISIBLE +// mWeatherAdapter = WeatherAdapter(weatherPages, adatpers = weatherAdapter, binding.weathers) +// binding.weathers.weatherViewPager.offscreenPageLimit = 2 +// } +// +// val decoration = DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL) +// +// binding.notiList.addItemDecoration(decoration) +// binding.infoList.addItemDecoration(decoration) +// // binding.smsList.visibility = View.GONE -// binding.otherCheck.isSelected = false -// binding.recentSms.isSelected = false -// binding.missedCalls.isSelected = false -// binding.notice.isSelected = false - } - - val nomoreShowCount = 5 - fun rssStateVote() = (lasted?.filter { it.vote == true }?.size ?: -1) == (lasted?.size ?: 0) - - var lasted: List? = null - var lastedNoti: List? = null - var infosJob: Job? = null - var noticeJob: Job? = null - - lateinit var mRecentCallsAdapter: RecentCallsAdapter - lateinit var mSmsLogsAdapter: SmsLogsAdapter - lateinit var mRssAdapter: RssItemAdapter - lateinit var mNotiAdapter: NotificationItemAdapter - lateinit var mAppsAdapter: AppsAdapter - var mWeatherAdapter: WeatherAdapter? = null - var weatherDressAdapter: WeatherDressAdatper? = null - var weatherHourlyAdapter: WeatherHourlyAdapter? = null - var mRssDataResult: RealmResults? = null - var mNotificationResult: RealmResults? = null - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - home = this - } - - var musicJob: Job? = null - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = LauncherHomeOldBinding.inflate(inflater, container, false) - fragManager = lActivity!!.supportFragmentManager - settingsPrefs = requireContext().getSharedPreferences(PREFS_SETTINGS, 0) - batteryReceiver = BatteryReceiver(binding.batteryProgress) - mRecentCallsAdapter = RecentCallsAdapter(arrayListOf(), requireContext()) - mSmsLogsAdapter = SmsLogsAdapter(arrayListOf(), requireContext()) - mNotiAdapter = NotificationItemAdapter(requireContext()) - mAppsAdapter = AppsAdapter(requireContext().packageManager , fragManager, null) - mRssAdapter = RssItemAdapter(requireContext()) - - weatherDressAdapter = WeatherDressAdatper(arrayListOf()) - weatherHourlyAdapter = WeatherHourlyAdapter(arrayListOf()) - - - var weatherPages = arrayListOf() - var weatherAdapter = arrayListOf?>() - (PrefBoolean.weatherDress.get(false) || PrefBoolean.weatherState.get(false)).letTrue { - PrefBoolean.weatherDress.get(false).letTrue { weatherPages.add(R.layout.hourly_weather); weatherAdapter.add(weatherDressAdapter!!) } - PrefBoolean.weatherState.get(false).letTrue { weatherPages.add(R.layout.recommended_hourly_dress); weatherAdapter.add(weatherHourlyAdapter!!) } - binding.weathers.root.visibility = View.VISIBLE - mWeatherAdapter = WeatherAdapter(weatherPages, adatpers = weatherAdapter, binding.weathers) - binding.weathers.weatherViewPager.offscreenPageLimit = 2 - } - - val decoration = DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL) - - binding.notiList.addItemDecoration(decoration) - binding.infoList.addItemDecoration(decoration) - - binding.smsList.visibility = View.GONE - binding.infoList.visibility = View.GONE - - binding.weathers.weatherViewPager.orientation = ViewPager2.ORIENTATION_VERTICAL - - binding.mainList.adapter = mRecentCallsAdapter - binding.smsList.adapter = mSmsLogsAdapter - binding.infoList.adapter = mRssAdapter - binding.notiList.adapter = mNotiAdapter - binding.appsList.adapter = mAppsAdapter - binding.weathers.weatherViewPager.adapter = mWeatherAdapter - binding.weathers.weatherViewPager.registerOnPageChangeCallback(object : - ViewPager2.OnPageChangeCallback() { - override fun onPageSelected(position: Int) { - super.onPageSelected(position) - // 페이지가 변경될 때 호출됨 - mWeatherAdapter?.syncScroll(position) - - } - - }) - - binding.favApps.setOnLongClickListener { - RssViewBuilder(lActivity!!) - .setRssId("https://jav.guru") - .webViewDomStorageEnabled(true) - .webViewJavaScriptEnabled(true) - .webViewUserAgentAppend(false) - .webViewAllowContentAccess(true) - .webViewCookieEnabled(true) - .webViewCacheMode(LOAD_NO_CACHE) - .webViewUserAgentString(USAGT) - .webViewMixedContentMode(MIXED_CONTENT_ALWAYS_ALLOW) - .showIconClose(true) - .showIconBack(false) - .showProgressBar(true) - .backPressToClose(false) - .webViewCookieEnabled(true) - .show("https://jav.guru") - true - } - - binding.missedCalls.setOnLongClickListener { -// lActivity?.startActivity(Intent(lActivity, PhotoFilter::class.java)) +// binding.infoList.visibility = View.GONE +// +// binding.weathers.weatherViewPager.orientation = ViewPager2.ORIENTATION_VERTICAL +// +// binding.mainList.adapter = mRecentCallsAdapter +// binding.smsList.adapter = mSmsLogsAdapter +// binding.infoList.adapter = mRssAdapter +// binding.notiList.adapter = mNotiAdapter +// binding.appsList.adapter = mAppsAdapter +// binding.weathers.weatherViewPager.adapter = mWeatherAdapter +// binding.weathers.weatherViewPager.registerOnPageChangeCallback(object : +// ViewPager2.OnPageChangeCallback() { +// override fun onPageSelected(position: Int) { +// super.onPageSelected(position) +// // 페이지가 변경될 때 호출됨 +// mWeatherAdapter?.syncScroll(position) +// +// } +// +// }) +// +// binding.favApps.setOnLongClickListener { // RssViewBuilder(lActivity!!) -// .setRssId("https://booktoki468.com/") -// .webViewMixedContentMode(MIXED_CONTENT_ALWAYS_ALLOW) -// .webViewCacheMode(LOAD_NO_CACHE) +// .setRssId("https://jav.guru") +// .webViewDomStorageEnabled(true) // .webViewJavaScriptEnabled(true) // .webViewUserAgentAppend(false) // .webViewAllowContentAccess(true) // .webViewCookieEnabled(true) -// .webViewDomStorageEnabled(true) +// .webViewCacheMode(LOAD_NO_CACHE) // .webViewUserAgentString(USAGT) -// .showIconClose(true).showIconBack(false).showProgressBar(true).backPressToClose(false) -// .show("https://booktoki468.com/") - true - } - - arrayListOf(binding.mainList,binding.smsList,binding.infoList,binding.notiList).forEach { - try { - it.removeOnScrollListener(onScrChanged) - } catch (e: Exception) { - e.printStackTrace() - } - it.addOnScrollListener(onScrChanged) - } - - - - queryInfos() - queryNotice() - queryWeather() - queryApps() - setMusicFunction() - return binding.root - } - - fun isPackageInstalled( packageName : String, packageManager : PackageManager?) : Boolean{ - try { - packageManager!!.getPackageInfo(packageName, 0); - return true; - } catch ( e : Exception) { - return false; - } - } - - private fun queryApps() { - WorkersDb.getRealm().apply { - var newQ = query() - newQ.sort(Pair("clickCount", Sort.DESCENDING),Pair("lastUseDate",Sort.DESCENDING)).limit(30).find()?.let { - if(it.size > 0) { - WorkersDb.getRealm().apply { - var packageList = arrayListOf() - writeBlocking { - it.filter { - var installed = isPackageInstalled(it.pkgName ?: "fffffffail", lActivity?.packageManager) -// it.isInstalled = installed - installed - }.let { result -> - packageList.addAll(copyFromRealm(result)) - binding.appsList.post { if (result.size > 0) { - mAppsAdapter?.updateData(packageList) - }} - } - } - } - } - } - } - } - - fun setMusicFunction() { - binding.currentMusic.setOnClickListener { - lActivity?.apply { - packageManager?.apply { - startActivity(getLaunchIntentForPackage("com.google.android.apps.youtube.music")) - } - } - } - - if(PrefBoolean.showNowPlaying.get(false)) { - musicJob?.cancel() - musicJob = CoroutineScope(Dispatchers.Default).launch { - WorkersDb.getRealm().apply { - query().find().asFlow() - .collect { changes: ResultsChange -> - binding.currentMusic.postDelayed({ - Blog.LOGE("changes.list >>> ${changes.list}") - if (changes.list.size > 0) { - changes.list.first()?.let { - binding.currentMusic.visibility = View.VISIBLE - binding.nextPlay.visibility = View.GONE - binding.artist.text = it.artists - binding.artist.isSelected = true - binding.title.text = it.title - binding.title.isSelected = true - try { - BitmapConverter.StringToBitmap(it.albumArt)?.let { - binding.albumArt.setImageBitmap(it) - } - } catch (exception: java.lang.Exception) { - // log error - } - } - } else { - binding.currentMusic.visibility = View.GONE - binding.nextPlay.visibility = View.VISIBLE - } - }, 150L) - } - } - } - musicJob?.start() - binding.nextBtn.setOnClickListener { - val mAudioManager = - requireContext().getSystemService(AUDIO_SERVICE) as AudioManager - - val eventtime: Long = SystemClock.uptimeMillis() - - val downEvent = - KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT, 0) - mAudioManager.dispatchMediaKeyEvent(downEvent) - - val upEvent = - KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT, 0) - mAudioManager.dispatchMediaKeyEvent(upEvent) - } - binding.nextPlay.setOnClickListener { - val mAudioManager = - requireContext().getSystemService(AUDIO_SERVICE) as AudioManager - - val eventtime: Long = SystemClock.uptimeMillis() - - val downEvent = - KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY, 0) - mAudioManager.dispatchMediaKeyEvent(downEvent) - - val upEvent = - KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY, 0) - mAudioManager.dispatchMediaKeyEvent(upEvent) - } - } else { - binding.currentMusic.visibility = View.GONE - binding.nextPlay.visibility = View.VISIBLE - } - } - @SuppressLint("NotifyDataSetChanged") - fun queryWeatherWithLoc() { - WorkersDb.getRealm().apply { - var latR = latitudeRange( - BigDecimal.valueOf(LocationGetter.latitude).setScale(6, RoundingMode.HALF_UP) - .toDouble(), 200 - ) - var lonR = longitudeRange( - BigDecimal.valueOf(LocationGetter.latitude).setScale(6, RoundingMode.HALF_UP) - .toDouble(), - BigDecimal.valueOf(LocationGetter.longitude).setScale(6, RoundingMode.HALF_UP) - .toDouble(), - 200 - ) - query() - .query( - "lat >= $0 AND lat <= $1 AND lon >= $2 AND lon <= $3 AND time_epoch >= $4", - latR.first(), latR.last(), - lonR.first(), lonR.last(), - (System.currentTimeMillis() / 1000L).toLong() - ).also { -// Blog.LOGE("re >>> ${it.description()}") - }.find().let { hours -> - Handler(Looper.getMainLooper()).post { - weatherDressAdapter?.let { - it.update( - mutableListOf().apply { - this.addAll( -// it.filter(hours) - copyFromRealm(hours) - ) - } - ) - it.notifyDataSetChanged() - } - weatherHourlyAdapter?.let { - it.update( - mutableListOf().apply { - this.addAll( -// it.filter(hours) - copyFromRealm(hours) - ) - } - ) -// Blog.LOGE("hour ${hours}") - it.notifyDataSetChanged() - } - mWeatherAdapter?.let { - fun onclick() { - requireContext().startActivity(Intent().apply { - action = Intent.ACTION_VIEW - setData(Uri.parse("https://www.accuweather.com/ko/search-locations?query=${LocationGetter.latitude},${LocationGetter.longitude}")) - }) - } - binding.weathers.weatherViewPager.setOnTouchListener { v, event -> - onclick() - true - } - binding.weathers.weatherViewPager.setOnClickListener { onclick() } - binding.weathers.root.setOnClickListener { onclick() } - binding.weathers.textLocation = - if (hours.isNotEmpty()) WeatherInfoManager.getShowingInfo(hours.first()).textLocation else "도시 / 나라" - it.notifyDataSetChanged() - } - } - } - } - } - - - // lateinit var weatherJob : Job -// @SuppressLint("NotifyDataSetChanged") - private fun queryWeather() { - result = WorkersDb.getRealm().query().also { -// Blog.LOGE("re >>> ${it.description()}") // 쿼리 로그 - }.find() - weatherJob?.cancel() - weatherJob = CoroutineScope(Dispatchers.Default).launch { - result?.asFlow()?.collect { li -> - //Blog.LOGE("queryWeather done. >>> ${li}") - if (li.list.size > 0) { - //Blog.LOGE("queryWeather done. >>> ${li.list.size}") - queryWeatherWithLoc() - } - } - } - weatherJob?.start() - } - - - val onScrChanged = object : RecyclerView.OnScrollListener() { - override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { - super.onScrollStateChanged(recyclerView, newState) - commandHandler.removeCallbacks(hideListView) - when (newState) { - RecyclerView.SCROLL_STATE_IDLE -> { - commandHandler.postDelayed(hideListView, hideListViewTime) - } - - RecyclerView.SCROLL_STATE_DRAGGING -> { - } - - RecyclerView.SCROLL_STATE_SETTLING -> { - } - } - } - - override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { - super.onScrolled(recyclerView, dx, dy) - commandHandler.removeCallbacks(hideListView) - } - } - - private fun queryNotice() { - mNotificationResult = null - clearJob(noticeJob) - mNotificationResult = WorkersDb.getRealm().query().sort("postTime", Sort.DESCENDING).find() - noticeJob = CoroutineScope(Dispatchers.Default).launch { - mNotificationResult?.asFlow()?.collect { changes: ResultsChange -> - commandHandler.removeCallbacks(hideListView) - when (changes) { - is UpdatedResults -> { - WorkersDb.getRealm().apply { - lastedNoti = copyFromRealm(changes.list) - } - commandHandler.removeCallbacks(notiUpdate) - commandHandler.postDelayed(notiUpdate, UPDATE_DELAY) - } - - else -> { - } - } - } - } - noticeJob?.start() - } - fun clearJob(job : Job?) { - try { job?.cancel() } catch (e: Exception) { e.printStackTrace() } - try { System.gc() } catch (e: Exception) { e.printStackTrace() } - } - fun beforeQuery() { - clearJob(infosJob) - mRssDataResult = null - WorkersDb.getRealm().writeBlocking { - delete( - query() - .query("pubDate < $0", beforeDay(30)) - .query("category != $0 AND category != $1 ", RssDataType.GURU.name, RssDataType.MOST.name) - .query("vote != $0", true).find() - ) - } - } - - fun updateQuery(q: RealmQuery) { - mRssDataResult = q.sort("pubDate ", Sort.DESCENDING).limit(300).distinct("originPage", "title").find() - mRssDataResult?.asFlow()?.let { flow -> - - infosJob = CoroutineScope(Dispatchers.IO).launch { - flow.collect { changes: ResultsChange -> - commandHandler.removeCallbacks(hideListView) - commandHandler.removeCallbacks(infoUpdate) - WorkersDb.getRealm().apply { - lasted = copyFromRealm(changes.list) - } - commandHandler.postDelayed(infoUpdate, UPDATE_DELAY) - - } - } - infosJob?.start() - } - - - - } - - fun queryVotes() { - beforeQuery() - updateQuery(WorkersDb.getVotedRss()) - } - - fun queryInfos( - filter: Collection? = arrayListOf(RssDataType.GURU, RssDataType.MOST,RssDataType.REDDIT_NSFW), noLimit: Boolean = false - ) { - beforeQuery() - var rQ = WorkersDb.getRealm().query().query("read < $0", nomoreShowCount).distinct("originPage", "title") - if (!noLimit) rQ.query("pubDate > $0", beforeOneDay()) - ((filter?.size ?: 0) > 0).letTrue {filter!!.forEach {rQ = rQ.query("category != $0", it.name)}} - updateQuery(rQ) - } - - fun queryInfos( - keyword: String, - category: ArrayList = arrayListOf(), - noLimit: Boolean = false - ) { - beforeQuery() - updateQuery(WorkersDb.getRssQuery(keyword,category,noLimit)) - } - - - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - - PrefBoolean.displayDateTime.get().letTrue { - binding.time.visibility = View.VISIBLE - } - - - PrefBoolean.displayBattery.get().letTrue { - binding.batteryProgress.visibility = View.VISIBLE - } - - binding.batteryProgress.setOnTouchListener(SimpleFingerGestures(context = requireContext(), binding.batteryProgress, mFingerGestureListener)) - binding.root.setOnTouchListener(SimpleFingerGestures(context = requireContext(), binding.root, mFingerGestureListener)) - binding.functionLayer.setOnTouchListener(SimpleFingerGestures(context = requireContext(), binding.functionLayer, mFingerGestureListener)) - binding.time.setOnTouchListener(SimpleFingerGestures(context = requireContext(), binding.time, mFingerGestureListener)) - - Blog.LOGE("onViewCreated()") - - binding.summaryChoose.visibility = View.GONE - (PrefBoolean.showCallHistory.get(false) || PrefBoolean.showSMSHistory.get(false) || PrefBoolean.showNotificationHistory.get(false) || PrefBoolean.showNewsHistory.get(false)).letTrue { - binding.summaryChoose.visibility = View.VISIBLE - binding.missedCalls.visibility = if (PrefBoolean.showCallHistory.get(false)) View.VISIBLE else View.GONE - binding.recentSms.visibility = if (PrefBoolean.showSMSHistory.get(false)) View.VISIBLE else View.GONE - binding.notice.visibility = if (PrefBoolean.showNotificationHistory.get(false)) View.VISIBLE else View.GONE - binding.otherCheck.visibility = if (PrefBoolean.showNewsHistory.get(false)) View.VISIBLE else View.GONE - } - - fragManager.addOnBackStackChangedListener { - Blog.LOGE("addOnBackStackChangedListener()") - shouldResume = if (fragManager.backStackEntryCount == 0) { - binding.root.visibility = View.VISIBLE - true - } else { - binding.root.visibility = View.GONE - false - } - } - - var checkListner = object : View.OnClickListener { - override fun onClick(v: View?) { - commandHandler.removeCallbacks(hideListView) - var views = arrayListOf(binding.mainList, binding.smsList, binding.infoList, binding.notiList,binding.appsList) - var chechboxs = arrayListOf(binding.missedCalls, binding.recentSms, binding.otherCheck, binding.notice, binding.favApps) - chechboxs.remove(v) - when (v) { - binding.missedCalls -> { - binding.missedCalls.isSelected = !binding.missedCalls.isSelected - if (binding.missedCalls.isSelected) { - views.remove(binding.mainList) - binding.mainList.visibility = View.VISIBLE - } - } - - binding.recentSms -> { - binding.recentSms.isSelected = !binding.recentSms.isSelected - if (binding.recentSms.isSelected) { - views.remove(binding.smsList) - binding.smsList.visibility = View.VISIBLE - } - } - - binding.otherCheck -> { - if (binding.otherCheck.isSelected) { - if (rssStateVote()) { - queryInfos() - } else { - binding.otherCheck.isSelected = false - } - } else { - queryInfos() - binding.otherCheck.isSelected = true - views.remove(binding.infoList) - binding.infoList.scrollToPosition(0) - binding.infoList.visibility = View.VISIBLE - } - } - - binding.notice -> { - if (binding.notice.isSelected) { - binding.notice.isSelected = false - } else { - queryNotice() - binding.notice.isSelected = true - views.remove(binding.notiList) - binding.notiList.visibility = View.VISIBLE - } - } - binding.favApps -> { - if (binding.favApps.isSelected) { - binding.favApps.isSelected = false - } else { - binding.favApps.isSelected = true - views.remove(binding.appsList) - binding.appsList.visibility = View.VISIBLE - } - } - } - chechboxs.forEach { it.isSelected = false } - views.forEach { it.visibility = View.GONE } - chooseAdpater() - } - } - - binding.otherCheck.setOnClickListener(checkListner) - binding.recentSms.setOnClickListener(checkListner) - binding.missedCalls.setOnClickListener(checkListner) - binding.notice.setOnClickListener(checkListner) - binding.favApps.setOnClickListener(checkListner) - binding.otherCheck.setOnLongClickListener { - queryInfos() - true - } - enableSwipeToDeleteAndUndo() - } - - - - fun searchData() { - val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext()) - builder.setTitle("Command Line") - val viewInflated: View = LayoutInflater.from(context) - .inflate(R.layout.search_layout, view as ViewGroup?, false) - val input = viewInflated.findViewById(R.id.input) as EditText - val categoryz = - viewInflated.findViewById(R.id.categoryz) as TableRadioGroup - categoryz.setMaxColumns(3) - categoryz.setMaxRows(8) - categoryz.setOnCheckedChangeListener(object : TableRadioGroup.OnCheckedChangeListener { - override fun onCheckedChanged(group: TableRadioGroup?, checkedId: Int) { - - } - }) - var idx = 0 - RssDataType.values().reversed().toList().chunked(3).forEach { - var tb = TableRow(requireContext()) - it.forEach { c -> - if (c.equals(RssDataType.NO_DATA) == false) { - tb.addView( - CheckBox(requireContext()).apply { - this.tag = c.name - this.text = c.name - } - ) - } - } - categoryz.addView(tb) - } - - builder.setView(viewInflated) - builder.setPositiveButton(android.R.string.ok, - DialogInterface.OnClickListener { dialog, which -> - dialog.dismiss() - var category = arrayListOf() - categoryz.children.forEach { - if (it is TableRow) { - it.children.forEach { - if (it is CheckBox && it.isChecked) { - (it.tag as? String)?.let { category.add(it) } - } - } - } - } - queryInfos(keyword = input.text.toString(), category, false) - }) - builder.setNegativeButton(android.R.string.cancel, - DialogInterface.OnClickListener { dialog, which -> dialog.cancel() }) - builder.show() - } - - - fun showAl() { - binding.alcholKatalkT.visibility = View.VISIBLE - binding.alcholKatalkT.setOnClickListener { - openSearchApps( - "kakaot://taxi?dest_lat=${URLEncoder.encode("37.467696")}&dest_lng=${ - URLEncoder.encode( - "127.101063" - ) - }", "com.kakao.taxi" - ) - } - - } - - fun openSearchApps(schemeString: String, pakage: String? = null) { - val gmmIntentUri = Uri.parse(schemeString) - val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri) - pakage?.let { - mapIntent.setPackage(pakage) - } - startActivity(mapIntent) - } - - fun hideAl() { - binding.alcholKatalkT.visibility = View.GONE - binding.alcholKatalkT.setOnClickListener { - - } - } - - fun chooseAdpater() { - commandHandler.removeCallbacks(hideListView) - var tabs = arrayOf(binding.missedCalls,binding.recentSms,binding.otherCheck,binding.notice,binding.favApps) - fun unsel(view: View) { - tabs.filter { - it.equals(view) == false - }.forEach { it.isSelected = false } - } - binding.mainList.visibility = View.INVISIBLE - binding.smsList.visibility = View.INVISIBLE - binding.infoList.visibility = View.INVISIBLE - binding.notiList.visibility = View.INVISIBLE - - var dateParam = beforeDay(30).toString() - if (binding.missedCalls.isSelected) { - WorkersDb.getRealm().apply { - val result = query().query("callDayTime >= $0", dateParam) - .sort("callDayTime", Sort.DESCENDING).find() - val list = copyFromRealm(result) - binding.missedCalls.text = "통화 목록 [${list.size}]" - binding.mainList.visibility = View.VISIBLE - mRecentCallsAdapter.updateData(list) - } - } else if (binding.recentSms.isSelected) { - WorkersDb.getRealm().apply { - val result = query().query("rcvDate >= $0 OR pstDate >= $0 ", dateParam) - .sort("rcvDate", Sort.DESCENDING).find() - if (result.size > 0) { - try { - binding.recentSms.text = "문자 내역 [${result.size}]" - binding.smsList.visibility = View.VISIBLE - val list = copyFromRealm(result) - mSmsLogsAdapter.updateData(list) - - } catch (e: Exception) { - - } - } - } - } else if (binding.otherCheck.isSelected) { - unsel(binding.otherCheck) - binding.infoList.visibility = View.VISIBLE -// binding.otherCheck.text = "글타래 [${lasted?.size ?: "-"}]" - lasted?.let { mRssAdapter.updateData(it) } - } else if (binding.notice.isSelected) { - unsel(binding.notice) - binding.notiList.visibility = View.VISIBLE -// binding.notice.text = "알림 [${lastedNoti?.size ?: "-"}]" - lastedNoti?.let { mNotiAdapter.updateData(it) } - } else if (binding.favApps.isSelected) { - unsel(binding.favApps) - binding.appsList.visibility = View.VISIBLE - } - commandHandler.postDelayed(hideListView, hideListViewTime) - } - - private fun enableSwipeToDeleteAndUndo() { - val swipeToDeleteCallback: SwipeToDeleteCallback = - object : SwipeToDeleteCallback(requireContext()) { - override fun onSwiped(@NonNull viewHolder: RecyclerView.ViewHolder, direction: Int) { - Blog.LOGE("onSwiped direction >>>> $direction") - (viewHolder.itemView.tag as? RssData)?.let { rss -> - CoroutineScope(Dispatchers.IO).launch { - WorkersDb.getRealm().apply { - writeBlocking { - when (direction) { - ItemTouchHelper.LEFT -> { - if (rssStateVote() && rss.vote) { - rss.vote = false - rss.read = 0 - } else { - rss.read += nomoreShowCount - } - query( - "originPage == $0", - rss.originPage - ).find().forEach { it -> - it.read += nomoreShowCount - } - } - - ItemTouchHelper.RIGHT -> { - if (rssStateVote() && rss.vote) { - rss.vote = false - rss.read = 0 - } else { - rss.vote = true - - } - } - - else -> {} - } - binding.infoList.post { mRssAdapter.refresh() } - } - } - } - } - } - } - - val itemTouchhelper = ItemTouchHelper(swipeToDeleteCallback) - itemTouchhelper.attachToRecyclerView(binding.infoList) - } - - override fun onResume() { - super.onResume() -// BLog.LOGE("${this} ::::: onResume >>>> ") - if (shouldResume) { - - /* register battery changes */ - requireContext().registerReceiver( - batteryReceiver, - IntentFilter(Intent.ACTION_BATTERY_CHANGED) - ) - /* time and date */ -// binding.time.textLocale = Locale.US -// binding.date.textLocale = Locale.US -// if (DateFormat.is24HourFormat(requireContext())) { -// binding.time.format24Hour = timeFormat -// binding.date.format24Hour = "yyyy년 M월 W주차, dd일 E요일" -// } else { -// binding.time.format12Hour = timeFormat -// binding.date.format12Hour = dateFormat +// .webViewMixedContentMode(MIXED_CONTENT_ALWAYS_ALLOW) +// .showIconClose(true) +// .showIconBack(false) +// .showProgressBar(true) +// .backPressToClose(false) +// .webViewCookieEnabled(true) +// .show("https://jav.guru") +// true +// } +// +// binding.missedCalls.setOnLongClickListener { +//// lActivity?.startActivity(Intent(lActivity, PhotoFilter::class.java)) +//// RssViewBuilder(lActivity!!) +//// .setRssId("https://booktoki468.com/") +//// .webViewMixedContentMode(MIXED_CONTENT_ALWAYS_ALLOW) +//// .webViewCacheMode(LOAD_NO_CACHE) +//// .webViewJavaScriptEnabled(true) +//// .webViewUserAgentAppend(false) +//// .webViewAllowContentAccess(true) +//// .webViewCookieEnabled(true) +//// .webViewDomStorageEnabled(true) +//// .webViewUserAgentString(USAGT) +//// .showIconClose(true).showIconBack(false).showProgressBar(true).backPressToClose(false) +//// .show("https://booktoki468.com/") +// true +// } +// +// arrayListOf(binding.mainList,binding.smsList,binding.infoList,binding.notiList).forEach { +// try { +// it.removeOnScrollListener(onScrChanged) +// } catch (e: Exception) { +// e.printStackTrace() // } - /* show weather */ -// WeatherExecutor(settingsPrefs).generateWeatherString(binding.weather) - } -// binding.root.visibility = View.VISIBLE - } - - - override fun onPause() { - super.onPause() - /* unregister battery changes */ - if (shouldResume) requireContext().unregisterReceiver(batteryReceiver) -// binding.root.visibility = View.GONE - } - - - var mFingerGestureListener = object : SimpleFingerGestures.OnFingerGestureListener { - override fun onSwipeUp( - targetView: View, - fingers: Int, - gestureDuration: Long, - gestureDistance: Double - ): Boolean { - when (fingers) { - 4 -> { - lActivity!!.startActivity(Intent(requireContext(), Behavior::class.java)) - } - - 3 -> QuickAccess().show(fragManager, BOTTOM_SHEET_TAG) - 2 -> { - var startIntene = Intent(Intent.ACTION_MAIN) - startIntene.setComponent( - ComponentName( - "com.mime.dualscreenview", - "com.mime.dualscreenview.activity.Intro" - ) - ) - startActivity(startIntene) - } - 1->{ - lActivity?.switchAppDrawer() - } - else -> {} - } - return false - } - - override fun onSwipeDown( - targetView: View, - fingers: Int, - gestureDuration: Long, - gestureDistance: Double - ): Boolean { - when (fingers) { - 2 -> - if (targetView.equals(binding.batteryProgress)) { - expandNotificationPanel(requireContext()) - } else { - expandNotificationPanel(requireContext()) - } - - 4 -> { - var startIntene = Intent(Intent.ACTION_MAIN) - startIntene.setComponent( - ComponentName( - "com.samsung.android.app.interpreter", - "com.samsung.android.app.interpreter.interpretation.view.InterpretationActivity" - ) - ) - startActivity(startIntene) - } - - 3 -> { - lActivity!!.startActivity( - Intent( - requireContext(), - SettingsActivity::class.java - ) - ) - } - - else -> {} - } - return false - } - - override fun onSwipeLeft( - targetView: View, - fingers: Int, - gestureDuration: Long, - gestureDistance: Double - ): Boolean { -// if (targetView.equals(binding.time)) { -// val mClockIntent = Intent(AlarmClock.ACTION_SHOW_ALARMS) -// mClockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) -// startActivity(mClockIntent) -// } - - Blog.LOGE("onSwipeLeft targetView. >>>> ${targetView} && ${targetView.equals(binding.functionLayer)}") - if(targetView.equals(binding.functionLayer)){ - targetView?.performHapticFeedback(HapticFeedbackConstants.CONFIRM) - when(fingers) { - 1->lActivity?.switchAppDrawer() - 2-> { - - } - else ->{} - } - } else if (targetView.equals(binding.time) && fingers == 2) { - val mClockIntent = Intent(AlarmClock.ACTION_SHOW_ALARMS) - mClockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - startActivity(mClockIntent) - } - return false - } - - override fun onSwipeRight( - targetView: View, - fingers: Int, - gestureDuration: Long, - gestureDistance: Double - ): Boolean { - if(targetView.equals(binding.functionLayer)){ - targetView?.performHapticFeedback(HapticFeedbackConstants.CONFIRM) - when(fingers) { - 1-> { -// lActivity?.switchFeeds() - return true - } - // - else ->{} - } - } else if (targetView.equals(binding.time) && fingers == 2) { - val intent = Intent(Intent.ACTION_MAIN) - intent.addCategory(Intent.CATEGORY_APP_CALENDAR) - startActivity(intent) - } - return false - } - - override fun onPinch( - targetView: View, - fingers: Int, - gestureDuration: Long, - gestureDistance: Double - ): Boolean { - Blog.LOGE("Maybe GA PINCH is Like Zoom out") - return false - } - - override fun onUnpinch( - targetView: View, - fingers: Int, - gestureDuration: Long, - gestureDistance: Double - ): Boolean { - Blog.LOGE("Maybe GA UN PINCH is Like Zoom In") - return false - } - - override fun onDoubleTap(targetView: View, fingers: Int): Boolean { - targetView?.performHapticFeedback(HapticFeedbackConstants.CONFIRM) - when (fingers) { - 1 -> lockMethod(settingsPrefs.getInt(KEY_LOCK_METHOD, 0), requireContext(), binding.functionLayer) - else -> { - - } - } - return false - } - - override fun onLongPress(targetView: View, fingers: Int): Boolean { - if (targetView?.equals(binding.batteryProgress) == true) { - lActivity!!.startActivity(Intent(requireContext(), SettingsActivity::class.java)) - } else if (targetView?.equals(binding.mainList) == true) { -// when (settingsPrefs.getBoolean(KEY_TODO_LOCK, false)) { -// false -> launchTodoManager() -// /* show authentication screen if lock is on */ -// true -> { -// if (canAuthenticate(requireContext())) { -// val biometricPrompt = -// BiometricPrompt(lActivity!!, authenticationCallback) -// try { -// biometricPrompt.authenticate( -// biometricPromptInfo( -// lActivity!!.getString( -// R.string.todo_manager -// ) -// ) -// ) -// } catch (exception: Exception) { -// exception.printStackTrace() +// it.addOnScrollListener(onScrChanged) +// } +// +// +// +// queryInfos() +// queryNotice() +// queryWeather() +// queryApps() +// setMusicFunction() +// return binding.root +// } +// +// fun isPackageInstalled( packageName : String, packageManager : PackageManager?) : Boolean{ +// try { +// packageManager!!.getPackageInfo(packageName, 0); +// return true; +// } catch ( e : Exception) { +// return false; +// } +// } +// +// private fun queryApps() { +// WorkersDb.getRealm().apply { +// var newQ = query() +// newQ.sort(Pair("clickCount", Sort.DESCENDING),Pair("lastUseDate",Sort.DESCENDING)).limit(30).find()?.let { +// if(it.size > 0) { +// WorkersDb.getRealm().apply { +// var packageList = arrayListOf() +// writeBlocking { +// it.filter { +// var installed = isPackageInstalled(it.pkgName ?: "fffffffail", lActivity?.packageManager) +//// it.isInstalled = installed +// installed +// }.let { result -> +// packageList.addAll(copyFromRealm(result)) +// binding.appsList.post { if (result.size > 0) { +// mAppsAdapter?.updateData(packageList) +// }} // } // } // } // } - } else if (targetView?.equals(binding.functionLayer) == true) { - targetView?.performHapticFeedback(HapticFeedbackConstants.CONFIRM) - if(binding.otherCheck.isSelected && rssStateVote()) { - queryInfos() - } else { - binding.otherCheck.isSelected = true - queryVotes() - } - return true - } - return false - } - - override fun onClick(targetView: View, fingers: Int): Boolean { -// BLog.LOGE("onClick ${view} , fingers ${fingers}") - targetView.performHapticFeedback(HapticFeedbackConstants.CONFIRM) - when (fingers) { - 1 -> { - if (targetView.equals(binding.batteryProgress) == true) { - startActivity(Intent(Settings.ACTION_SETTINGS)) - }else if(targetView.equals(binding.functionLayer)) { - if (binding.otherCheck.isSelected) { - searchData() - } -// else if (binding.otherCheck.isSelected) { -// searchData() -// } -// else if (binding.otherCheck.isSelected) { -// searchData() -// } -// else if (binding.otherCheck.isSelected) { -// searchData() -// } -// else if (binding.otherCheck.isSelected) { -// searchData() -// } - else { -// QuickAccess().show(fragManager, BOTTOM_SHEET_TAG) - } - } - } - - 2 -> { - lockMethod( - settingsPrefs.getInt(KEY_LOCK_METHOD, 0), - requireContext(), - binding.functionLayer - ) - } - - else -> { - - } - } - - return true - } - - } - - - fun jsonObjLog(pkey: String, key: String, jsonObject: JSONObject) { - if (jsonObject.has(key) == true && jsonObject.get(key) is String) { - Blog.LOGE("jsonObjLog $pkey String in $key >> ${jsonObject.getString(key)}") - } else if (jsonObject.has(key) == true && jsonObject.get(key) is JSONObject) { - var obj = jsonObject.getJSONObject(key) - Blog.LOGE("jsonObjLog $pkey JSONObject in $key >> ${obj}") - obj?.keys()?.forEach { -// jsonObjLog(key,it, obj) - } - } else if (jsonObject.has(key) == true && jsonObject.get(key) is JSONArray) { - Blog.LOGE("jsonObjLog $pkey JSONArray in $key >> ${jsonObject.getJSONArray(key)}") - var array = jsonObject.getJSONArray(key) - for (i in 0..<(array?.length() ?: 0)) { - if (array?.get(i) is String) { - - } else if (array?.get(i) is JSONObject) { - var child = array.getJSONObject(i) - child?.keys()?.forEach { -// jsonObjLog(key, it, child) - } - } else if (array?.get(i) is JSONArray) { - Blog.LOGE("jsonObjLog $pkey JSONArray in $key >> ${array.getJSONArray(i)}") - } - } - } else { - Blog.LOGE( - "jsonObjLog $pkey else in $key >> ${ - if (jsonObject.has(key) == true) (jsonObject.get( - key - )) else ("") - }" - ) - } - } - - - /* gestures on root view */ - @SuppressLint("ClickableViewAccessibility") - private fun rootViewGestures() { - binding.root.setOnTouchListener( - SimpleFingerGestures( - context = requireContext(), - binding.root, - mFingerGestureListener - ) - ) - } - - - - /* gestures on to-do area */ - @SuppressLint("ClickableViewAccessibility") - private fun todosGestures() { - binding.mainList.setOnTouchListener( - SimpleFingerGestures( - context = requireContext(), - binding.mainList, - mFingerGestureListener - ) - ) - } - - - - /* authentication callback for TodoManager lock */ - private val authenticationCallback = object : BiometricPrompt.AuthenticationCallback() { - override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { - launchTodoManager() - } - - override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { - Toast.makeText( - requireContext(), - lActivity!!.getString(R.string.authentication_error), - Toast.LENGTH_SHORT - ).show() - } - - override fun onAuthenticationFailed() { - Toast.makeText( - requireContext(), - lActivity!!.getString(R.string.authentication_failed), - Toast.LENGTH_SHORT - ).show() - } - } - - /* launch TodoManager fragment */ - private fun launchTodoManager() { -// fragManager.beginTransaction().replace(R.id.mainFragmentsContainer, TodoManager()) -// .addToBackStack("").commit() - } - - - /* get time format string */ - private val timeFormat: String - get() { -// when (settingsPrefs.getInt(KEY_TIME_FORMAT, 0)) { -// 0 -> return if (DateFormat.is24HourFormat(requireContext())) { -// "kk:mm" -// } else { -// "HH:mm a" -// } -// 1 -> return "HH:mm a" -// 2 -> return "kk:mm" -// } - return "a HH : mm" - } - - /* get date number suffix */ - private val dateNumberSuffix: String - get() { - return when (Calendar.getInstance()[Calendar.DAY_OF_MONTH]) { - 1, 21, 31 -> "ˢᵗ" - 2, 22 -> "ⁿᵈ" - 3, 23 -> "ʳᵈ" - else -> "ᵗʰ" - } - } - - /* get date format string */ - private val dateFormat: String - get() { -// settingsPrefs.getString(KEY_DATE_FORMAT, DEFAULT_DATE_FORMAT).let { -// return if (it!!.contains("x")) { -// it.replace("x", dateNumberSuffix) -// } else { -// it // } // } - return "yyyy년 M월 W주차, dd일 E요일" - } - -} - - - - +// } +// +// fun setMusicFunction() { +// binding.currentMusic.setOnClickListener { +// lActivity?.apply { +// packageManager?.apply { +// startActivity(getLaunchIntentForPackage("com.google.android.apps.youtube.music")) +// } +// } +// } +// +// if(PrefBoolean.showNowPlaying.get(false)) { +// musicJob?.cancel() +// musicJob = CoroutineScope(Dispatchers.Default).launch { +// WorkersDb.getRealm().apply { +// query().find().asFlow() +// .collect { changes: ResultsChange -> +// binding.currentMusic.postDelayed({ +// Blog.LOGE("changes.list >>> ${changes.list}") +// if (changes.list.size > 0) { +// changes.list.first()?.let { +// binding.currentMusic.visibility = View.VISIBLE +// binding.nextPlay.visibility = View.GONE +// binding.artist.text = it.artists +// binding.artist.isSelected = true +// binding.title.text = it.title +// binding.title.isSelected = true +// try { +// BitmapConverter.StringToBitmap(it.albumArt)?.let { +// binding.albumArt.setImageBitmap(it) +// } +// } catch (exception: java.lang.Exception) { +// // log error +// } +// } +// } else { +// binding.currentMusic.visibility = View.GONE +// binding.nextPlay.visibility = View.VISIBLE +// } +// }, 150L) +// } +// } +// } +// musicJob?.start() +// binding.nextBtn.setOnClickListener { +// val mAudioManager = +// requireContext().getSystemService(AUDIO_SERVICE) as AudioManager +// +// val eventtime: Long = SystemClock.uptimeMillis() +// +// val downEvent = +// KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT, 0) +// mAudioManager.dispatchMediaKeyEvent(downEvent) +// +// val upEvent = +// KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT, 0) +// mAudioManager.dispatchMediaKeyEvent(upEvent) +// } +// binding.nextPlay.setOnClickListener { +// val mAudioManager = +// requireContext().getSystemService(AUDIO_SERVICE) as AudioManager +// +// val eventtime: Long = SystemClock.uptimeMillis() +// +// val downEvent = +// KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY, 0) +// mAudioManager.dispatchMediaKeyEvent(downEvent) +// +// val upEvent = +// KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY, 0) +// mAudioManager.dispatchMediaKeyEvent(upEvent) +// } +// } else { +// binding.currentMusic.visibility = View.GONE +// binding.nextPlay.visibility = View.VISIBLE +// } +// } +// @SuppressLint("NotifyDataSetChanged") +// fun queryWeatherWithLoc() { +// WorkersDb.getRealm().apply { +// var latR = latitudeRange( +// BigDecimal.valueOf(LocationGetter.latitude).setScale(6, RoundingMode.HALF_UP) +// .toDouble(), 200 +// ) +// var lonR = longitudeRange( +// BigDecimal.valueOf(LocationGetter.latitude).setScale(6, RoundingMode.HALF_UP) +// .toDouble(), +// BigDecimal.valueOf(LocationGetter.longitude).setScale(6, RoundingMode.HALF_UP) +// .toDouble(), +// 200 +// ) +// query() +// .query( +// "lat >= $0 AND lat <= $1 AND lon >= $2 AND lon <= $3 AND time_epoch >= $4", +// latR.first(), latR.last(), +// lonR.first(), lonR.last(), +// (System.currentTimeMillis() / 1000L).toLong() +// ).also { +//// Blog.LOGE("re >>> ${it.description()}") +// }.find().let { hours -> +// Handler(Looper.getMainLooper()).post { +// weatherDressAdapter?.let { +// it.update( +// mutableListOf().apply { +// this.addAll( +//// it.filter(hours) +// copyFromRealm(hours) +// ) +// } +// ) +// it.notifyDataSetChanged() +// } +// weatherHourlyAdapter?.let { +// it.update( +// mutableListOf().apply { +// this.addAll( +//// it.filter(hours) +// copyFromRealm(hours) +// ) +// } +// ) +//// Blog.LOGE("hour ${hours}") +// it.notifyDataSetChanged() +// } +// mWeatherAdapter?.let { +// fun onclick() { +// requireContext().startActivity(Intent().apply { +// action = Intent.ACTION_VIEW +// setData(Uri.parse("https://www.accuweather.com/ko/search-locations?query=${LocationGetter.latitude},${LocationGetter.longitude}")) +// }) +// } +// binding.weathers.weatherViewPager.setOnTouchListener { v, event -> +// onclick() +// true +// } +// binding.weathers.weatherViewPager.setOnClickListener { onclick() } +// binding.weathers.root.setOnClickListener { onclick() } +// binding.weathers.textLocation = +// if (hours.isNotEmpty()) WeatherInfoManager.getShowingInfo(hours.first()).textLocation else "도시 / 나라" +// it.notifyDataSetChanged() +// } +// } +// } +// } +// } +// +// +// // lateinit var weatherJob : Job +//// @SuppressLint("NotifyDataSetChanged") +// private fun queryWeather() { +// result = WorkersDb.getRealm().query().also { +//// Blog.LOGE("re >>> ${it.description()}") // 쿼리 로그 +// }.find() +// weatherJob?.cancel() +// weatherJob = CoroutineScope(Dispatchers.Default).launch { +// result?.asFlow()?.collect { li -> +// //Blog.LOGE("queryWeather done. >>> ${li}") +// if (li.list.size > 0) { +// //Blog.LOGE("queryWeather done. >>> ${li.list.size}") +// queryWeatherWithLoc() +// } +// } +// } +// weatherJob?.start() +// } +// +// +// val onScrChanged = object : RecyclerView.OnScrollListener() { +// override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { +// super.onScrollStateChanged(recyclerView, newState) +// commandHandler.removeCallbacks(hideListView) +// when (newState) { +// RecyclerView.SCROLL_STATE_IDLE -> { +// commandHandler.postDelayed(hideListView, hideListViewTime) +// } +// +// RecyclerView.SCROLL_STATE_DRAGGING -> { +// } +// +// RecyclerView.SCROLL_STATE_SETTLING -> { +// } +// } +// } +// +// override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { +// super.onScrolled(recyclerView, dx, dy) +// commandHandler.removeCallbacks(hideListView) +// } +// } +// +// private fun queryNotice() { +// mNotificationResult = null +// clearJob(noticeJob) +// mNotificationResult = WorkersDb.getRealm().query().sort("postTime", Sort.DESCENDING).find() +// noticeJob = CoroutineScope(Dispatchers.Default).launch { +// mNotificationResult?.asFlow()?.collect { changes: ResultsChange -> +// commandHandler.removeCallbacks(hideListView) +// when (changes) { +// is UpdatedResults -> { +// WorkersDb.getRealm().apply { +// lastedNoti = copyFromRealm(changes.list) +// } +// commandHandler.removeCallbacks(notiUpdate) +// commandHandler.postDelayed(notiUpdate, UPDATE_DELAY) +// } +// +// else -> { +// } +// } +// } +// } +// noticeJob?.start() +// } +// fun clearJob(job : Job?) { +// try { job?.cancel() } catch (e: Exception) { e.printStackTrace() } +// try { System.gc() } catch (e: Exception) { e.printStackTrace() } +// } +// fun beforeQuery() { +// clearJob(infosJob) +// mRssDataResult = null +// WorkersDb.getRealm().writeBlocking { +// delete( +// query() +// .query("pubDate < $0", beforeDay(30)) +// .query("category != $0 AND category != $1 ", RssDataType.GURU.name, RssDataType.MOST.name) +// .query("vote != $0", true).find() +// ) +// } +// } +// +// fun updateQuery(q: RealmQuery) { +// mRssDataResult = q.sort("pubDate ", Sort.DESCENDING).limit(300).distinct("originPage", "title").find() +// mRssDataResult?.asFlow()?.let { flow -> +// +// infosJob = CoroutineScope(Dispatchers.IO).launch { +// flow.collect { changes: ResultsChange -> +// commandHandler.removeCallbacks(hideListView) +// commandHandler.removeCallbacks(infoUpdate) +// WorkersDb.getRealm().apply { +// lasted = copyFromRealm(changes.list) +// } +// commandHandler.postDelayed(infoUpdate, UPDATE_DELAY) +// +// } +// } +// infosJob?.start() +// } +// +// +// +// } +// +// fun queryVotes() { +// beforeQuery() +// updateQuery(WorkersDb.getVotedRss()) +// } +// +// fun queryInfos( +// filter: Collection? = arrayListOf(RssDataType.GURU, RssDataType.MOST,RssDataType.REDDIT_NSFW), noLimit: Boolean = false +// ) { +// beforeQuery() +// var rQ = WorkersDb.getRealm().query().query("read < $0", nomoreShowCount).distinct("originPage", "title") +// if (!noLimit) rQ.query("pubDate > $0", beforeOneDay()) +// ((filter?.size ?: 0) > 0).letTrue {filter!!.forEach {rQ = rQ.query("category != $0", it.name)}} +// updateQuery(rQ) +// } +// +// fun queryInfos( +// keyword: String, +// category: ArrayList = arrayListOf(), +// noLimit: Boolean = false +// ) { +// beforeQuery() +// updateQuery(WorkersDb.getRssQuery(keyword,category,noLimit)) +// } +// +// +// +// override fun onViewCreated(view: View, savedInstanceState: Bundle?) { +// super.onViewCreated(view, savedInstanceState) +// +// +// PrefBoolean.displayDateTime.get().letTrue { +// binding.time.visibility = View.VISIBLE +// } +// +// +// PrefBoolean.displayBattery.get().letTrue { +// binding.batteryProgress.visibility = View.VISIBLE +// } +// +// binding.batteryProgress.setOnTouchListener(SimpleFingerGestures(context = requireContext(), binding.batteryProgress, mFingerGestureListener)) +// binding.root.setOnTouchListener(SimpleFingerGestures(context = requireContext(), binding.root, mFingerGestureListener)) +// binding.functionLayer.setOnTouchListener(SimpleFingerGestures(context = requireContext(), binding.functionLayer, mFingerGestureListener)) +// binding.time.setOnTouchListener(SimpleFingerGestures(context = requireContext(), binding.time, mFingerGestureListener)) +// +// Blog.LOGE("onViewCreated()") +// +// binding.summaryChoose.visibility = View.GONE +// (PrefBoolean.showCallHistory.get(false) || PrefBoolean.showSMSHistory.get(false) || PrefBoolean.showNotificationHistory.get(false) || PrefBoolean.showNewsHistory.get(false)).letTrue { +// binding.summaryChoose.visibility = View.VISIBLE +// binding.missedCalls.visibility = if (PrefBoolean.showCallHistory.get(false)) View.VISIBLE else View.GONE +// binding.recentSms.visibility = if (PrefBoolean.showSMSHistory.get(false)) View.VISIBLE else View.GONE +// binding.notice.visibility = if (PrefBoolean.showNotificationHistory.get(false)) View.VISIBLE else View.GONE +// binding.otherCheck.visibility = if (PrefBoolean.showNewsHistory.get(false)) View.VISIBLE else View.GONE +// } +// +// fragManager.addOnBackStackChangedListener { +// Blog.LOGE("addOnBackStackChangedListener()") +// shouldResume = if (fragManager.backStackEntryCount == 0) { +// binding.root.visibility = View.VISIBLE +// true +// } else { +// binding.root.visibility = View.GONE +// false +// } +// } +// +// var checkListner = object : View.OnClickListener { +// override fun onClick(v: View?) { +// commandHandler.removeCallbacks(hideListView) +// var views = arrayListOf(binding.mainList, binding.smsList, binding.infoList, binding.notiList,binding.appsList) +// var chechboxs = arrayListOf(binding.missedCalls, binding.recentSms, binding.otherCheck, binding.notice, binding.favApps) +// chechboxs.remove(v) +// when (v) { +// binding.missedCalls -> { +// binding.missedCalls.isSelected = !binding.missedCalls.isSelected +// if (binding.missedCalls.isSelected) { +// views.remove(binding.mainList) +// binding.mainList.visibility = View.VISIBLE +// } +// } +// +// binding.recentSms -> { +// binding.recentSms.isSelected = !binding.recentSms.isSelected +// if (binding.recentSms.isSelected) { +// views.remove(binding.smsList) +// binding.smsList.visibility = View.VISIBLE +// } +// } +// +// binding.otherCheck -> { +// if (binding.otherCheck.isSelected) { +// if (rssStateVote()) { +// queryInfos() +// } else { +// binding.otherCheck.isSelected = false +// } +// } else { +// queryInfos() +// binding.otherCheck.isSelected = true +// views.remove(binding.infoList) +// binding.infoList.scrollToPosition(0) +// binding.infoList.visibility = View.VISIBLE +// } +// } +// +// binding.notice -> { +// if (binding.notice.isSelected) { +// binding.notice.isSelected = false +// } else { +// queryNotice() +// binding.notice.isSelected = true +// views.remove(binding.notiList) +// binding.notiList.visibility = View.VISIBLE +// } +// } +// binding.favApps -> { +// if (binding.favApps.isSelected) { +// binding.favApps.isSelected = false +// } else { +// binding.favApps.isSelected = true +// views.remove(binding.appsList) +// binding.appsList.visibility = View.VISIBLE +// } +// } +// } +// chechboxs.forEach { it.isSelected = false } +// views.forEach { it.visibility = View.GONE } +// chooseAdpater() +// } +// } +// +// binding.otherCheck.setOnClickListener(checkListner) +// binding.recentSms.setOnClickListener(checkListner) +// binding.missedCalls.setOnClickListener(checkListner) +// binding.notice.setOnClickListener(checkListner) +// binding.favApps.setOnClickListener(checkListner) +// binding.otherCheck.setOnLongClickListener { +// queryInfos() +// true +// } +// enableSwipeToDeleteAndUndo() +// } +// +// +// +// fun searchData() { +// val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext()) +// builder.setTitle("Command Line") +// val viewInflated: View = LayoutInflater.from(context) +// .inflate(R.layout.search_layout, view as ViewGroup?, false) +// val input = viewInflated.findViewById(R.id.input) as EditText +// val categoryz = +// viewInflated.findViewById(R.id.categoryz) as TableRadioGroup +// categoryz.setMaxColumns(3) +// categoryz.setMaxRows(8) +// categoryz.setOnCheckedChangeListener(object : TableRadioGroup.OnCheckedChangeListener { +// override fun onCheckedChanged(group: TableRadioGroup?, checkedId: Int) { +// +// } +// }) +// var idx = 0 +// RssDataType.values().reversed().toList().chunked(3).forEach { +// var tb = TableRow(requireContext()) +// it.forEach { c -> +// if (c.equals(RssDataType.NO_DATA) == false) { +// tb.addView( +// CheckBox(requireContext()).apply { +// this.tag = c.name +// this.text = c.name +// } +// ) +// } +// } +// categoryz.addView(tb) +// } +// +// builder.setView(viewInflated) +// builder.setPositiveButton(android.R.string.ok, +// DialogInterface.OnClickListener { dialog, which -> +// dialog.dismiss() +// var category = arrayListOf() +// categoryz.children.forEach { +// if (it is TableRow) { +// it.children.forEach { +// if (it is CheckBox && it.isChecked) { +// (it.tag as? String)?.let { category.add(it) } +// } +// } +// } +// } +// queryInfos(keyword = input.text.toString(), category, false) +// }) +// builder.setNegativeButton(android.R.string.cancel, +// DialogInterface.OnClickListener { dialog, which -> dialog.cancel() }) +// builder.show() +// } +// +// +// fun showAl() { +// binding.alcholKatalkT.visibility = View.VISIBLE +// binding.alcholKatalkT.setOnClickListener { +// openSearchApps( +// "kakaot://taxi?dest_lat=${URLEncoder.encode("37.467696")}&dest_lng=${ +// URLEncoder.encode( +// "127.101063" +// ) +// }", "com.kakao.taxi" +// ) +// } +// +// } +// +// fun openSearchApps(schemeString: String, pakage: String? = null) { +// val gmmIntentUri = Uri.parse(schemeString) +// val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri) +// pakage?.let { +// mapIntent.setPackage(pakage) +// } +// startActivity(mapIntent) +// } +// +// fun hideAl() { +// binding.alcholKatalkT.visibility = View.GONE +// binding.alcholKatalkT.setOnClickListener { +// +// } +// } +// +// fun chooseAdpater() { +// commandHandler.removeCallbacks(hideListView) +// var tabs = arrayOf(binding.missedCalls,binding.recentSms,binding.otherCheck,binding.notice,binding.favApps) +// fun unsel(view: View) { +// tabs.filter { +// it.equals(view) == false +// }.forEach { it.isSelected = false } +// } +// binding.mainList.visibility = View.INVISIBLE +// binding.smsList.visibility = View.INVISIBLE +// binding.infoList.visibility = View.INVISIBLE +// binding.notiList.visibility = View.INVISIBLE +// +// var dateParam = beforeDay(30).toString() +// if (binding.missedCalls.isSelected) { +// WorkersDb.getRealm().apply { +// val result = query().query("callDayTime >= $0", dateParam) +// .sort("callDayTime", Sort.DESCENDING).find() +// val list = copyFromRealm(result) +// binding.missedCalls.text = "통화 목록 [${list.size}]" +// binding.mainList.visibility = View.VISIBLE +// mRecentCallsAdapter.updateData(list) +// } +// } else if (binding.recentSms.isSelected) { +// WorkersDb.getRealm().apply { +// val result = query().query("rcvDate >= $0 OR pstDate >= $0 ", dateParam) +// .sort("rcvDate", Sort.DESCENDING).find() +// if (result.size > 0) { +// try { +// binding.recentSms.text = "문자 내역 [${result.size}]" +// binding.smsList.visibility = View.VISIBLE +// val list = copyFromRealm(result) +// mSmsLogsAdapter.updateData(list) +// +// } catch (e: Exception) { +// +// } +// } +// } +// } else if (binding.otherCheck.isSelected) { +// unsel(binding.otherCheck) +// binding.infoList.visibility = View.VISIBLE +//// binding.otherCheck.text = "글타래 [${lasted?.size ?: "-"}]" +// lasted?.let { mRssAdapter.updateData(it) } +// } else if (binding.notice.isSelected) { +// unsel(binding.notice) +// binding.notiList.visibility = View.VISIBLE +//// binding.notice.text = "알림 [${lastedNoti?.size ?: "-"}]" +// lastedNoti?.let { mNotiAdapter.updateData(it) } +// } else if (binding.favApps.isSelected) { +// unsel(binding.favApps) +// binding.appsList.visibility = View.VISIBLE +// } +// commandHandler.postDelayed(hideListView, hideListViewTime) +// } +// +// private fun enableSwipeToDeleteAndUndo() { +// val swipeToDeleteCallback: SwipeToDeleteCallback = +// object : SwipeToDeleteCallback(requireContext()) { +// override fun onSwiped(@NonNull viewHolder: RecyclerView.ViewHolder, direction: Int) { +// Blog.LOGE("onSwiped direction >>>> $direction") +// (viewHolder.itemView.tag as? RssData)?.let { rss -> +// CoroutineScope(Dispatchers.IO).launch { +// WorkersDb.getRealm().apply { +// writeBlocking { +// when (direction) { +// ItemTouchHelper.LEFT -> { +// if (rssStateVote() && rss.vote) { +// rss.vote = false +// rss.read = 0 +// } else { +// rss.read += nomoreShowCount +// } +// query( +// "originPage == $0", +// rss.originPage +// ).find().forEach { it -> +// it.read += nomoreShowCount +// } +// } +// +// ItemTouchHelper.RIGHT -> { +// if (rssStateVote() && rss.vote) { +// rss.vote = false +// rss.read = 0 +// } else { +// rss.vote = true +// +// } +// } +// +// else -> {} +// } +// binding.infoList.post { mRssAdapter.refresh() } +// } +// } +// } +// } +// } +// } +// +// val itemTouchhelper = ItemTouchHelper(swipeToDeleteCallback) +// itemTouchhelper.attachToRecyclerView(binding.infoList) +// } +// +// override fun onResume() { +// super.onResume() +//// BLog.LOGE("${this} ::::: onResume >>>> ") +// if (shouldResume) { +// +// /* register battery changes */ +// requireContext().registerReceiver( +// batteryReceiver, +// IntentFilter(Intent.ACTION_BATTERY_CHANGED) +// ) +// /* time and date */ +//// binding.time.textLocale = Locale.US +//// binding.date.textLocale = Locale.US +//// if (DateFormat.is24HourFormat(requireContext())) { +//// binding.time.format24Hour = timeFormat +//// binding.date.format24Hour = "yyyy년 M월 W주차, dd일 E요일" +//// } else { +//// binding.time.format12Hour = timeFormat +//// binding.date.format12Hour = dateFormat +//// } +// /* show weather */ +//// WeatherExecutor(settingsPrefs).generateWeatherString(binding.weather) +// } +//// binding.root.visibility = View.VISIBLE +// } +// +// +// override fun onPause() { +// super.onPause() +// /* unregister battery changes */ +// if (shouldResume) requireContext().unregisterReceiver(batteryReceiver) +//// binding.root.visibility = View.GONE +// } +// +// +// var mFingerGestureListener = object : SimpleFingerGestures.OnFingerGestureListener { +// override fun onSwipeUp( +// targetView: View, +// fingers: Int, +// gestureDuration: Long, +// gestureDistance: Double +// ): Boolean { +// when (fingers) { +// 4 -> { +// lActivity!!.startActivity(Intent(requireContext(), Behavior::class.java)) +// } +// +// 3 -> QuickAccess().show(fragManager, BOTTOM_SHEET_TAG) +// 2 -> { +// var startIntene = Intent(Intent.ACTION_MAIN) +// startIntene.setComponent( +// ComponentName( +// "com.mime.dualscreenview", +// "com.mime.dualscreenview.activity.Intro" +// ) +// ) +// startActivity(startIntene) +// } +// 1->{ +// lActivity?.switchAppDrawer() +// } +// else -> {} +// } +// return false +// } +// +// override fun onSwipeDown( +// targetView: View, +// fingers: Int, +// gestureDuration: Long, +// gestureDistance: Double +// ): Boolean { +// when (fingers) { +// 2 -> +// if (targetView.equals(binding.batteryProgress)) { +// expandNotificationPanel(requireContext()) +// } else { +// expandNotificationPanel(requireContext()) +// } +// +// 4 -> { +// var startIntene = Intent(Intent.ACTION_MAIN) +// startIntene.setComponent( +// ComponentName( +// "com.samsung.android.app.interpreter", +// "com.samsung.android.app.interpreter.interpretation.view.InterpretationActivity" +// ) +// ) +// startActivity(startIntene) +// } +// +// 3 -> { +// lActivity!!.startActivity( +// Intent( +// requireContext(), +// SettingsActivity::class.java +// ) +// ) +// } +// +// else -> {} +// } +// return false +// } +// +// override fun onSwipeLeft( +// targetView: View, +// fingers: Int, +// gestureDuration: Long, +// gestureDistance: Double +// ): Boolean { +//// if (targetView.equals(binding.time)) { +//// val mClockIntent = Intent(AlarmClock.ACTION_SHOW_ALARMS) +//// mClockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) +//// startActivity(mClockIntent) +//// } +// +// Blog.LOGE("onSwipeLeft targetView. >>>> ${targetView} && ${targetView.equals(binding.functionLayer)}") +// if(targetView.equals(binding.functionLayer)){ +// targetView?.performHapticFeedback(HapticFeedbackConstants.CONFIRM) +// when(fingers) { +// 1->lActivity?.switchAppDrawer() +// 2-> { +// +// } +// else ->{} +// } +// } else if (targetView.equals(binding.time) && fingers == 2) { +// val mClockIntent = Intent(AlarmClock.ACTION_SHOW_ALARMS) +// mClockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) +// startActivity(mClockIntent) +// } +// return false +// } +// +// override fun onSwipeRight( +// targetView: View, +// fingers: Int, +// gestureDuration: Long, +// gestureDistance: Double +// ): Boolean { +// if(targetView.equals(binding.functionLayer)){ +// targetView?.performHapticFeedback(HapticFeedbackConstants.CONFIRM) +// when(fingers) { +// 1-> { +//// lActivity?.switchFeeds() +// return true +// } +// // +// else ->{} +// } +// } else if (targetView.equals(binding.time) && fingers == 2) { +// val intent = Intent(Intent.ACTION_MAIN) +// intent.addCategory(Intent.CATEGORY_APP_CALENDAR) +// startActivity(intent) +// } +// return false +// } +// +// override fun onPinch( +// targetView: View, +// fingers: Int, +// gestureDuration: Long, +// gestureDistance: Double +// ): Boolean { +// Blog.LOGE("Maybe GA PINCH is Like Zoom out") +// return false +// } +// +// override fun onUnpinch( +// targetView: View, +// fingers: Int, +// gestureDuration: Long, +// gestureDistance: Double +// ): Boolean { +// Blog.LOGE("Maybe GA UN PINCH is Like Zoom In") +// return false +// } +// +// override fun onDoubleTap(targetView: View, fingers: Int): Boolean { +// targetView?.performHapticFeedback(HapticFeedbackConstants.CONFIRM) +// when (fingers) { +// 1 -> lockMethod(settingsPrefs.getInt(KEY_LOCK_METHOD, 0), requireContext(), binding.functionLayer) +// else -> { +// +// } +// } +// return false +// } +// +// override fun onLongPress(targetView: View, fingers: Int): Boolean { +// if (targetView?.equals(binding.batteryProgress) == true) { +// lActivity!!.startActivity(Intent(requireContext(), SettingsActivity::class.java)) +// } else if (targetView?.equals(binding.mainList) == true) { +//// when (settingsPrefs.getBoolean(KEY_TODO_LOCK, false)) { +//// false -> launchTodoManager() +//// /* show authentication screen if lock is on */ +//// true -> { +//// if (canAuthenticate(requireContext())) { +//// val biometricPrompt = +//// BiometricPrompt(lActivity!!, authenticationCallback) +//// try { +//// biometricPrompt.authenticate( +//// biometricPromptInfo( +//// lActivity!!.getString( +//// R.string.todo_manager +//// ) +//// ) +//// ) +//// } catch (exception: Exception) { +//// exception.printStackTrace() +//// } +//// } +//// } +//// } +// } else if (targetView?.equals(binding.functionLayer) == true) { +// targetView?.performHapticFeedback(HapticFeedbackConstants.CONFIRM) +// if(binding.otherCheck.isSelected && rssStateVote()) { +// queryInfos() +// } else { +// binding.otherCheck.isSelected = true +// queryVotes() +// } +// return true +// } +// return false +// } +// +// override fun onClick(targetView: View, fingers: Int): Boolean { +//// BLog.LOGE("onClick ${view} , fingers ${fingers}") +// targetView.performHapticFeedback(HapticFeedbackConstants.CONFIRM) +// when (fingers) { +// 1 -> { +// if (targetView.equals(binding.batteryProgress) == true) { +// startActivity(Intent(Settings.ACTION_SETTINGS)) +// }else if(targetView.equals(binding.functionLayer)) { +// if (binding.otherCheck.isSelected) { +// searchData() +// } +//// else if (binding.otherCheck.isSelected) { +//// searchData() +//// } +//// else if (binding.otherCheck.isSelected) { +//// searchData() +//// } +//// else if (binding.otherCheck.isSelected) { +//// searchData() +//// } +//// else if (binding.otherCheck.isSelected) { +//// searchData() +//// } +// else { +//// QuickAccess().show(fragManager, BOTTOM_SHEET_TAG) +// } +// } +// } +// +// 2 -> { +// lockMethod( +// settingsPrefs.getInt(KEY_LOCK_METHOD, 0), +// requireContext(), +// binding.functionLayer +// ) +// } +// +// else -> { +// +// } +// } +// +// return true +// } +// +// } +// +// +// fun jsonObjLog(pkey: String, key: String, jsonObject: JSONObject) { +// if (jsonObject.has(key) == true && jsonObject.get(key) is String) { +// Blog.LOGE("jsonObjLog $pkey String in $key >> ${jsonObject.getString(key)}") +// } else if (jsonObject.has(key) == true && jsonObject.get(key) is JSONObject) { +// var obj = jsonObject.getJSONObject(key) +// Blog.LOGE("jsonObjLog $pkey JSONObject in $key >> ${obj}") +// obj?.keys()?.forEach { +//// jsonObjLog(key,it, obj) +// } +// } else if (jsonObject.has(key) == true && jsonObject.get(key) is JSONArray) { +// Blog.LOGE("jsonObjLog $pkey JSONArray in $key >> ${jsonObject.getJSONArray(key)}") +// var array = jsonObject.getJSONArray(key) +// for (i in 0..<(array?.length() ?: 0)) { +// if (array?.get(i) is String) { +// +// } else if (array?.get(i) is JSONObject) { +// var child = array.getJSONObject(i) +// child?.keys()?.forEach { +//// jsonObjLog(key, it, child) +// } +// } else if (array?.get(i) is JSONArray) { +// Blog.LOGE("jsonObjLog $pkey JSONArray in $key >> ${array.getJSONArray(i)}") +// } +// } +// } else { +// Blog.LOGE( +// "jsonObjLog $pkey else in $key >> ${ +// if (jsonObject.has(key) == true) (jsonObject.get( +// key +// )) else ("") +// }" +// ) +// } +// } +// +// +// /* gestures on root view */ +// @SuppressLint("ClickableViewAccessibility") +// private fun rootViewGestures() { +// binding.root.setOnTouchListener( +// SimpleFingerGestures( +// context = requireContext(), +// binding.root, +// mFingerGestureListener +// ) +// ) +// } +// +// +// +// /* gestures on to-do area */ +// @SuppressLint("ClickableViewAccessibility") +// private fun todosGestures() { +// binding.mainList.setOnTouchListener( +// SimpleFingerGestures( +// context = requireContext(), +// binding.mainList, +// mFingerGestureListener +// ) +// ) +// } +// +// +// +// /* authentication callback for TodoManager lock */ +// private val authenticationCallback = object : BiometricPrompt.AuthenticationCallback() { +// override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { +// launchTodoManager() +// } +// +// override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { +// Toast.makeText( +// requireContext(), +// lActivity!!.getString(R.string.authentication_error), +// Toast.LENGTH_SHORT +// ).show() +// } +// +// override fun onAuthenticationFailed() { +// Toast.makeText( +// requireContext(), +// lActivity!!.getString(R.string.authentication_failed), +// Toast.LENGTH_SHORT +// ).show() +// } +// } +// +// /* launch TodoManager fragment */ +// private fun launchTodoManager() { +//// fragManager.beginTransaction().replace(R.id.mainFragmentsContainer, TodoManager()) +//// .addToBackStack("").commit() +// } +// +// +// /* get time format string */ +// private val timeFormat: String +// get() { +//// when (settingsPrefs.getInt(KEY_TIME_FORMAT, 0)) { +//// 0 -> return if (DateFormat.is24HourFormat(requireContext())) { +//// "kk:mm" +//// } else { +//// "HH:mm a" +//// } +//// 1 -> return "HH:mm a" +//// 2 -> return "kk:mm" +//// } +// return "a HH : mm" +// } +// +// /* get date number suffix */ +// private val dateNumberSuffix: String +// get() { +// return when (Calendar.getInstance()[Calendar.DAY_OF_MONTH]) { +// 1, 21, 31 -> "ˢᵗ" +// 2, 22 -> "ⁿᵈ" +// 3, 23 -> "ʳᵈ" +// else -> "ᵗʰ" +// } +// } +// +// /* get date format string */ +// private val dateFormat: String +// get() { +//// settingsPrefs.getString(KEY_DATE_FORMAT, DEFAULT_DATE_FORMAT).let { +//// return if (it!!.contains("x")) { +//// it.replace("x", dateNumberSuffix) +//// } else { +//// it +//// } +//// } +// return "yyyy년 M월 W주차, dd일 E요일" +// } +// +//} +// +// +// +// diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/RssViewerActivity.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/RssViewerActivity.kt index 619485e5..a6298a9e 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/RssViewerActivity.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/RssViewerActivity.kt @@ -2,15 +2,11 @@ package bums.lunatic.launcher.home import android.content.ClipData import android.content.ClipboardManager -import android.content.ComponentName import android.content.Context import android.content.Intent -import android.net.Uri import android.os.Bundle import android.print.PDFPrint -import android.provider.AlarmClock import android.util.Base64 -import android.view.HapticFeedbackConstants import android.view.KeyEvent import android.view.KeyEvent.ACTION_UP import android.view.KeyEvent.KEYCODE_BUTTON_A @@ -29,28 +25,15 @@ import android.view.View import android.webkit.CookieManager import android.webkit.CookieSyncManager import android.webkit.JavascriptInterface -import android.webkit.ValueCallback import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.core.net.toUri 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.RssData -import bums.lunatic.launcher.qaccess.QuickAccess -import bums.lunatic.launcher.settings.SettingsActivity import bums.lunatic.launcher.utils.Blog -import bums.lunatic.launcher.utils.SimpleFingerGestures 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.realmListOf import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/RssItemAdapter.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/RssItemAdapter.kt index 54c8a895..7f71f5bb 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/RssItemAdapter.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/RssItemAdapter.kt @@ -21,6 +21,7 @@ package bums.lunatic.launcher.home.adapters import android.annotation.SuppressLint import android.content.Context import android.view.LayoutInflater +import android.view.MotionEvent import android.view.View import android.view.ViewGroup 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.RssDataType import bums.lunatic.launcher.openClient -import bums.lunatic.launcher.openDotax import bums.lunatic.launcher.openReddit import bums.lunatic.launcher.openYouTube +import bums.lunatic.launcher.tokiz.view.JxEvent import bums.lunatic.launcher.utils.Blog +import bums.lunatic.launcher.utils.SimpleFingerGestures import bums.lunatic.launcher.workers.WorkersDb import com.google.android.material.imageview.ShapeableImageView -import com.google.gson.Gson import com.squareup.picasso.Picasso -import kr.lunaticbum.awesomewebview.AwesomeWebView import io.realm.kotlin.UpdatePolicy import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kr.lunaticbum.awesomewebview.listeners.WebViewListener import java.text.SimpleDateFormat @@ -56,7 +55,8 @@ import java.util.Date internal class RssItemAdapter ( - private val context: Context) : RecyclerView.Adapter() { + private val context: Context, + private val dateViewClick : View.OnClickListener) : RecyclerView.Adapter() { companion object { @SuppressLint("SimpleDateFormat") 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(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().apply { - var jjjj = hashSetOf() - 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().apply { - var jjjj = hashSetOf() - 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().apply { - var jjjj = hashSetOf() - jjjj.addAll(rssList) - this.addAll(jjjj) - }) - .setRssId(rss.originPage()) - .showIconClose(true).showIconBack(false).showProgressBar(true).webViewMixedContentMode(0) - .show(rss.originPage!!) - } - } - } - } + private var rssDataItemLis: ArrayList = arrayListOf() val mLongClickListener = View.OnLongClickListener { v -> (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) { val rssData = rssDataItemLis[position] if (rssData.pubDate() > 1000L) { @@ -176,9 +195,6 @@ internal class RssItemAdapter ( 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.desc.text = rssData.description() @@ -198,6 +214,19 @@ internal class RssItemAdapter ( holder.itemView.tag = rssData 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 { // WorkersDb.getRealm().apply { // copyFromRealm(rss) diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/WeatherHourlyAdater.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/WeatherHourlyAdater.kt index f433f3df..dde6ccf6 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/WeatherHourlyAdater.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/adapters/WeatherHourlyAdater.kt @@ -7,7 +7,6 @@ import androidx.recyclerview.widget.RecyclerView import bums.lunatic.launcher.databinding.ItemHourlyWeatherBinding import bums.lunatic.launcher.model.Hour import bums.lunatic.launcher.model.WeatherInfoManager -import bums.lunatic.launcher.utils.Blog import com.squareup.picasso.Picasso class WeatherHourlyAdapter(private val dataSet: ArrayList): RecyclerView.Adapter() { diff --git a/app/src/main/kotlin/bums/lunatic/launcher/model/Adults.kt b/app/src/main/kotlin/bums/lunatic/launcher/model/Adults.kt index f390bf92..24896f1f 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/model/Adults.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/model/Adults.kt @@ -1,8 +1,6 @@ package bums.lunatic.launcher.model -import bums.lunatic.launcher.beforeDay import bums.lunatic.launcher.utils.JamoUtils -import java.util.Date class MostItem : JGuru , RssDataInterface { diff --git a/app/src/main/kotlin/bums/lunatic/launcher/model/UserActionModel.kt b/app/src/main/kotlin/bums/lunatic/launcher/model/UserActionModel.kt index 94d5f9a7..f0596646 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/model/UserActionModel.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/model/UserActionModel.kt @@ -1,9 +1,6 @@ package bums.lunatic.launcher.model -import com.ibm.icu.util.ChineseCalendar import io.realm.kotlin.types.RealmObject -import java.util.Calendar -import java.util.Date class UserActionModel: RealmObject { diff --git a/app/src/main/kotlin/bums/lunatic/launcher/receiver/NLService.kt b/app/src/main/kotlin/bums/lunatic/launcher/receiver/NLService.kt index ee2f1666..07212a82 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/receiver/NLService.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/receiver/NLService.kt @@ -15,7 +15,6 @@ import androidx.annotation.RequiresApi import androidx.core.content.getSystemService import bums.lunatic.launcher.model.CurrentPlayItem import bums.lunatic.launcher.model.NotificationItem -import bums.lunatic.launcher.utils.Blog import bums.lunatic.launcher.utils.BitmapConverter import bums.lunatic.launcher.workers.WorkersDb import io.realm.kotlin.UpdatePolicy diff --git a/app/src/main/kotlin/bums/lunatic/launcher/settings/childs/Apps.kt b/app/src/main/kotlin/bums/lunatic/launcher/settings/childs/Apps.kt index aa687c9f..4e58dc3a 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/settings/childs/Apps.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/settings/childs/Apps.kt @@ -28,7 +28,6 @@ import android.view.ViewGroup import bums.lunatic.launcher.R import bums.lunatic.launcher.databinding.SettingsAppsBinding import bums.lunatic.launcher.helpers.PrefBoolean -import bums.lunatic.launcher.helpers.PrefHelper import bums.lunatic.launcher.helpers.PrefLong import bums.lunatic.launcher.utils.Blog import com.google.android.material.bottomsheet.BottomSheetBehavior diff --git a/app/src/main/kotlin/bums/lunatic/launcher/settings/childs/WeatherSettings.kt b/app/src/main/kotlin/bums/lunatic/launcher/settings/childs/WeatherSettings.kt index 8cdaeb2c..fa7439a8 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/settings/childs/WeatherSettings.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/settings/childs/WeatherSettings.kt @@ -26,17 +26,11 @@ import android.view.ViewGroup import androidx.core.widget.doOnTextChanged import bums.lunatic.launcher.R import bums.lunatic.launcher.databinding.SettingsWeatherBinding -import bums.lunatic.launcher.helpers.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.PrefString -import bums.lunatic.launcher.settings.SettingsActivity.Companion.settingsPrefs import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.dialog.MaterialAlertDialogBuilder -import java.util.Objects import kotlin.system.exitProcess open class SettingChild : BottomSheetDialogFragment() { diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/Novels.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/Novels.kt new file mode 100644 index 00000000..e11ffda2 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/Novels.kt @@ -0,0 +1,1336 @@ +package bums.lunatic.launcher.tokiz + +import android.content.DialogInterface +import android.content.Intent +import android.content.pm.ActivityInfo +import android.content.res.Configuration +import android.graphics.Bitmap +import android.net.Uri +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.os.Message +import android.text.InputType +import android.text.SpannableStringBuilder +import android.text.style.RelativeSizeSpan +import android.util.Log +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import android.view.View.GONE +import android.view.View.OnTouchListener +import android.view.View.VISIBLE +import android.view.View.inflate +import android.view.ViewGroup +import android.webkit.WebView +import android.webkit.WebViewClient +import android.widget.ArrayAdapter +import android.widget.EditText +import android.widget.TextView +import android.widget.Toast +import androidx.appcompat.app.AlertDialog +import androidx.core.net.toUri +import androidx.core.view.isVisible +import androidx.fragment.app.Fragment +import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime +import bums.lunatic.launcher.R +import bums.lunatic.launcher.tokiz.common.PairArray +import bums.lunatic.launcher.tokiz.common.TouchArea +import bums.lunatic.launcher.tokiz.common.colorz +import bums.lunatic.launcher.tokiz.common.getIndex +import bums.lunatic.launcher.tokiz.common.typesfacez +import bums.lunatic.launcher.tokiz.data.HistoryManager +import bums.lunatic.launcher.tokiz.data.model.BookPageInfo +import bums.lunatic.launcher.tokiz.data.model.BookPageInfos +import bums.lunatic.launcher.tokiz.data.model.BookPageInfosJ +import bums.lunatic.launcher.tokiz.data.model.HistoryItem +import bums.lunatic.launcher.tokiz.data.model.LastInfo +import bums.lunatic.launcher.tokiz.data.model.PortMessage +import bums.lunatic.launcher.tokiz.data.model.ReaderConfig +import bums.lunatic.launcher.tokiz.dialog.DefaultList +import bums.lunatic.launcher.tokiz.view.JxEvent +import bums.lunatic.launcher.tokiz.view.PagedTextLayout +import bums.lunatic.launcher.tokiz.view.PagedTextViewInterface +import bums.lunatic.launcher.tokiz.webcontents.contentsinfo.BooktokiStruct.getLastedDoamin +import bums.lunatic.launcher.tokiz.webcontents.contentsinfo.BooktokiStruct.getWebcontentsName +import bums.lunatic.launcher.databinding.BooktokiBinding +import bums.lunatic.launcher.utils.Blog +import com.google.gson.Gson +import io.realm.kotlin.Realm +import io.realm.kotlin.UpdatePolicy +import io.realm.kotlin.ext.copyFromRealm +import io.realm.kotlin.ext.query +import org.json.JSONException +import org.json.JSONObject +import org.mozilla.gecko.util.ThreadUtils +import org.mozilla.geckoview.GeckoResult +import org.mozilla.geckoview.GeckoSession +import org.mozilla.geckoview.MediaSession +import org.mozilla.geckoview.WebExtension +import org.mozilla.geckoview.WebExtension.MessageDelegate +import org.mozilla.geckoview.WebExtension.PortDelegate +import org.mozilla.geckoview.WebExtensionController.AddonManagerDelegate +import org.mozilla.geckoview.WebRequestError +import java.lang.System.currentTimeMillis +import java.text.SimpleDateFormat +import java.util.Date +import kotlin.collections.ArrayList +import kotlin.collections.List +import kotlin.collections.MutableList +import kotlin.collections.arrayListOf +import kotlin.collections.first +import kotlin.collections.isNotEmpty +import kotlin.collections.last +import kotlin.collections.sortBy +import kotlin.random.Random +import kotlin.text.contains +import kotlin.text.endsWith +import kotlin.text.equals +import kotlin.text.replace +import kotlin.text.split +import kotlin.text.startsWith +import kotlin.text.toInt +import kotlin.text.toRegex +import kotlin.text.trim + + +class Novels : Fragment(), PagedTextViewInterface { + fun openRealm() : Realm = HistoryManager.openRealm + var lastInfo: LastInfo? = null + var currentBooinfo: BookPageInfo? = null + + val handle = object : Handler(Looper.getMainLooper()) { + override fun handleMessage(msg: Message) { + if (msg.what == 0) { + (msg.obj as? ReaderConfig)?.let { + } + } + } + } + + + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + Blog.LOGD(log = "onConfigurationChanged ${this::class.java.name} >> newConfig ${newConfig}") + } + + var lastedUrl: String? = null + var canGoBack: Boolean? = null + lateinit var binding: BooktokiBinding + + var mPort: WebExtension.Port? = null + val mPortNam = "browser" + val extPath = "resource://android/assets/extensions/my_extension/" + val extId = "messaging@booktoki468.com" + var mExtension: WebExtension? = null + + val OnTouchListener = object : OnTouchListener { + + override fun onTouch(v: View?, event: MotionEvent): Boolean { + when (event.getAction()) { + MotionEvent.ACTION_DOWN -> { + handle.removeCallbacks(mActionUp) + handle.removeCallbacks(mActionDown) + if(!binding.pagedLayer.isVisible) { + + } + } + + MotionEvent.ACTION_UP -> { + handle.removeCallbacks(mActionUp) + handle.removeCallbacks(mActionDown) + } + } + return false + } + + var mActionDown: Runnable = object : Runnable { + override fun run() { + sendScrollDown(false) + handle.postDelayed(this, 150) + } + } + var mActionUp: Runnable = object : Runnable { + override fun run() { + sendScrollDown(true) + handle.postDelayed(this, 150) + } + } + } + + + + var mOnGenericMotionListener = object : View.OnGenericMotionListener{ + override fun onGenericMotion( + v: View?, + event: MotionEvent? + ): Boolean { + Blog.LOGE("event >>>> $event") + return true + } + } + + val addonManagerDelegate = object : AddonManagerDelegate { + override fun onReady(extension: WebExtension) { + Blog.LOGE("onReady ${extension.id} from WebExtension") +// extension?.setMessageDelegate(messageDelegate, mPortNam) +// sRuntime!!.webExtensionController.enable(extension,EnableSource.USER) + mExtension = extension + + } + + override fun onEnabling(extension: WebExtension) { + Blog.LOGE("onEnabling ${extension.id} from WebExtension") + } + + override fun onEnabled(extension: WebExtension) { + Blog.LOGE("onEnabled ${extension.id} from WebExtension") +// extension?.setMessageDelegate(messageDelegate, mPortNam) + mExtension = extension + + } + } + val mediaDelegate = object : GeckoSession.MediaDelegate { + override fun onRecordingStatusChanged( + session: GeckoSession, + devices: Array + ) { + super.onRecordingStatusChanged(session, devices) + } + } + val mediaSessionDelegate = object : MediaSession.Delegate { + override fun onActivated( + session: GeckoSession, + mediaSession: MediaSession + ) { + super.onActivated(session, mediaSession) + } + + override fun onDeactivated( + session: GeckoSession, + mediaSession: MediaSession + ) { + super.onDeactivated(session, mediaSession) + } + + override fun onMetadata( + session: GeckoSession, + mediaSession: MediaSession, + meta: MediaSession.Metadata + ) { + super.onMetadata(session, mediaSession, meta) + } + + override fun onFeatures( + session: GeckoSession, + mediaSession: MediaSession, + features: Long + ) { + super.onFeatures(session, mediaSession, features) + } + + override fun onPlay( + session: GeckoSession, + mediaSession: MediaSession + ) { + super.onPlay(session, mediaSession) + } + + override fun onPause( + session: GeckoSession, + mediaSession: MediaSession + ) { + super.onPause(session, mediaSession) + } + + override fun onStop( + session: GeckoSession, + mediaSession: MediaSession + ) { + super.onStop(session, mediaSession) + } + + override fun onPositionState( + session: GeckoSession, + mediaSession: MediaSession, + state: MediaSession.PositionState + ) { + super.onPositionState(session, mediaSession, state) + } + + override fun onFullscreen( + session: GeckoSession, + mediaSession: MediaSession, + enabled: Boolean, + meta: MediaSession.ElementMetadata? + ) { + super.onFullscreen(session, mediaSession, enabled, meta) + } + } + + val contentDelegate = object : GeckoSession.ContentDelegate { + + } + val progressDelegate = object : GeckoSession.ProgressDelegate { + override fun onSecurityChange( + session: GeckoSession, + securityInfo: GeckoSession.ProgressDelegate.SecurityInformation + ) { + Blog.LOGE("onSecurityChange $securityInfo from WebExtension") + super.onSecurityChange(session, securityInfo) + } + + override fun onSessionStateChange( + session: GeckoSession, + sessionState: GeckoSession.SessionState + ) { + Blog.LOGE("onSessionStateChange $sessionState from WebExtension") + super.onSessionStateChange(session, sessionState) + } + + override fun onPageStart(session: GeckoSession, url: String) { + super.onPageStart(session, url) + binding.progress.visibility = VISIBLE + } + + override fun onPageStop(session: GeckoSession, success: Boolean) { + Blog.LOGE("onPageStop $success from WebExtension") + super.onPageStop(session, success) + if (success && mPort != null) { + if (mPort == null) { + // No extension registered yet, let's ignore this message + return + } + binding.menuWeb.postDelayed({ + Blog.LOGE("onPageStop $success from WebExtension ${mPort!!.name}") + val message: JSONObject = JSONObject() + try { + message.put("type", "getList") + message.put("event", "sadsadds") + message.put("tab", session.settings.screenId) + } catch (ex: JSONException) { + throw RuntimeException(ex) + } + + mPort!!.postMessage(message) +// binding.progress.visibility = GONE + }, 10L) +// completePageLoad(LastInfo().apply { +// this.pageUrl = lastedUrl?.toUri()?.path ?: getLastedDoamin() ?: "" +// this.contentsName = getWebcontentsName() ?: "" +// this.pageIndex = 0 +// }) + } + } + } + val navigationDelegate = object : GeckoSession.NavigationDelegate { + override fun onLoadError( + session: GeckoSession, + uri: String?, + error: WebRequestError + ): GeckoResult? { + error.printStackTrace() + Blog.LOGE("onLoadError >>> ${uri} ::>> ${error.category} , ${error.code}") + if (error.code == WebRequestError.ERROR_NET_RESET) { + session.loadUri("https://naver.com") + } + return super.onLoadError(session, uri, error) + } + + override fun onNewSession( + session: GeckoSession, + uri: String + ): GeckoResult? { + Blog.LOGE("GeckoView", "onNewSession: $session from WebExtension") + + + return super.onNewSession(session, uri) + } + + override fun onLocationChange( + session: GeckoSession, + url: String?, + perms: MutableList, + hasUserGesture: Boolean + ) { + if (url?.startsWith("about") ?: true) { + + } else { + // url이 현재 로드된 주소입니다. + Blog.LOGE("GeckoView", "현재 주소: $url") + Blog.LOGE("GeckoView", "현재 session: $session") + url?.let { url -> + if (url.split("//").size > 1) { + url.replace("//", "/").replace("https:/", "https://").let { + Blog.LOGE("url >> ${url} , it >>> ${it}") + lastedUrl = url + } + } else { + lastedUrl = url + } + } + completePageLoad(LastInfo().apply { + this.pageUrl = url?.toUri()?.path ?: getLastedDoamin() ?: "" + this.contentsName = getWebcontentsName() ?: "" + this.pageIndex = 0 + }) + } + } + + override fun onCanGoBack(session: GeckoSession, canGoBack: Boolean) { + super.onCanGoBack(session, canGoBack) + this@Novels.canGoBack = canGoBack + if (canGoBack) { + + } + } + + } + val portDelegate: PortDelegate = object : PortDelegate { + + override fun onPortMessage( + message: Any, port: WebExtension.Port + ) { + Blog.LOGE("PortDelegate", "Received message from extension: $message") + if (message is String && message.contains("type")) { + try { + var lPortMessage = + Gson().fromJson(message, PortMessage::class.java) + when(lPortMessage.type) { + "getListResult" -> { + lPortMessage.bookInfos?.let { onBookInfos(it) } + } + "BookContents"->{ + lPortMessage?.book?.chapterTitle?.let { onFindTitle(it) } + lPortMessage?.book?.bookContents?.let { onLoadedContents(it) } + } + "NotRegistered" -> { + binding.pagedLayer.visibility = GONE + } + "WebtoonContents"-> { + binding.pagedLayer.visibility = GONE + } + "MSG" -> { + lPortMessage.msg?.let { Toast.makeText(requireContext(),it, Toast.LENGTH_SHORT).show() } + } + else -> { + + } + } + binding.progress.visibility = GONE + } catch (e: Exception) { + e.printStackTrace() + } + + } + } + + + override fun onDisconnect(port: WebExtension.Port) { + // This port is not usable anymore. + if (port === mPort) { + mPort = null + } + } + } + val messageDelegate: MessageDelegate = object : MessageDelegate { + override fun onConnect(port: WebExtension.Port) { + mPort = port + mPort!!.setDelegate(portDelegate) + } + + override fun onMessage( + nativeApp: String, + message: Any, + sender: WebExtension.MessageSender + ): GeckoResult? { + Blog.LOGE( + "messageDelegate", + "onMessage from WebExtension: ${nativeApp} , $message , ${sender.webExtension.id}" + ) + return super.onMessage(nativeApp, message, sender) + } + + + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + Blog.LOGD(log = "onCreate ${this::class.java.name} >> savedInstanceState ${savedInstanceState}") + binding = BooktokiBinding.inflate(inflater) + binding.menuWeb.let { + it.setOnLongClickListener { + onTouch(TouchArea.Center) + return@setOnLongClickListener false + } + it.setOnGenericMotionListener(mOnGenericMotionListener) + } + + binding.btnList.setOnClickListener { v -> + lastedUrl?.let { + Uri.parse(it).path?.let { + HistoryManager.getBookInfos(it, { + it?.let { + it.pages.sortBy { it.pathUrl } + showList(it) + } + }) + } + } + } + + + binding.btnSetting.setOnClickListener { v -> + activity?.startActivity(Intent(requireContext(), Settings::class.java)) + } + binding.btnHistory.setOnClickListener { v -> + var realm = openRealm() + realm.query().find().let { + showHistory(realm.copyFromRealm(it)) + } + } + binding.btnHome.setOnClickListener { v -> + binding.pagedLayer.visibility = GONE + goToHome() + } + getRuntime()?.apply { + val session: GeckoSession = GeckoSession() + session.open(this) + binding.menuWeb.setSession(session) + binding.menuWeb.jxInteface = { jxEvent -> + when(jxEvent) { + JxEvent.SCROLL_UP -> sendScrollDown(true) + JxEvent.SCROLL_DOWN -> sendScrollDown(false) + else -> {} + } + } + session.contentDelegate = contentDelegate + session.progressDelegate = progressDelegate + session.navigationDelegate = navigationDelegate + this.webExtensionController.setAddonManagerDelegate(addonManagerDelegate) + session.mediaDelegate = mediaDelegate + session.mediaSessionDelegate = mediaSessionDelegate + this.webExtensionController + .ensureBuiltIn(extPath, extId) + .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) }) + loadLastInfo() + } + return binding.root + } + override fun onStart() { + super.onStart() + } + + override fun onResume() { + super.onResume() + loadLastInfo() + } + + fun loadLastInfo() { + var targetUrl = getLastedDoamin() + val realm = openRealm() + try { + lastInfo = realm.query().find().last()?.copyFromRealm() + HistoryManager.openRealm.query()?.find()?.let { + if (it.size > 0) { + realm.copyFromRealm(it.first()).let { + applyReaderConfig() + } + } + } + lastInfo?.let { lastInfo -> + Blog.LOGE("lastInfo >>> ${lastInfo} path ::> ${lastInfo!!.pageUrl}") + HistoryManager.getBookPageInfo(lastInfo.pageUrl) { + it?.let { + currentBooinfo = it + Blog.LOGE("currentBooinfo :: ${currentBooinfo} ${currentBooinfo?.pathUrl}") + if ((currentBooinfo?.pathUrl?.length ?: 0) > 1) { + HistoryManager.save( + historyItem = HistoryItem().putHistory( + currentBooinfo, + currentBooinfo?.pathUrl ?: getLastedDoamin() + ) + ) + currentBooinfo?.pathUrl?.let { targetPath -> + if (targetPath.startsWith("http",true)) { + targetUrl = targetPath + } else { + targetUrl = getLastedDoamin() + targetPath + } + } + } + } + } + } ?: Blog.LOGE("lastInfo is Null") + } catch (e1: Exception) { + + } finally { + contentsLoad(targetUrl) + } + } + + + fun onBookInfos(aInfos: BookPageInfos) { + Blog.LOGE("onBookInfos(aInfos: ${aInfos})") + activity?.runOnUiThread { + showList(aInfos) + } + } + + fun onBookInfos(jsonString: String) { + Blog.LOGE("onBookInfos", "jsonString >> ${jsonString}") + val realm = openRealm() + var infos: BookPageInfos? = null + realm.writeBlocking { + try { + var infosj: BookPageInfosJ? = null + infosj = Gson().fromJson(jsonString, BookPageInfosJ::class.java) + HistoryManager.getBookInfos(infosj.bookPageUrl!!) { + if (it != null) { + + infos = copyToRealm(it!!, UpdatePolicy.ALL) + for (item in infosj.pages) { + if (infos!!.hasItem(item.getRealm()) == false) { + infos!!.pages.add(item.getRealm()) + } + } + if (infos != null) { + infos = this.copyFromRealm(infos!!) + } + } else { + infos = infosj?.getR() + if (infos != null) { + infos = copyToRealm(infos!!, UpdatePolicy.ALL) + for (item in infosj.pages) { + infos?.pages?.add(item.getRealm()) + } + } + if (infos != null) { + infos = this.copyFromRealm(infos!!) + } + } + } + + } catch (e: Exception) { + e.printStackTrace() + } finally { + infos?.bookPageUrl?.let { + HistoryManager.getBookInfos(it) { + it?.let { + Blog.LOGE(s(), "onBookInfos it >> ${it}") + activity?.runOnUiThread { showList(it) } + } + } + } + } + } + } + + fun onBookInfos(infosj: BookPageInfosJ) { + Blog.LOGE("onBookInfos", "jsonString >> ${infosj}") + val realm = openRealm() + var infos: BookPageInfos? = null + realm.writeBlocking { + try { + HistoryManager.getBookInfos(infosj.bookPageUrl!!) { + if (it != null) { + + infos = copyToRealm(it!!, UpdatePolicy.ALL) + for (item in infosj.pages) { + if (infos!!.hasItem(item.getRealm()) == false) { + infos!!.pages.add(item.getRealm()) + } + } + if (infos != null) { + infos = this.copyFromRealm(infos!!) + } + } else { + infos = infosj?.getR() + if (infos != null) { + infos = copyToRealm(infos!!, UpdatePolicy.ALL) + for (item in infosj.pages) { + infos?.pages?.add(item.getRealm()) + } + } + if (infos != null) { + infos = this.copyFromRealm(infos!!) + } + } + } + + } catch (e: Exception) { + e.printStackTrace() + } finally { + infos?.bookPageUrl?.let { + HistoryManager.getBookInfos(it) { + it?.let { + Blog.LOGE(s(), "onBookInfos it >> ${it}") + activity?.runOnUiThread { showList(it) } + } + } + } + } + } + } + + private fun s() = "onBookInfos" + + + fun showHistory(infos: List) { + + val builderSingle: AlertDialog.Builder = AlertDialog.Builder(requireContext()) + builderSingle.setTitle("${currentTitle} : ${currentChapter} -> Select One ") + val arrayAdapter = + ArrayAdapter(requireContext(), android.R.layout.select_dialog_singlechoice) + for (item in infos) { + arrayAdapter.addAll(item.title) + } + + builderSingle.setNegativeButton( + "cancel", + DialogInterface.OnClickListener { dialog, which -> dialog.dismiss() }) + + builderSingle.setAdapter( + arrayAdapter, + DialogInterface.OnClickListener { dialog, which -> + val strName = arrayAdapter.getItem(which) + val item = infos.get(which) + val builderInner: AlertDialog.Builder = AlertDialog.Builder(requireContext()) + builderInner.setMessage(strName) + builderInner.setTitle("${infos.get(which).title}로 이동 고고!?") + builderInner.setPositiveButton( + "Ok", + DialogInterface.OnClickListener { dialog, which -> + contentsLoad(item.pageUrl) + dialog.dismiss() + }) + builderInner.setNeutralButton( + "삭제", + DialogInterface.OnClickListener { dialog, which -> + var realm = openRealm() + realm?.writeBlocking { + this.query().query("title == '${item.title}'").find() + ?.last()?.let { + this.delete(it) + } + } + dialog.dismiss() + }) + builderInner.setNegativeButton( + "취소", + DialogInterface.OnClickListener { dialog, which -> + dialog.dismiss() + }) + builderInner.show() + }) + var ddddd = builderSingle.create() + ddddd.setOnShowListener { d -> + (d as? AlertDialog)?.let { + it.listView?.setSelection(currentChapter) + } + } + + ddddd.show() + } + + fun showList(infos: BookPageInfos) { + Blog.LOGE("showList infos >>>>${infos}") + if (infos != null && infos.pages.size ?: 0 > 0) { + var items: ArrayList = arrayListOf() + for (item in infos.pages) { + items.add(item) + } + + items.sortBy { it.chapterID } + + DefaultList.showDefaultList( + requireContext(), + "현제는 ${currentTitle} - ${currentChapter} -> 다른화를 골라", + items, + currentChapter, + { position -> + return@showDefaultList items?.get(position)?.chapterTitle ?: "" + }, + { position -> + items?.get(position)?.let { moveTo(it) } + }, { state -> + if (state < 0) { + saveContinuation = true + moveToNext(currentBooinfo?.pathUrl ?: lastedUrl?.toUri()?.path) + } + }) + } + } + + val String.cleanTextContent: String + get() { + // strips off all non-ASCII characters + var text = this + text = text.replace("[^\\x00-\\x7F]".toRegex(), "") + + // erases all the ASCII control characters + text = text.replace("[\\p{Cntrl}&&[^\r\n\t]]".toRegex(), "") + + // removes non-printable characters from Unicode + text = text.replace("\\p{C}".toRegex(), "") + return text.trim() + } + + + var saveClient = object : WebViewClient() { + override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { + super.onPageStarted(view, url, favicon) + + } + + override fun onPageFinished(webView: WebView?, url: String?) { + super.onPageFinished(webView, url) +// val delayed = 3500L + Math.abs(Random.nextLong().rem(9999L)) + finishedUrl = url ?: "" + webView?.postDelayed({ + webView?.evaluateJavascript( + "function getAll() {\n" + + " MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" + + " };getAll()" + ) { result -> + (result as? String)?.let { + + } + } + }, delayed) + } + + + } + + fun showToast(origin: String) { + activity?.runOnUiThread { + val toast = Toast(requireContext()) + toast.duration = Toast.LENGTH_SHORT + val biggerText = SpannableStringBuilder(origin) + biggerText.setSpan(RelativeSizeSpan(1.6f), 0, origin.length, 0) + val view: View = inflate(requireContext(), R.layout.simple_toast, null) + view.findViewById(R.id.text).text = biggerText + toast.view = view + toast.show() +// Toast.makeText( +// baseContext, +// biggerText, +// Toast.LENGTH_SHORT +// ).show() + } + } + + var delayed = 3500L + Math.abs(Random.nextLong().rem(9999L)) + var finishedUrl: String? = null + + private fun moveTo(item: BookPageInfo?) { + Blog.LOGE("item >>> ${item}") + item?.pathUrl?.let { newPath -> + contentsLoad(newPath) + } + } + + + fun moveToNext(pathUrl: String?) { + if (pathUrl != null && pathUrl.length > 6) { + HistoryManager.getNextPage(pathUrl) { + if (it != null && (it.pathUrl?.length ?: 0) > 6) { + moveTo(it) + } else { + showToast("다음 편이 없다요.") + } + } + } + } + + fun moveToPrev(pathUrl: String?) { + if (pathUrl != null && pathUrl.length > 6) { + HistoryManager.getPrevPage(pathUrl) { + if (it != null && (it.pathUrl?.length ?: 0) > 6) { + moveTo(it) + } else { + showToast("이전 편이 없다요.") + } + } + } + } + + fun contentsLoad(pathUrl: String) { + + fun applyCurrentBook(bookPageInfo: BookPageInfo) { + applyReaderConfig() + bookPageInfo.contents?.let { onLoadedContents(it) } + bookPageInfo.chapterTitle?.let { onFindTitle(it) } + if (bookPageInfo.pathUrl?.startsWith("http") == true) { + binding.menuWeb.loadUrl(pathUrl) + } else { + binding.menuWeb.loadUrl(getLastedDoamin() + bookPageInfo.pathUrl!!) + } + HistoryManager.save(HistoryItem().putHistory(bookPageInfo, bookPageInfo.pathUrl!!)) + } + + if (currentBooinfo?.pathUrl.equals(pathUrl)) { + applyCurrentBook(currentBooinfo!!) + } else { + HistoryManager.getBookPageInfo(pathUrl) { + Blog.LOGE("contentsLoad :::: pathUrl >> ${pathUrl} , book >> ${it}") + if (it != null && it.isValidBook()) { + currentBooinfo = it + applyCurrentBook(it) + } else if(lastInfo != null){ + binding.pagedLayer.visibility = GONE + binding.menuWeb.loadUrl(getLastedDoamin() + lastInfo!!.pageUrl) + } else { + binding.menuWeb.loadUrl(getLastedDoamin()) + } + } + } + } + + + fun actionNextEvent(fast: Boolean = false) { + if (binding.pagedLayer.isVisible && binding.pagedLayer.size() > 0 && (binding.pagedLayer.current() < binding.pagedLayer!!.size() - 1)) { + binding.pagedLayer.doNext(fast) + updateLastInfo(binding.pagedLayer!!) + } else { + moveToNext(currentBooinfo?.pathUrl ?: lastedUrl?.toUri()?.path) + } + } + + fun applyReaderConfig() { + var realm = HistoryManager.openRealm + realm.query().find().let { + if (it.isNotEmpty()) { + realm.copyFromRealm(it.first()).let { + activity?.runOnUiThread { + var typeface = + typesfacez.get(getIndex(typesfacez as PairArray, it.font ?: "")) + binding.pagedLayer.setTypeface(resources.getFont(typeface.second)) + val color = colorz.get(it.style ?: 0) + binding.pagedLayer.setColorStyle(color.second) + binding.pagedLayer.setTextSize(it.textSize?.toFloat() ?: 14f) + binding.pagedLayer.setLineSpacing(it.lineSpace?.toFloat() ?: 1f) + binding.pagedLayer.setLetterSpacing(it.letterSpace?.toFloat() ?: 1f) + binding.pagedLayer.setPadding( + it.padding ?: 1, + it.padding ?: 1, + it.padding ?: 1, + it.padding ?: 1 + ) + binding.pagedLayer.invalidate() + } + } + } + } + } + + fun actionPrevEvent(fast: Boolean = false) { + if (binding.pagedLayer.isVisible && binding.pagedLayer.size() > 0 && binding.pagedLayer.current() > 0) { + binding.pagedLayer.doPrev(fast) + updateLastInfo(binding.pagedLayer) + } else { + moveToPrev(currentBooinfo?.pathUrl ?: lastedUrl?.toUri()?.path) + } + } +// +// override fun onBackPressed() { +// +// +// +// if (binding.pagedLayer.isVisible) { +// didBackPress = false +// binding.pagedLayer.visibility = GONE +// onTouch(TouchArea.Center) +// return +// } +// +// if (canGoBack == true) { +// didBackPress = false +// canGoBack = false +// binding.menuWeb.session?.goBack() +// return +// } +// +// if (!didBackPress) { +// firstBackPress() +// return +// } else { +// Activity.finishAffinity() +// didBackPress = false +// super.onBackPressed() +// } +// } + + + + fun showAlert(alert: String) { + Log.i(TAG, "showAlert >> " + alert) + } + + + fun onLoadedContents(aContents: String) { + binding.pagedLayer.apply { + binding.pagedLayer.post { + if (aContents.length > 10) { + var contents = aContents.replace("\\\"", "\"") + contents = (contents.replace("\\n", System.getProperty("line.separator"))) +// contents = (contents.replace("\\n", System.getProperty("line.separator"))) + mPagedTextViewInterface = this@Novels + if (lastInfo != null && lastedUrl?.endsWith(lastInfo!!.pageUrl) == true) { + binding.progress.visibility = VISIBLE + binding.pagedLayer.postDelayed({ + binding.progress.visibility = GONE + }, 1000) + } + applyReaderConfig() + activity?.runOnUiThread { + text = contents + visibility = VISIBLE + } + forceUpdateUI() + lastedUrl?.let { + Uri.parse(it)?.let { + it.path?.let { + HistoryManager.getBookPageInfo(it) { + it?.let { + currentBooinfo = it + currentChapter = it?.chapterNum ?: 0 + currentPage = it?.chapterNum ?: 0 + HistoryManager.save( + historyItem = HistoryItem().putHistory( + it, + lastedUrl!! + ) + ) + } + } + } + HistoryManager.getBooPageInfoContentsSave(it!!.path!!, contents) + if (saveContinuation) { + binding.menuWeb.postDelayed({moveToNext(currentBooinfo?.pathUrl ?: lastedUrl?.toUri()?.path)}, 10000) + + } + } + } + } + + } + } +// Log.i(TAG, "onLoadedContents >> " + aContents) + } + + var currentTitle: String = "" + var currentChapter: Int = 0 + + fun onFindTitle(contents: String) { + binding.textviewTitle.text = contents + binding.textviewTitle.setOnClickListener { + val builder = AlertDialog.Builder(requireContext()) + builder.setTitle("Title") + val input = EditText(requireContext()) + input.setText(lastedUrl ?: "") + input.inputType = InputType.TYPE_CLASS_TEXT + builder.setView(input) + builder.setPositiveButton( + "OK" + ) { dialog, which -> + var m_Text = input.text.toString() + contentsLoad(m_Text.trim()) + } + builder.setNegativeButton( + "Cancel" + ) { dialog, which -> dialog.cancel() } + builder.show() + } + var testRegex = """[^0-9]""".toRegex() + Blog.LOGI(TAG, "onFindTitle >> " + contents + " ::: ${testRegex.replace(contents, "")}") + if (contents.contains("-")) { + currentTitle = contents.split("-")[0] + try { + currentChapter = testRegex.replace(contents.split("-")[1], "").toInt() + } catch (e: Exception) { + currentChapter = 0 + } + } else if (testRegex.replace(contents, "").length > 0) { + currentChapter = testRegex.replace(contents, "").toInt() + currentTitle = contents.split(testRegex.replace(contents, ""))[0] + } else { + val dateFormat = "yyyyMMdd-HH" + val date = Date(currentTimeMillis()) + val simpleDateFormat = SimpleDateFormat(dateFormat) + currentTitle = simpleDateFormat.format(date) + } + + } + + fun onStartLoad() { + binding.progress.visibility = VISIBLE + } + + fun completePageLoad(lastInfo: LastInfo) { + val configuration: Configuration = getResources().configuration + if (this.lastInfo == null || !(this.lastInfo?.pageUrl.equals(lastInfo?.pageUrl)) || this.lastInfo?.displayOrientation != configuration?.orientation) { + lastInfo.displayOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + saveLastInfo(lastInfo) + } + } + +// override fun onTouchEvent(event: MotionEvent?): Boolean { +// return super.onTouchEvent(event) +// if (saveContinuation) { +// saveContinuation = false +// } +// } + + fun saveLastInfo(lastInfo: LastInfo) { + val realm = openRealm() + if ((realm.query()?.count()?.find() ?: 0) > 0) { + realm.writeBlocking { + this.query()?.find()?.last()?.let { + it.pageUrl = lastInfo.pageUrl + it.title = currentTitle + it.chapter = currentChapter + it.pageIndex = lastInfo.pageIndex + it.contentsName = lastInfo.contentsName + it.displayOrientation = lastInfo.displayOrientation + this@Novels.lastInfo = copyFromRealm(it) + } + } + } else { + realm.writeBlocking { + copyToRealm(lastInfo) + } + } + Blog.LOGD(log = "Successfully opened realm: ${realm.configuration.name}") + + } + + fun updateLastInfo(pagedTextLayout: PagedTextLayout) { + (currentBooinfo?.pathUrl ?: lastedUrl?.toUri()?.path)?.let { + HistoryManager.setBookPageInfo(it,binding.pagedLayer.current()) + } + val configuration: Configuration = getResources().configuration + val realm = openRealm() + realm.writeBlocking { + this.query().find()?.last()?.let { + it.displayOrientation = configuration.orientation + it.title = currentTitle + it.chapter = currentChapter + it.pageIndex = pagedTextLayout.current() + this@Novels.lastInfo = copyFromRealm(it) + } + if (currentTitle.length > 0 && currentChapter > 0) { + this@Novels.lastInfo?.makeHistoryItem()?.let { + copyToRealm(it, UpdatePolicy.ALL) + } + } + } + val message: JSONObject = JSONObject() + try { + message.put("type", "scrollDown") + message.put("max", binding.pagedLayer.size()) + message.put("current",binding.pagedLayer.current()) + } catch (ex: JSONException) { + throw RuntimeException(ex) + } + mPort?.postMessage(message) + Blog.LOGD(log = "Successfully opened realm: ${realm.configuration.name}") + } + + 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) + } + + +// 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) +// } +// +// override fun dispatchTrackballEvent(ev: MotionEvent?): Boolean { +// Blog.LOGE("dispatchTrackballEvent ev?.device?.name >>> ${ev?.device?.name}") +// return super.dispatchTrackballEvent(ev) +// } +// +// @SuppressLint("RestrictedApi") +// override fun dispatchKeyShortcutEvent(ev: KeyEvent): Boolean { +// Blog.LOGE("dispatchKeyShortcutEvent ev?.device?.name >>> ${ev?.device?.name}") +// return super.dispatchKeyShortcutEvent(ev) +// } +// +// +// +// override fun dispatchGenericMotionEvent(ev: MotionEvent?): Boolean { +// Blog.LOGE("dispatchKeyShortcutEvent ev?.device?.name >>> ${ev?.device?.name}") +// return super.dispatchGenericMotionEvent(ev) +// } +// +// override fun dispatchKeyEvent(ev: KeyEvent): Boolean { +// Blog.LOGE("dispatch ev?.device?.name >>> ${ev?.device?.name}") +// if (ev?.device?.name?.contains("SM-031N Mouse") == true) { +// when (ev.action) { +// ACTION_UP -> { +// Blog.LOGE("dispatch dispatchKeyEvent>>> ${ev}") +// when (ev.keyCode) { +// KEYCODE_BUTTON_Y -> { +// actionPrevEvent() +// } +// +// KEYCODE_BUTTON_X -> { +// +// } +// +// KEYCODE_BUTTON_A -> { +// actionNextEvent() +// } +// +// KEYCODE_BUTTON_B -> { +// +// } +// +// KEYCODE_DPAD_DOWN -> { +// +// } +// +// KEYCODE_DPAD_UP -> { +// +// } +// +// KEYCODE_BUTTON_START -> { +// goToHome() +// } +// +// KEYCODE_BUTTON_SELECT -> { +// +// saveContinuation = !saveContinuation +// if (saveContinuation) { +// moveToNext(currentBooinfo?.pathUrl ?: lastedUrl?.toUri()?.path) +// } +// } +// +// else -> {} +// } +// } +// +// else -> {} +// } +// return true +// } +// return super.dispatchKeyEvent(ev) +// } + + private fun goToHome() { + contentsLoad(getLastedDoamin()) + } + + var saveContinuation = false + override fun onTouch(touchArea: TouchArea) { + Blog.LOGD(log = "onTouch ${touchArea}") + when (touchArea) { + TouchArea.Center -> { + + } + + TouchArea.Right -> { + actionNextEvent() + } + + TouchArea.Left -> { + actionPrevEvent() + } + + TouchArea.DoubleRight -> { + actionNextEvent(true) + } + + TouchArea.DoubleLeft -> { + actionPrevEvent(true) + } + else -> { + + } + } + + + } + + override fun onLongClick() { + Blog.LOGD(log = "onLongClick") + + } + + override fun onSwipeLeft(count: Int) { + Blog.LOGD(log = "onSwipeLeft ${count}") + actionNextEvent(count > 1) + + } + + override fun onSwipeRight(count: Int) { + Blog.LOGD(log = "onSwipeRight ${count}") + actionPrevEvent(count > 1) + } + + override fun onSwipeUp(touchCount: Int) { + + } + + override fun onSwipeDown(touchCount: Int) { + if (touchCount == 2) { + if (binding.pagedLayer.isVisible) { + binding.pagedLayer.visibility = GONE + } + } + } + + override fun onTimeoverTouch() { + + } + + + + companion object { + private const val TAG = "DualScreenStatus" + } + + + + +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/Settings.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/Settings.kt new file mode 100644 index 00000000..5bc0ccfd --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/Settings.kt @@ -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()?.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,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) + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/common/Definez.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/common/Definez.kt new file mode 100644 index 00000000..91559239 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/common/Definez.kt @@ -0,0 +1,88 @@ +package bums.lunatic.launcher.tokiz.common + +import bums.lunatic.launcher.R + + +typealias PairArray = Array> +val colorz : PairArray> = arrayOf>>( + Pair("color set 01",arrayOf("#E1F5FE", "#263238")), + Pair("color set 02",arrayOf("#F0F4C3", "#37474F")), + Pair("color set 03",arrayOf("#ECEFF1", "#455A64")), + Pair("color set 04",arrayOf("#E0F7FA", "#263238")), + Pair("color set 05",arrayOf("#F5F5F5", "#263238")), + Pair("color set 06",arrayOf("#ECEFF1", "#263238")), + Pair("color set 07",arrayOf("#F8BBD0", "#263238")), + Pair("color set 08",arrayOf("#E6EE9C", "#455A64")), + Pair("color set 09",arrayOf("#CFD8DC", "#455A64")), + Pair("color set 10",arrayOf("#FFF59D", "#37474F")), + Pair("color set 21",arrayOf("#263238","#E1F5FE")), + Pair("color set 22",arrayOf("#37474F","#F0F4C3")), + Pair("color set 23",arrayOf("#455A64","#ECEFF1")), + Pair("color set 24",arrayOf("#263238","#E0F7FA")), + Pair("color set 25",arrayOf("#263238","#F5F5F5")), + Pair("color set 26",arrayOf("#263238","#ECEFF1")), + Pair("color set 27",arrayOf("#263238","#F8BBD0")), + Pair("color set 28",arrayOf("#455A64","#E6EE9C")), + Pair("color set 29",arrayOf("#455A64","#CFD8DC")), + Pair("color set 30",arrayOf("#37474F","#FFF59D")), + Pair("color set 31",arrayOf("#FFFFFF","#1C1B1B")), + Pair("color set 32",arrayOf("#272727","#FFFFFF")), + Pair("color set 33",arrayOf("#1C1B1B","#FFFFFF")), + Pair("color set 34",arrayOf("#FFFFFF","#272727")) +) +val typesfacez : PairArray = arrayOf>( + 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.getIndex(key : String) = getIndex(this, key) +fun getIndex(collection : PairArray, 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 +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/common/PrefManager.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/common/PrefManager.kt new file mode 100644 index 00000000..bd4af4e5 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/common/PrefManager.kt @@ -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() + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/data/HistoryManager.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/data/HistoryManager.kt new file mode 100644 index 00000000..2ea5d5d1 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/data/HistoryManager.kt @@ -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) + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/data/model/BookPageInfo.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/data/model/BookPageInfo.kt new file mode 100644 index 00000000..a7a4928d --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/data/model/BookPageInfo.kt @@ -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 = arrayListOf() + + fun getTitleArray() : ArrayList { + var arrayList = ArrayList() + 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 = realmListOf() + + fun getTitleArray() : ArrayList { + var arrayList = ArrayList() + pages.forEach { + arrayList.add(it.getTitleItem())} + return arrayList + } + + fun sort() { + val comparator : Comparator = 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() + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/data/model/PageInfo.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/data/model/PageInfo.kt new file mode 100644 index 00000000..d9e98607 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/data/model/PageInfo.kt @@ -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 = "" +} + + diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/data/model/ReaderConfig.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/data/model/ReaderConfig.kt new file mode 100644 index 00000000..61dbe841 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/data/model/ReaderConfig.kt @@ -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 +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/dialog/DefaultList.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/dialog/DefaultList.kt new file mode 100644 index 00000000..1e62a393 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/dialog/DefaultList.kt @@ -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, firstPosition : Int, choosedTitle : (Int)->String, chooedPositive : (Int)->Unit, saveCalback : (Int)->Unit ) { + val builderSingle: AlertDialog.Builder = AlertDialog.Builder(context) + builderSingle.setTitle(title) + val arrayAdapter = + ArrayAdapter(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() + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/dialog/DialogManager.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/dialog/DialogManager.kt new file mode 100644 index 00000000..898ac18b --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/dialog/DialogManager.kt @@ -0,0 +1,17 @@ +package bums.lunatic.launcher.tokiz.dialog + +import androidx.activity.ComponentDialog + +object DialogManager { + val dialogs = arrayListOf() + fun add(item : ComponentDialog) = dialogs.add(item) + fun closeAll() { + for (dialog in dialogs) { + try { + dialog?.dismiss() + } catch(e : Exception) { + + } + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/dialog/Stylez.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/dialog/Stylez.kt new file mode 100644 index 00000000..ba1de9e9 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/dialog/Stylez.kt @@ -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>) : +// RecyclerView.Adapter() { +// private val inflater: LayoutInflater +// private val myImageNameList: Array> +// 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() +// } +// } +// } +//} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/BWebview.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/BWebview.kt new file mode 100644 index 00000000..66f000f6 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/BWebview.kt @@ -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) + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/PagedTextGenerateInterface.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/PagedTextGenerateInterface.kt new file mode 100644 index 00000000..a3849bc3 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/PagedTextGenerateInterface.kt @@ -0,0 +1,5 @@ +package bums.lunatic.launcher.tokiz.view + +interface PagedTextGenerateInterface { + fun completePagination(pageList: ArrayList) +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/PagedTextLayout.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/PagedTextLayout.kt new file mode 100644 index 00000000..496e47b8 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/PagedTextLayout.kt @@ -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? = 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) { +// 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) { + 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))) + } +} + diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/PagedTextView.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/PagedTextView.kt new file mode 100644 index 00000000..cb80fe8f --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/PagedTextView.kt @@ -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() + 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 + } + +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/PagedTextViewInterface.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/PagedTextViewInterface.kt new file mode 100644 index 00000000..acc56181 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/PagedTextViewInterface.kt @@ -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() +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/ScopeEditor.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/ScopeEditor.kt new file mode 100644 index 00000000..473a54de --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/ScopeEditor.kt @@ -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? = 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 = ">" + } + + + +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/SideButtonTextView.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/SideButtonTextView.kt new file mode 100644 index 00000000..a5ef91d3 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/SideButtonTextView.kt @@ -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() } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/StepsEditor.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/StepsEditor.kt new file mode 100644 index 00000000..03ab88fc --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/view/StepsEditor.kt @@ -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 = "+" + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/BWebviewClient.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/BWebviewClient.kt new file mode 100644 index 00000000..a3bc825f --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/BWebviewClient.kt @@ -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 +// }) +// } +// }) +// +// } +// } +// +//} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/BaseWebContentsViewer.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/BaseWebContentsViewer.kt new file mode 100644 index 00000000..264fbd43 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/BaseWebContentsViewer.kt @@ -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() +////// 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("

"," ").replace("

","\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 "" \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/DefineTypes.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/DefineTypes.kt new file mode 100644 index 00000000..9951351d --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/DefineTypes.kt @@ -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 diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/MainControllInterface.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/MainControllInterface.kt new file mode 100644 index 00000000..ad6e8346 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/MainControllInterface.kt @@ -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) +// +//} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/WebContentsManger.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/WebContentsManger.kt new file mode 100644 index 00000000..e9af7dc1 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/WebContentsManger.kt @@ -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 = 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 +// } +//} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/contentsinfo/BaseWebContents.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/contentsinfo/BaseWebContents.kt new file mode 100644 index 00000000..fed214f1 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/contentsinfo/BaseWebContents.kt @@ -0,0 +1,5 @@ +package bums.lunatic.launcher.tokiz.webcontents.contentsinfo + +abstract class BaseWebContents : ContentsInfoInterface { + open var lastNumber : Int = 221 +} diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/contentsinfo/BooktokiStruct.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/contentsinfo/BooktokiStruct.kt new file mode 100644 index 00000000..e4c0f8de --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/contentsinfo/BooktokiStruct.kt @@ -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) + } + +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/contentsinfo/ContentsInfoInterface.kt b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/contentsinfo/ContentsInfoInterface.kt new file mode 100644 index 00000000..e30e96ae --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/tokiz/webcontents/contentsinfo/ContentsInfoInterface.kt @@ -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 +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/utils/Blog.kt b/app/src/main/kotlin/bums/lunatic/launcher/utils/Blog.kt index c181537d..f73a0ca8 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/utils/Blog.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/utils/Blog.kt @@ -36,17 +36,27 @@ object Blog { 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")) { when(type) { BLogType.D -> { - Log.d(tag,log) + Log.d(tag, ("${fileName}\n${className}\n${methodName} : ${lineNumber}\n" + log)) } BLogType.I -> { - Log.i(tag,log) + Log.i(tag, ("${fileName}\n${className}\n${methodName} : ${lineNumber}\n" + log)) } BLogType.E -> { - Log.e(tag,log) + Log.e(tag, ("${fileName}\n${className}\n${methodName} : ${lineNumber}\n" + log)) } else -> {} } diff --git a/app/src/main/kotlin/bums/lunatic/launcher/view/DateTimeView.kt b/app/src/main/kotlin/bums/lunatic/launcher/view/DateTimeView.kt index f9087873..bb9bf3a3 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/view/DateTimeView.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/view/DateTimeView.kt @@ -1,20 +1,14 @@ package bums.lunatic.launcher.view import android.content.Context -import android.content.Intent -import android.net.Uri import android.os.Handler import android.os.Looper -import android.provider.AlarmClock import android.text.SpannableString import android.text.SpannableStringBuilder import android.text.Spanned -import android.text.TextPaint import android.text.method.LinkMovementMethod import android.text.style.AbsoluteSizeSpan -import android.text.style.ClickableSpan import android.util.AttributeSet -import android.view.View import androidx.appcompat.widget.AppCompatTextView import bums.lunatic.launcher.R import bums.lunatic.launcher.helpers.PrefString diff --git a/app/src/main/kotlin/bums/lunatic/launcher/view/TableRadioGroup.kt b/app/src/main/kotlin/bums/lunatic/launcher/view/TableRadioGroup.kt index 4defe9c6..e5f72d01 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/view/TableRadioGroup.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/view/TableRadioGroup.kt @@ -3,7 +3,6 @@ package bums.lunatic.launcher.view import android.content.Context import android.util.AttributeSet import android.view.View -import android.view.View.OnClickListener import android.view.ViewGroup import android.widget.RadioButton import android.widget.TableLayout diff --git a/app/src/main/kotlin/bums/lunatic/launcher/workers/AppInfoGetter.kt b/app/src/main/kotlin/bums/lunatic/launcher/workers/AppInfoGetter.kt index 3a7625e0..b607ef92 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/workers/AppInfoGetter.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/workers/AppInfoGetter.kt @@ -8,7 +8,6 @@ import android.content.pm.ResolveInfo import android.os.Build import androidx.work.WorkerParameters import bums.lunatic.launcher.BuildConfig -import bums.lunatic.launcher.LauncherActivity import bums.lunatic.launcher.LauncherActivity.Companion.lActivity import bums.lunatic.launcher.apps.AppDrawer.Companion.appNamesPrefs import bums.lunatic.launcher.model.AppInfo diff --git a/app/src/main/kotlin/bums/lunatic/launcher/workers/DCGetter.kt b/app/src/main/kotlin/bums/lunatic/launcher/workers/DCGetter.kt index ce2634fd..1a1927cb 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/workers/DCGetter.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/workers/DCGetter.kt @@ -4,13 +4,10 @@ import android.annotation.SuppressLint import android.content.Context import androidx.core.net.toUri import androidx.work.WorkerParameters -import bums.lunatic.launcher.helpers.PrefHelper import bums.lunatic.launcher.model.DcInside -import bums.lunatic.launcher.model.RssData import bums.lunatic.launcher.model.RssDataInterface import bums.lunatic.launcher.model.RssDataType import bums.lunatic.launcher.model.getRssData -import bums.lunatic.launcher.utils.Blog import org.jsoup.Jsoup import java.text.SimpleDateFormat diff --git a/app/src/main/kotlin/bums/lunatic/launcher/workers/FmKoreaGetter.kt b/app/src/main/kotlin/bums/lunatic/launcher/workers/FmKoreaGetter.kt index 6276d0ca..1ea442ff 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/workers/FmKoreaGetter.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/workers/FmKoreaGetter.kt @@ -6,7 +6,6 @@ import androidx.work.WorkerParameters import bums.lunatic.launcher.model.FmKorea import bums.lunatic.launcher.model.RssDataType import bums.lunatic.launcher.model.getRssData -import bums.lunatic.launcher.utils.Blog import org.jsoup.Jsoup import java.util.Date diff --git a/app/src/main/kotlin/bums/lunatic/launcher/workers/LocationGetter.kt b/app/src/main/kotlin/bums/lunatic/launcher/workers/LocationGetter.kt index 12b80038..1c1eb006 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/workers/LocationGetter.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/workers/LocationGetter.kt @@ -4,10 +4,8 @@ import android.annotation.SuppressLint import android.content.Context import android.location.Location import androidx.work.WorkerParameters -import bums.lunatic.launcher.LauncherActivity.Companion.runWeatherGetter import bums.lunatic.launcher.common.letTrue import bums.lunatic.launcher.helpers.PrefBoolean -import bums.lunatic.launcher.utils.Blog import bums.lunatic.launcher.workers.LocationUpdateService.Companion.pushLocation import com.google.android.gms.location.LocationServices 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}") longitude = it.longitude latitude = it.latitude - runWeatherGetter() +// runWeatherGetter() PrefBoolean.location.get().letTrue { pushLocation(this.applicationContext,it.latitude, it.longitude) } diff --git a/app/src/main/kotlin/bums/lunatic/launcher/workers/LocationUpdateService.kt b/app/src/main/kotlin/bums/lunatic/launcher/workers/LocationUpdateService.kt index 466d2f17..bdde663b 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/workers/LocationUpdateService.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/workers/LocationUpdateService.kt @@ -11,7 +11,6 @@ import android.location.LocationManager import android.os.Build import android.os.IBinder import android.widget.Toast -import bums.lunatic.launcher.LauncherActivity.Companion.runWeatherGetter import bums.lunatic.launcher.common.letTrue import bums.lunatic.launcher.helpers.PrefBoolean import bums.lunatic.launcher.helpers.PrefLong @@ -141,7 +140,7 @@ class LocationUpdateService : Service(), LocationListener { PrefBoolean.location.get().letTrue { longitude = p0.longitude latitude = p0.latitude - runWeatherGetter() +// runWeatherGetter() pushLocation(this.applicationContext, p0.latitude,p0.longitude) } } @@ -173,7 +172,7 @@ class LocationUpdateService : Service(), LocationListener { ).show() longitude = location.longitude latitude = location.latitude - runWeatherGetter() +// runWeatherGetter() pushLocation(this.applicationContext, location.latitude, location.longitude) } } diff --git a/app/src/main/kotlin/bums/lunatic/launcher/workers/RuliWebGetter.kt b/app/src/main/kotlin/bums/lunatic/launcher/workers/RuliWebGetter.kt index c4edd306..435d62a0 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/workers/RuliWebGetter.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/workers/RuliWebGetter.kt @@ -7,7 +7,6 @@ import androidx.work.WorkerParameters import bums.lunatic.launcher.model.RssDataType import bums.lunatic.launcher.model.RuliWeb import bums.lunatic.launcher.model.getRssData -import bums.lunatic.launcher.utils.Blog import org.jsoup.Jsoup class RuliWebGetter : BaseGetter { diff --git a/app/src/main/kotlin/bums/lunatic/launcher/workers/WorkersDb.kt b/app/src/main/kotlin/bums/lunatic/launcher/workers/WorkersDb.kt index 431362a0..ce92c122 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/workers/WorkersDb.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/workers/WorkersDb.kt @@ -2,6 +2,11 @@ package bums.lunatic.launcher.workers import bums.lunatic.launcher.BuildConfig 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.model.AppInfo 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.RssData import bums.lunatic.launcher.model.RssDataInterface -import bums.lunatic.launcher.model.RssDataType import bums.lunatic.launcher.model.TelegramBotUpdate import bums.lunatic.launcher.model.TelegramChat import bums.lunatic.launcher.model.TelegramData import bums.lunatic.launcher.model.TelegramFrom import bums.lunatic.launcher.model.TelegramMessage -import bums.lunatic.launcher.model.UserActionModel import bums.lunatic.launcher.model.WeatherForcast import bums.lunatic.launcher.utils.Blog import bums.lunatic.launcher.utils.JamoUtils @@ -63,11 +66,11 @@ object WorkersDb { // this.query().query("weekOfYear == $0 OR weekOfMonth == $1 OR dayOfWeek == $2").limit() } } - val clazz : Set> = 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, 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 diff --git a/app/src/main/res/color/tabs_black.xml b/app/src/main/res/color/tabs_black.xml new file mode 100644 index 00000000..38e9ad9a --- /dev/null +++ b/app/src/main/res/color/tabs_black.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/angle_left.xml b/app/src/main/res/drawable/angle_left.xml new file mode 100644 index 00000000..ba9bad44 --- /dev/null +++ b/app/src/main/res/drawable/angle_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/angle_right.xml b/app/src/main/res/drawable/angle_right.xml new file mode 100644 index 00000000..aebb5dd9 --- /dev/null +++ b/app/src/main/res/drawable/angle_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/bookmark.xml b/app/src/main/res/drawable/bookmark.xml new file mode 100644 index 00000000..0d108ef1 --- /dev/null +++ b/app/src/main/res/drawable/bookmark.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/circle_progressbar.xml b/app/src/main/res/drawable/circle_progressbar.xml new file mode 100644 index 00000000..a0827387 --- /dev/null +++ b/app/src/main/res/drawable/circle_progressbar.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/history.png b/app/src/main/res/drawable/history.png new file mode 100644 index 00000000..15fb4f7e Binary files /dev/null and b/app/src/main/res/drawable/history.png differ diff --git a/app/src/main/res/drawable/home.xml b/app/src/main/res/drawable/home.xml new file mode 100644 index 00000000..b906b99b --- /dev/null +++ b/app/src/main/res/drawable/home.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/invoice.png b/app/src/main/res/drawable/invoice.png new file mode 100644 index 00000000..49426b13 Binary files /dev/null and b/app/src/main/res/drawable/invoice.png differ diff --git a/app/src/main/res/drawable/rotation.png b/app/src/main/res/drawable/rotation.png new file mode 100644 index 00000000..0a16bdd5 Binary files /dev/null and b/app/src/main/res/drawable/rotation.png differ diff --git a/app/src/main/res/drawable/saved.xml b/app/src/main/res/drawable/saved.xml new file mode 100644 index 00000000..34d2c6d2 --- /dev/null +++ b/app/src/main/res/drawable/saved.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/settings.xml b/app/src/main/res/drawable/settings.xml new file mode 100644 index 00000000..8a7da8ae --- /dev/null +++ b/app/src/main/res/drawable/settings.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/simple_bg.xml b/app/src/main/res/drawable/simple_bg.xml new file mode 100644 index 00000000..19f69e22 --- /dev/null +++ b/app/src/main/res/drawable/simple_bg.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/font/cafe24oneprettynight.ttf b/app/src/main/res/font/cafe24oneprettynight.ttf new file mode 100644 index 00000000..02524ed8 Binary files /dev/null and b/app/src/main/res/font/cafe24oneprettynight.ttf differ diff --git a/app/src/main/res/font/dovemayo.otf b/app/src/main/res/font/dovemayo.otf new file mode 100644 index 00000000..131556d2 Binary files /dev/null and b/app/src/main/res/font/dovemayo.otf differ diff --git a/app/src/main/res/font/ebs_r.ttf b/app/src/main/res/font/ebs_r.ttf new file mode 100644 index 00000000..5bc6671d Binary files /dev/null and b/app/src/main/res/font/ebs_r.ttf differ diff --git a/app/src/main/res/font/gabia_solmee.ttf b/app/src/main/res/font/gabia_solmee.ttf new file mode 100644 index 00000000..b3e72ab6 Binary files /dev/null and b/app/src/main/res/font/gabia_solmee.ttf differ diff --git a/app/src/main/res/font/godomaum.ttf b/app/src/main/res/font/godomaum.ttf new file mode 100644 index 00000000..e0645c6b Binary files /dev/null and b/app/src/main/res/font/godomaum.ttf differ diff --git a/app/src/main/res/font/jsarirang_hon.otf b/app/src/main/res/font/jsarirang_hon.otf new file mode 100644 index 00000000..8c210f8e Binary files /dev/null and b/app/src/main/res/font/jsarirang_hon.otf differ diff --git a/app/src/main/res/font/jsarirang_ppuri.otf b/app/src/main/res/font/jsarirang_ppuri.otf new file mode 100644 index 00000000..5c0ed015 Binary files /dev/null and b/app/src/main/res/font/jsarirang_ppuri.otf differ diff --git a/app/src/main/res/font/jsdongkang_regular.otf b/app/src/main/res/font/jsdongkang_regular.otf new file mode 100644 index 00000000..ed0a9cbe Binary files /dev/null and b/app/src/main/res/font/jsdongkang_regular.otf differ diff --git a/app/src/main/res/font/kcc_kimhoon.ttf b/app/src/main/res/font/kcc_kimhoon.ttf new file mode 100644 index 00000000..36769688 Binary files /dev/null and b/app/src/main/res/font/kcc_kimhoon.ttf differ diff --git a/app/src/main/res/font/kcc_sonkeechung.otf b/app/src/main/res/font/kcc_sonkeechung.otf new file mode 100644 index 00000000..73f7e3c9 Binary files /dev/null and b/app/src/main/res/font/kcc_sonkeechung.otf differ diff --git a/app/src/main/res/font/kccahnjunggeun.ttf b/app/src/main/res/font/kccahnjunggeun.ttf new file mode 100644 index 00000000..a952f6fb Binary files /dev/null and b/app/src/main/res/font/kccahnjunggeun.ttf differ diff --git a/app/src/main/res/font/kotra_bold.ttf b/app/src/main/res/font/kotra_bold.ttf new file mode 100644 index 00000000..519d55ad Binary files /dev/null and b/app/src/main/res/font/kotra_bold.ttf differ diff --git a/app/src/main/res/font/kotra_songeulssi.ttf b/app/src/main/res/font/kotra_songeulssi.ttf new file mode 100644 index 00000000..a0ee0b1f Binary files /dev/null and b/app/src/main/res/font/kotra_songeulssi.ttf differ diff --git a/app/src/main/res/font/kyobo_handwriting_2021sjy.otf b/app/src/main/res/font/kyobo_handwriting_2021sjy.otf new file mode 100644 index 00000000..f272324a Binary files /dev/null and b/app/src/main/res/font/kyobo_handwriting_2021sjy.otf differ diff --git a/app/src/main/res/font/mapoagape.ttf b/app/src/main/res/font/mapoagape.ttf new file mode 100644 index 00000000..b22b1c28 Binary files /dev/null and b/app/src/main/res/font/mapoagape.ttf differ diff --git a/app/src/main/res/font/mapobackpacking.ttf b/app/src/main/res/font/mapobackpacking.ttf new file mode 100644 index 00000000..081f0f36 Binary files /dev/null and b/app/src/main/res/font/mapobackpacking.ttf differ diff --git a/app/src/main/res/font/mapodacapo.ttf b/app/src/main/res/font/mapodacapo.ttf new file mode 100644 index 00000000..5da4a121 Binary files /dev/null and b/app/src/main/res/font/mapodacapo.ttf differ diff --git a/app/src/main/res/font/mapodpp.ttf b/app/src/main/res/font/mapodpp.ttf new file mode 100644 index 00000000..ccc860de Binary files /dev/null and b/app/src/main/res/font/mapodpp.ttf differ diff --git a/app/src/main/res/font/mapodpp_2.ttf b/app/src/main/res/font/mapodpp_2.ttf new file mode 100644 index 00000000..ccc860de Binary files /dev/null and b/app/src/main/res/font/mapodpp_2.ttf differ diff --git a/app/src/main/res/font/mapoflowerisland.ttf b/app/src/main/res/font/mapoflowerisland.ttf new file mode 100644 index 00000000..adad4f2a Binary files /dev/null and b/app/src/main/res/font/mapoflowerisland.ttf differ diff --git a/app/src/main/res/font/mapogoldenpier.ttf b/app/src/main/res/font/mapogoldenpier.ttf new file mode 100644 index 00000000..8149d99c Binary files /dev/null and b/app/src/main/res/font/mapogoldenpier.ttf differ diff --git a/app/src/main/res/font/mapomaponaru.ttf b/app/src/main/res/font/mapomaponaru.ttf new file mode 100644 index 00000000..4d320611 Binary files /dev/null and b/app/src/main/res/font/mapomaponaru.ttf differ diff --git a/app/src/main/res/font/mapopeacefull.ttf b/app/src/main/res/font/mapopeacefull.ttf new file mode 100644 index 00000000..3861ab36 Binary files /dev/null and b/app/src/main/res/font/mapopeacefull.ttf differ diff --git a/app/src/main/res/font/nnsgc_brhp.ttf b/app/src/main/res/font/nnsgc_brhp.ttf new file mode 100644 index 00000000..7f5e216a Binary files /dev/null and b/app/src/main/res/font/nnsgc_brhp.ttf differ diff --git a/app/src/main/res/font/nnsgc_gd_an_gd.ttf b/app/src/main/res/font/nnsgc_gd_an_gd.ttf new file mode 100644 index 00000000..bdf08b3c Binary files /dev/null and b/app/src/main/res/font/nnsgc_gd_an_gd.ttf differ diff --git a/app/src/main/res/font/nnsgc_md.ttf b/app/src/main/res/font/nnsgc_md.ttf new file mode 100644 index 00000000..ac2de9de Binary files /dev/null and b/app/src/main/res/font/nnsgc_md.ttf differ diff --git a/app/src/main/res/font/nnsgc_wsjidyp.ttf b/app/src/main/res/font/nnsgc_wsjidyp.ttf new file mode 100644 index 00000000..146ad011 Binary files /dev/null and b/app/src/main/res/font/nnsgc_wsjidyp.ttf differ diff --git a/app/src/main/res/font/nnsgc_yjc.ttf b/app/src/main/res/font/nnsgc_yjc.ttf new file mode 100644 index 00000000..64c196ae Binary files /dev/null and b/app/src/main/res/font/nnsgc_yjc.ttf differ diff --git a/app/src/main/res/font/on_jsuhl.ttf b/app/src/main/res/font/on_jsuhl.ttf new file mode 100644 index 00000000..fd68d783 Binary files /dev/null and b/app/src/main/res/font/on_jsuhl.ttf differ diff --git a/app/src/main/res/font/on_jsuhr.ttf b/app/src/main/res/font/on_jsuhr.ttf new file mode 100644 index 00000000..1094155e Binary files /dev/null and b/app/src/main/res/font/on_jsuhr.ttf differ diff --git a/app/src/main/res/font/on_sbsjl.ttf b/app/src/main/res/font/on_sbsjl.ttf new file mode 100644 index 00000000..14c40e52 Binary files /dev/null and b/app/src/main/res/font/on_sbsjl.ttf differ diff --git a/app/src/main/res/font/on_sbsjr.ttf b/app/src/main/res/font/on_sbsjr.ttf new file mode 100644 index 00000000..a1594e9c Binary files /dev/null and b/app/src/main/res/font/on_sbsjr.ttf differ diff --git a/app/src/main/res/font/on_treeususimgul.ttf b/app/src/main/res/font/on_treeususimgul.ttf new file mode 100644 index 00000000..38d088ac Binary files /dev/null and b/app/src/main/res/font/on_treeususimgul.ttf differ diff --git a/app/src/main/res/font/on_treeususimgul_r.ttf b/app/src/main/res/font/on_treeususimgul_r.ttf new file mode 100644 index 00000000..b8ed508e Binary files /dev/null and b/app/src/main/res/font/on_treeususimgul_r.ttf differ diff --git a/app/src/main/res/font/on_wibsr.ttf b/app/src/main/res/font/on_wibsr.ttf new file mode 100644 index 00000000..6a09d280 Binary files /dev/null and b/app/src/main/res/font/on_wibsr.ttf differ diff --git a/app/src/main/res/font/on_wisbl.ttf b/app/src/main/res/font/on_wisbl.ttf new file mode 100644 index 00000000..75441024 Binary files /dev/null and b/app/src/main/res/font/on_wisbl.ttf differ diff --git a/app/src/main/res/font/on_ychyuhl.ttf b/app/src/main/res/font/on_ychyuhl.ttf new file mode 100644 index 00000000..1e42d702 Binary files /dev/null and b/app/src/main/res/font/on_ychyuhl.ttf differ diff --git a/app/src/main/res/font/on_ychyuhr.ttf b/app/src/main/res/font/on_ychyuhr.ttf new file mode 100644 index 00000000..f0bffd5c Binary files /dev/null and b/app/src/main/res/font/on_ychyuhr.ttf differ diff --git a/app/src/main/res/font/ssshinb7.ttf b/app/src/main/res/font/ssshinb7.ttf new file mode 100644 index 00000000..b2e77eea Binary files /dev/null and b/app/src/main/res/font/ssshinb7.ttf differ diff --git a/app/src/main/res/font/taebaek_milkyway.otf b/app/src/main/res/font/taebaek_milkyway.otf new file mode 100644 index 00000000..d17f9bdf Binary files /dev/null and b/app/src/main/res/font/taebaek_milkyway.otf differ diff --git a/app/src/main/res/font/taefont_tsthlml.ttf b/app/src/main/res/font/taefont_tsthlml.ttf new file mode 100644 index 00000000..efe28009 Binary files /dev/null and b/app/src/main/res/font/taefont_tsthlml.ttf differ diff --git a/app/src/main/res/font/tvn_jguiyg_light.ttf b/app/src/main/res/font/tvn_jguiyg_light.ttf new file mode 100644 index 00000000..5ebfe223 Binary files /dev/null and b/app/src/main/res/font/tvn_jguiyg_light.ttf differ diff --git a/app/src/main/res/font/tvn_jguiyg_medium.ttf b/app/src/main/res/font/tvn_jguiyg_medium.ttf new file mode 100644 index 00000000..21d4b7d3 Binary files /dev/null and b/app/src/main/res/font/tvn_jguiyg_medium.ttf differ diff --git a/app/src/main/res/font/wandohoper.ttf b/app/src/main/res/font/wandohoper.ttf new file mode 100644 index 00000000..fd251448 Binary files /dev/null and b/app/src/main/res/font/wandohoper.ttf differ diff --git a/app/src/main/res/font/ylee_mortal_heart_immortal_memory.ttf b/app/src/main/res/font/ylee_mortal_heart_immortal_memory.ttf new file mode 100644 index 00000000..e85465d4 Binary files /dev/null and b/app/src/main/res/font/ylee_mortal_heart_immortal_memory.ttf differ diff --git a/app/src/main/res/layout/booktoki.xml b/app/src/main/res/layout/booktoki.xml new file mode 100644 index 00000000..55c39a47 --- /dev/null +++ b/app/src/main/res/layout/booktoki.xml @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_setting_title.xml b/app/src/main/res/layout/item_setting_title.xml new file mode 100644 index 00000000..9189866d --- /dev/null +++ b/app/src/main/res/layout/item_setting_title.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/launcher_activity.xml b/app/src/main/res/layout/launcher_activity.xml index 3ac776bc..1d3922b4 100644 --- a/app/src/main/res/layout/launcher_activity.xml +++ b/app/src/main/res/layout/launcher_activity.xml @@ -1,19 +1,65 @@ - + > + + - + + + + android:layout_height="wrap_content"> + + + - - - + diff --git a/app/src/main/res/layout/launcher_home.xml b/app/src/main/res/layout/launcher_home.xml index fd747a5c..f5a3c640 100644 --- a/app/src/main/res/layout/launcher_home.xml +++ b/app/src/main/res/layout/launcher_home.xml @@ -17,13 +17,17 @@ android:padding="@dimen/default_padding" android:scrollbars="none" android:visibility="visible" - android:background="@drawable/base_bg" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> - + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_steps_editor.xml b/app/src/main/res/layout/layout_steps_editor.xml new file mode 100644 index 00000000..643ef69d --- /dev/null +++ b/app/src/main/res/layout/layout_steps_editor.xml @@ -0,0 +1,47 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_textviewer.xml b/app/src/main/res/layout/layout_textviewer.xml new file mode 100644 index 00000000..8247f3f0 --- /dev/null +++ b/app/src/main/res/layout/layout_textviewer.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/settings.xml b/app/src/main/res/layout/settings.xml new file mode 100644 index 00000000..2485e9c7 --- /dev/null +++ b/app/src/main/res/layout/settings.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/simple_toast.xml b/app/src/main/res/layout/simple_toast.xml new file mode 100644 index 00000000..3d081d94 --- /dev/null +++ b/app/src/main/res/layout/simple_toast.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml deleted file mode 100644 index a6b3daec..00000000 --- a/app/src/main/res/values-bn-rBD/strings.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml deleted file mode 100644 index fd6a0446..00000000 --- a/app/src/main/res/values-de/strings.xml +++ /dev/null @@ -1,148 +0,0 @@ - - - OWM API-Schlüssel - Center - Warnung! Diese Operation löscht alle Daten von dieser App! Dies kann nicht rückgängig gemacht werden. - Zeit — Datum - Sie haben leider kein Icon-Pack installiert. - Standart - Zurücksetzen - Temperatur - Erlauben, bei Doppeltippen in den Ruhezustand zu wechseln - Neu Hinzufügen - In Zwischenablage kopiert - Willkommen - Zahl der To-Do einträge auf dem Startbildschirm - APK-Datei teilen über - Widget hinzufügen - App-Thema wählen - App-Ausrichtung - Letzte Aktualisierung - Erleichterte Bedienung - Kein AppStore auf diesem Gerät. - Danksagungen -\n https://github.com/cachapa/ExpandableLayout - Hintergrund geändert - Negativ - Nicht ausführbar - Anzeigezeitpunkt - Weiteres - Die Änderungen werden erst nach Neustart der App übernommen. Jetzt neu starten\? - Willkommen bei Lunar Launcher. -\n -\n Nachdem Sie dieses Dialogfeld geschlossen haben, werden Sie aufgefordert, die erforderlichen Berechtigungen zu erteilen, damit die App wie erwartet funktioniert. -\n -\n
  • Systemeinstellungen ändern – Um die Helligkeit mit einem Schieberegler zu steuern
  • -\n
  • Telefon – Zum Tätigen von Anrufen über Verknüpfungen
  • -\n -\n Es handelt sich um eine mit Copyleft versehene Libre-Software. \u0020Überprüfen, ändern und mit allen teilen. -\n -\n Gesten: -\n
  • Nach oben wischen – Schnellzugriffsdialog
  • -\n
  • Nach unten wischen – Benachrichtigungsfeld
  • -\n
  • Nach rechts wischen – Feeds
  • -\n
  • Nach links wischen – App-Schublade
  • -\n
  • Tippen und halten Sie die Batterieanzeige – Launcher-Einstellungen
  • -\n
  • Tippen und halten Sie den unteren Teil des Bildschirms – To-Do-Manager
  • -\n
  • Doppeltippen – Gerätesperre/Ruhezustand (in den Einstellungen aktivieren)
  • -\n
  • Tippen Sie auf den Favoriten und halten Sie es gedrückt – Favorit entfernen
  • -\n -\n Weitere Informationen auf der Wiki-Seite auf GitHub.
    - Total - Liste mit Symbolen - Statusleiste verstecken - 12-Stunden - Das Eingabefeld ist leer - Standart-Launcher wählen - RSS-Feed - Jetzt neu starten\? - Rechts - Sperrservice - Bild konnte nicht geladen werden - Aktualisieren - Verknüpfung & App-Icon Größe - Erweitert - Icon-Pack wählen - Aussehen des App-Drawers - Fortfahren - App-Info-Fenster öffnen - Stadtname mit Wetter zeigen - RSS-Feed-URL - Quellcode - Geräteadministratoren - To-Do Manager Sperren - In pip Modus öffnen - Löschen - Höhe der A bis Z Scroll-Leiste - Authentifizierungsfehler - Support - Version - URL - Wiederholungszahl - Alle To-Do Eingaben löschen\? - Wetter - Leider ist etwas schief gelaufen - Kontakte - Favorit - App deinstallieren - Auf App-Market anzeigen - Entwickelt von Md. Rasel Hossian - Hochgefahren seit -\nSystem Aktiv -\nVerwendeter Arbeitsspeicher -\nAkkutemperatur -\nAkku-Voltzahl -\nSpeicherplatz -\nIPv4 -\nIPv6 - Verwendet - Über - Neustart - App-Drawer - Telegramgruppe - Erste Installation - Detailinfos anzeigen - Authentifizierungsfehler - Links - Lunar-Einstellungen - Root - Kostenlos - 24-Stunden - Hintergrund - Hochbewegen - Dunkelmodus - To-Do - Runterbewegen - Lunar Launcher erlauben, das Gerät in den Ruhezustand zu versetzen (API 28+). - Fortfahren - System folgen - Mit Tastatur starten - Hilf dem Entwickler die App Kostenlos und am leben zu halten -\n -\n
  • Spenden: Wenn möglich, direkt Spenden.
  • -\n
  • Amazon: Nutze den Link um den Entwickler beim Shoppen zu unterstützen.
  • -\n
  • Star: Star auf GitHub um deine Unterstützung zu zeigen.
  • - Liste - Tabelle - Spenden - Alle löschen - Datumsformat - Höhe erhöhen - Keine Tabellenspalten - Positiv - Schnellstart - Hintergrund ändern - Stadtname - APK-Datei teilen - Höhe verkleinern - Zeitformat - Immer zum Home-Bildschirm zurückkehren - To-Do Manager - Zahl der Verknüpfungen (URL/Kontakte) - Licht - Temperatureinheit - Später - Mit ihrem Gerätanmeldedaten anmelden, um fortzufahren. - Aktivitäten durchsuchen - Systemstatus -
    \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml deleted file mode 100644 index b7e06187..00000000 --- a/app/src/main/res/values-es/strings.xml +++ /dev/null @@ -1,142 +0,0 @@ - - - Acerca de - Accesibilidad - Deja que Lunar Launcher ponga el dispositivo en reposo (API 28+). - Bloquear servicio - - Agradecimientos\n - https://github.com/cachapa/ExpandableLayout - - Añadir nuevo - Añadir widget - Avanzado - Apariencia - Elegir el tema de la aplicación - Alineamiento de la app - Cajón de aplicaciones - Abrir la ventana con la información de la aplicación - Visitar en la Tienda de aplicaciones - Error de autenticación - Autenticación fallida - Identifícate con las credenciales del dispositivo para proceder. - Fondo - Siempre volver a la pantalla de inicio - Centro - Cambiar fondo de pantalla - Escoger launcher predeterminado - Ciudad - Contactar - Copiado al portapapeles - Oscuro - Formato de fecha - Reducir altura - Predeterminado - Borrar - Borrar todo - ¿Borrar todas las tareas existentes\? - Desarrollado por Md. Rasel Hossain - Administrador del dispositivo - Permite poner el dispositivo en reposo con un doble toque - Donar - Método de bloqueo de doble toque - El campo de texto está vacío - URL de la fuente RSS - Primera instalación - Seguir al sistema - Libre - Abrir en modo pip - Frecuencias - Entendido - Ocultar barra de estado - Tamaño de los accesos directos e iconos de las aplicaciones - Error al buscar imagen - Aumentar altura - Última actualización - Izquierda - Claro - Ajustes de Lunar - Miscelánea - - Tiempo encendido\nSistema activo\nUmbral de memoria\nTemperatura de la batería\nVoltaje de la bateria\nRaíz de almacenamiento\nIPv4\nIPv6 - - Mover hacia arriba - Mover hacia abajo - Negativo - No se pude encontrar ninguna tienda de aplicaciones en este dispositivo. - Clave de la API de OWM - Positivo - Proceder - Lanzado rápido - Resetear - Esta operación borrará todos los datos almacenados para esta aplicación, y no se puede deshacer. - Reiniciar - Derecha - Raíz - Feed RSS - Altura de la barra alfabética - Comienza con el teclado - Número de accesos directos (URL/Contacto) - Mostrar nombre de la ciudad en los datos meteorológicos - Algo ha ido mal - Código fuente - Estrella - Soporte - Apoya al desarrollador para mantener esta aplicación gratis y viva. - \n
  • Donar: si es posible, haga donaciones directas para ayudar y alentar al desarrollador.
  • - \n
  • Amazon: use el enlace de afiliado mientras compra en Amazon para recompensar al desarrollador.
  • - \n
  • Estrella: Destaca en GitHub para mostrar tu apoyo.
  • -
    - Información del sistema - Grupo de Telegram - Temperatura - Unidad de temperatura - Hora — Fecha - Formato de hora - Tareas pendientes - Número de entradas de tareas pendientes en la pantalla de inicio - Administrador de tareas pendientes - Bloquear el gestor de tareas pendientes - Total - 12 Horas - 24 Horas - Fallo al abrir - Desinstalar la aplicación - Actualizar - URL - Usado - Versión - Fondo de pantalla cambiado - Tiempo - Bienvenide - Bienvenide a Lunar Launcher. Esta es la primera vez que abres la aplicación; si es la primera vez que la usas, lee estos textos antes de proceder. - \n\nPrimero, tras cerrar este mensaje, se te pedirá conceder los siguientes permisos. Si decides no hacerlo, esta aplicación no funcionará como se espera. - \n\n
  • Modificar ajustes del sistema - Para controlar el brillo usando una barra deslizable
  • - \n
  • Teléfono - Para poder hacer llamadas desde los accesos directos a contactos
  • - \n\n Si sigues teniendo cualquier duda, puedes comprobar el código fuente de la aplicación, este es una aplicación completamente de código abierto. - \n\nGestos: - \n
  • Deslizar hacia arriba - acceso rápido
  • - \n
  • Deslizar hacia abajo - panel de notificaciones
  • - \n
  • Deslizar a la derecha - Feed
  • - \n
  • Deslizar a la izquierda - Cajón de aplicaciones
  • - \n
  • Mantener pulsado en el reloj circular - Ajustes de Lunar launcher
  • - \n
  • Mantener pulsado en la parte inferior de la pantalla - Administrador de tareas
  • - \n
  • Doble toque - Bloquear dispositivo (activar en ajustes)
  • - \n
  • Mantener pulsado un elemento favorito - Eliminar favorito
  • - \n\nPara más información, visite la página de Wiki en Github. -
    - Lo sentimos, no tienes ningún paquete de iconos instalado. - Comparte el APK a través de - Los cambios que acabas de realizar requieren reiniciar la aplicación para que surtan efecto. ¿Quieres reiniciarla ahora\? - ¿Reiniciar ahora\? - Elige un paquete de iconos - Diseño del cajón de las aplicaciones - Ver la información detallada - Lista - Cuadrícula - Número de columnas de la cuadrícula - Compartir el archivo apk - Más tarde - Navegar por las actividades - Lista con iconos -
    \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml deleted file mode 100644 index 493de380..00000000 --- a/app/src/main/res/values-fr/strings.xml +++ /dev/null @@ -1,148 +0,0 @@ - - - Centrer - Ajouter nouveau - Copié dans le presse-papier - Ajouter widget - Sélection du thème de l’application - Alignement des applications - Accessibilité - Remerciements -\nhttps://github.com/cachapa/ExpandableLayout - Apparence - Sélectionner le lanceur par défaut - Service de verrouillage - Avancé - Sélectionner le pack d’icônes - Contact - À propos - Arrière-plan - Sombre - Laissez Lunar Launcher mettre l’appareil en sommeil (API 28+). - Modifier le fond d’écran - Nom de la ville - Parcourir les activités - agencement du tiroir d\'applications - Fenêtre des informations sur l\'application - Visiter sur l\'app market - tiroir d\'applications - Erreur d\'authentification - Par défaut - Permettre de mettre l\'appareil en mode veille en tapant deux fois - Administrateur de l\'appareil - Supprimer - Échec d\'authentification - Supprimer toutes les tâches\? - Développé par Md. Rasel Hossain - Voir l\'information en détail - Faire un don - Tout supprimer - Format de la date - Diminuer la hauteur - Toujours revenir à l\'écran d\'accueil - Connectez-vous à l\'aide de votre code - Clé d\'API chez OWM - Cette opération supprimera toutes les données stockées pour cette application, sans retour possible. - Heure — Date - Désolé, vous n\'avez aucun pack d\'icônes installé. - Réinitialiser - Température - Bienvenue - Nombre de tâches sur la page d\'accueil - Partager le fichier .apk via - Dernière mise à jour - Aucun magasin d\'applications trouvé sur cet appareil. - Fond d\'écran changé - Négatif - Incapable de lancer - Autres - Les changements que vous venez de faire requièrent un redémarrage de l\'application pour être appliqués. Voulez-vous redémarrer maintenant ? - Bienvenue sur Lunar Launcher. -\n -\nAprès avoir fermé cette boîte de dialogue, il vous sera demandé d\'accorder les permissions nécessaires au bon fonctionnement de cette application. -\n -\n
  • Modifier les paramètres système — Pour contrôler la luminosité de l\'écran en utilisant un curseur
  • -\n
  • Téléphone — Pour faire des appels à partir de raccourcis contact
  • -\n -\nCeci est un logiciel libre ; inspectez son code source, modifiez-le et partagez-le avec le plus grand nombre. -\n -\nGestes : -\n
  • Glisser vers le haut — Fenêtre d\'accès rapide
  • -\n
  • Glisser vers le bas — Panneau de notifications
  • -\n
  • Glisser vers la droite — Fils RSS
  • -\n
  • Glisser vers la gauche — Liste des applications
  • -\n
  • Rester appuyé sur l\'indicateur de batterie — Paramètres du lanceur
  • -\n
  • Rester appuyé dans la zone inférieure de l\'écran — Gestionnaire de tâches
  • -\n
  • Double-clic — Verrouiller l\'appareil (à activer dans les paramètres du lanceur)
  • -\n
  • Rester appuyé sur un favori — Supprimer cet item
  • -\n -\nPlus d\'infos sur la page wiki (en anglais) sur GitHub.
    - Total - Liste avec icône - Cacher la barre d\'état - 12 heures - La zone de texte est vide - Flux RSS - Redémarrer maintenant ? - Droite - Impossible de récupérer l\'image - Mettre à jour - Raccourci et taille des icônes - Compris - Montrer la ville avec la météo - URL du flux RSS - Code source - Vérouiller le gestionnaire de tâches - Ouvrir en mode pip - Hauteur de la barre de défilement A-Z - Soutenir - Version - URL - Fréquence - Météo - Quelque chose s\'est mal déroulé - Noter - Désinstaller l\'application - Temps d\'éveil de l\'appareil -\nSystème actif -\nSeuil mémoire -\nTempérature de la batterie -\nTension de la batterie -\nDossier de stockage racine -\nIPv4 -\nIPv6 - Utilisé - Redémarrer - Groupe Telegram - Première installation - Gauche - Paramètres de Lunar - Racine - Gratuit - 24 heures - Déplacer vers le haut - Tâches - Déplacer vers le bas - Continuer - Suivre le système - Démarrer avec le clavier - Apportez votre soutien au développeur pour garder cette application gratuite et en vie. -\n -\n
  • Faire un don : Si possible, faites un don directement au développeur pour l\'aider et l\'encourager.
  • -\n
  • Amazon : Utilisez le lien d\'affiliation lors de vos achats chez Amazon pour récompenser le développeur.
  • -\n
  • GitHub : Ajoutez cette application à vos favoris sur GitHub pour montrer votre soutien.
  • - Liste - Grille - Augmenter la hauteur - Nombre de colonnes dans la grille - Positif - Lancement rapide - Partager le fichier .apk - Format d\'heure - Gestionnaire de tâches - Nombre de raccourcis (URL/Contact) - Clair - Unité de température - Plus tard - Statistiques système -
    \ No newline at end of file diff --git a/app/src/main/res/values-ia/strings.xml b/app/src/main/res/values-ia/strings.xml deleted file mode 100644 index 44ff7053..00000000 --- a/app/src/main/res/values-ia/strings.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - Clave del API de OWM - Hora — Data - Predeterminate - Reinitialisar - Temperatura - Adder nove - Copiate al area de transferentia - Benvenite - Compartir le APK via - Adder widget - Seliger le thema del application - Alineamento del applicationes - Ultime actualisation - Accessibilitate - Non poteva trovar necun magazin de applicationes in iste apparato. - Fundo de schermo cambiate - Negative - Non pote lancear - Apparentia - Miscellanea - Total - Lista con icones - Celar le barra de stato - 12 horas - Seliger lanceator predefinite - Fluxo RSS - Reinitiar ora? - Dextra - Non poteva obtener le imagine - Actualisar - Dimension de icones de application e accessos directe - Avantiate - Seliger le pacchetto de icones - Designo de tiratorio de applicationes - Comprendite - Aperir le fenestra de information del application - Monstrar nomine del citate con le tempore - URL de fluxo RSS - Codice fonte - Administrator de apparato - Aperir in modo pip - Deler - Altitude del barra alphabetic A-Z - Falleva le authentication - Supporto - Version - URL - Frequentia - Tempore - Contacto - Disinstallar le application - Visitar sur le magazin de applicationes - Disvellopate per Md. Rasel Hossain - Usate - A proposito de - Reinitiar - Tiratorio de applicationes - Gruppo de Telegram - Prime installation - Vider le information in detalio - Error de authentication - Sinistra - Parametros de Lunar - Radice - Libere - 24 horas - Fundo - Obscur - Continuar - Sequer le systema - Comenciar con le claviero - Lista - Grillia - Facer un donation - Deler toto - Formato del data - Augmentar le altitude - Numero de columnas del grillia - Positive - Cambiar le fundo del schermo - Nomine del citate - Compartir le file apk - Diminuer le altitude - Formato de hora - Sempre retornar al schermo de initio - Numero de accessos directe (URL/Contacto) - Clar - Unitate de temperatura - Depost - Navigar per le activitates - Information del systema - Centro - Iste operation delera tote le datos immagazinate pro iste application e non pote esser disfacite. - Nos regretta, tu non ha necun pacchetto de icones installate. - Numero de entratas de cargas in le schermo de initio - \u0020Recognoscentias -\n \u0020https://github.com/cachapa/ExpandableLayout \u0020 - Le campo de texto es vacue - Blocar servicio - Blocar le gestor de cargas - Deler tote le entratas de cargas? - Habeva qualcosa improprie - Tempore de activitate del apparato -\nSystema active -\nLimine de memoria -\nTemperatura de batteria -\nVoltage de batteria -\nImmagazinage radice -\nIPv4 -\nIPv6 - Mover in alto - Cargas pendente - Mover in basso - Lanceamento rapide - Gestor de cargas - \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml deleted file mode 100644 index 1f2889c6..00000000 --- a/app/src/main/res/values-it/strings.xml +++ /dev/null @@ -1,147 +0,0 @@ - - - Maggiori informazioni - Accessibilità - Permette a Lunar Launcher di bloccare il dispositivo,(API 28 e successivi). - Servizio di blocco - - Ringraziamenti\n - https://github.com/cachapa/ExpandableLayout - - Aggiungi - Aggiungi widget - Avanzate - Stile - Scegli il tema dell\'applicazione - Allineamento applicazioni - Pannello applicazioni - Apri finestra informazioni app - Visualizza nel negozio app - Errore di autenticazione - Autenticazione fallita - Autenticati con le credenziali del dispositivo per procedere. - Colore di fondo - Torna sempre alla schermata principale - Centro - Cambia sfondo - Scegli il launcher predefinito - Nome della città - Contatti - Copiato negli appunti - Scuro - Formato Data - Predefinito - Cancella - Cancella tutto - Elimino tutte le note\? - Sviluppato da Md. Rasel Hossain - Amministratore del dispositivo - Permetti il blocco dello schermo con due tocchi - Donazioni - Blocco schermo con due tocchi - Il campo è vuoto - URL del flusso RSS - Prima installazione - Come da sistema - Libero - Apri in modalità PiP - Frequenza - Capito - Immagine non ottenuta - Ultimo aggiornamento - Sinistra - Chiaro - Impostazioni di Lunar - Varie - - Tempo di uptime\nSistema attivo da\nSoglia della Memoria\nTemperatura della Batteria\nTensione della Batteria - \nArchiviazione di Root\nIPv4\nIPv6 - - Negativo - Non riesco a trovare Negozi installati in questo dispositivo. - Chiave API OWM - Affermativo - Procedere - Avvio Rapido - Reset - Questa operazione cancellerà tutti i dati salvati per questa applicazione. I dati non saranno ripristinabili. - Riavvia - Destra - Root - Flusso RSS - Inizia con tastiera - Numero di scorciatoie (URL/Contatti) - Mostra il nome della città con il meteo - Qualcosa è andato storto - Codice sorgente - Stella - Supporto - Supporti lo sviluppatore per mantenere l\'applicazione viva e gratuita: -\n -\n
  • Donazioni: se possibile, può fare una donazione diretta ed incoraggiare lo sviluppatore.
  • -\n
  • Amazon: può usare il link di affiliazione mentre fa acquisti su Amazon per ricompensare lo sviluppatore.
  • -\n
  • Metta una stella: può mostrare il suo supporto su Github mettendo una stella.
  • - Statistiche di sistema - Grruppo Telegram - Temperatura - Unità della temperatura - Data e ora - Formato ora - Note - Numero di note nella schermata principale - Gestore delle note - Blocco del gestore note - Totale - 12 ore - 24 ore - Impossibile avviare - Disinstalla la applicazione - Aggiorna - URL - Usata - Versione - Sfondo cambiato - Meteo - Benvenuti - Benvenuti su Lunar Launcher. -\n -\nAppena chiuso questo dialogo, le verrà chiesto di fornire le seguenti autorizzazioni. Se si rifiuta di fornirle, questa applicazione non funzionerà come previsto. -\n -\n
  • Modifica dei parametri di sistema - Per controllare la luminosità utilizzando il cursore
  • -\n
  • Telefono - Per effettuare chiamate dalle scorciatoie
  • -\n -\nSe ha ancora qualche dubbio, può verificare il codice sorgente in qualsiasi momento. Questa applicazione è completamente open-source. -\n -\nGesti: -\n
  • Scorrere verso l\'alto - comparsa accesso rapido
  • -\n
  • Scorrere verso il basso - pannello delle notifiche
  • -\n
  • Scorrere a destra - pannello delle informazioni
  • -\n
  • Scorrere a sinistra - pannello delle applicazioni
  • -\n
  • Premere e mantenere sull\'indicatore della batteria - impostazioni del launcher
  • -\n
  • Premere e mantenere sulla parte inferiore dello schermo - gestore delle note
  • -\n
  • Doppio tocco - blocco del dispositivo (attivare dalle impostazioni)
  • -\n
  • Premere e mantenere l\'elemento dei preferiti - rimuove l\'elemento
  • -\n -\nPer maggiori informazioni, visitare la wiki su Github.
    - Scusa, non hai pacchetti di icone installati. - Condividi APK via - I cambiamenti che hai fatto richiedono il riavvio della app per essere applicati. Vuoi riavviare la app adesso\? - Lista con icone - Nascondi barra di stato - Riavviare adesso\? - Dimensioni scorciatoie e icone app - Scegli pacchetto icone - Layout cassetto delle app - Altezza della barra A-Z - Visualizza dettagli - Muovi sù - Muovi giù - Lista - Griglia - Aumenta altezza - Numero colonne - Condividi il file apk - Abbassa altezza - Dopo - Scorri attività -
    \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml deleted file mode 100644 index a88a1afe..00000000 --- a/app/src/main/res/values-ja/strings.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - 新しく追加 - ウィジェットを追加 - アプリケーションのテーマを選択 - アプリの調整 - アクセシビリティ - 感謝 -\n https://github.com/cachapa/ExpandableLayout - 外観 - ロックサービス - 高度 - アプリドロワーのレイアウト - アプリ情報ウィンドウを開く - アプリマーケットにアクセス - 詳細 - アプリドロワー - Lunar Launcherでデバイスをスリープ状態にします。(API 28+) - アクティビティを参照 - センター - デフォルトのランチャーを選択 - アイコンパックを選択 - 認証に失敗しました - 連絡先 - 認証エラー - バックグラウンド - 壁紙を変更 - 都市名 - 常にホーム画面に戻る - 続行するには、デバイスの情報で認証してください。 - 申し訳ありませんが、アイコンパックがインストールされていません。 - デフォルト - ダブルタップのジェスチャーでデバイスをスリープ状態にします - クリップボードにコピーしました - ステータスバーを非表示にする - テキストフィールドが空です - 画像を取得出来ませんでした - ショートカット&アプリアイコンのサイズ - 分かった - RSSフィードURL - デバイス管理者 - PIPモードで開く - 削除 - 頻度 - 全てのToDoエントリーを削除しますか? - 開発者:Md. Rasel Hossain - 最初のインストール - 詳細情報を見る - 自由 - ダーク - フォローシステム - グリッド - 寄付 - 全て削除 - 日付 - グリッド列の数 - 高さを減らす - \ No newline at end of file diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml deleted file mode 100644 index ed86e22e..00000000 --- a/app/src/main/res/values-ml/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - അക്‌സസിബിളിറ്റി - വിശദാംശം - \ No newline at end of file diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml deleted file mode 100644 index 8909e049..00000000 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - Tilgjengelighet - Bakgrunn - Legg til ny - Enhetsadministrator - Programdrakt - Kopiert til utklippstavlen - Alltid gå tilbake til hjemmeskjermen - Forvalg - Endre bakgrunnsbilde - Datoformat - Slett - Slett alle - Doner - Tekstfeltet er tomt - Programjustering - Om - Legg til miniprogram - Utseeender - Programskuff - Programinfo - Programbutikk - Bynavn - Kontakt - Mørk - Tilbakestill - Temperatur - Del APK via - Ymse - Velg forvalgt oppstarter - RSS-informasjonskanal - Høyre - Låsetjeneste - Kildekode - Støtte - Slett alle gjøremålsoppføringer\? - Noe gikk galt - Omstart - Telegram-gruppe - Vis detaljer info - Tidsformat - Temperaturenhet - \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml deleted file mode 100644 index 74e51182..00000000 --- a/app/src/main/res/values-night/colors.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - #FF1C1B1F - #FFFFFBFE - #11FFFFFF - #01000000 - \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml deleted file mode 100644 index 978bc96c..00000000 --- a/app/src/main/res/values-night/themes.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml deleted file mode 100644 index cc3f4913..00000000 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - Sobre - Acessibilidade - \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml deleted file mode 100644 index a2e002b4..00000000 --- a/app/src/main/res/values-pt/strings.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - Alterar papel de parede - Agradecimentos -\n https://github.com/cachapa/ExpandableLayout - Adicionar Widget - Avançar - Aparências - Tema do aplicativo - Alinhamento do aplicativo - Autentifique-se com a credencial do seu dispositivo para prosseguir. - Escolher Launcher padrão - Nome da cidade - Copiado para a área de transferência - Formato de data - Diminuir altura - Padrão - Excluir - Desenvolvido por Md. Rasel Hossain - Administrador do dispositivo - Doar - Método de bloqueio de toque-duplo - O campo de texto está vazio - URL do Feed RSS - Primeira instalação - Gratuito - Forma livre - Frequência - Entendi - Ocultar a barra de status - Tamanho do atalho e do ícone do aplicativo - Não foi possível buscar a imagem - Aumentar a altura - Última atualização - Esquerda - Claro - Miscelâneos - Código-fonte - Estrela - Apoie - Grupo no Telegram - Temperatura - Unidade de temperatura - Tempo — Data - Formato de hora - Gerenciador de tarefas - Bloqueio do gerenciador de tarefas - Total - Bem-vindo(a) - 12 horas - 24 horas - Não é possível iniciar - Desinstalar - Atualizar - URL - Usado - Versão - Papel de parede alterado - Centro - Fundo - Sempre voltar para a tela inicial - Sobre - Acessibilidade - Deixar o Lunar Launcher colocar o dispositivo para dormir (no Android Pie (API 28+)). - Informações do aplicativo - Adicionar novo - Serviço de bloqueio - Gaveta de aplicativos - Loja de aplicativos - Erro de autenticação - Falha na autentificação - Contato - Seguir o sistema - Toque duplo para bloquear - Escuro - Excluir tudo - Excluir todas as tarefas\? - Clima - Negativo - Positivo - Bem-vindo(a) ao Luna Launcher. -\n -\nApós fechar este diálogo, você será pedido para dar as permissões necessárias para o aplicativo funcionar como esperado. -\n -\n
  • Modificar configurações do sistema — Para controlar o brilho com um deslizador
  • -\n
  • Telefone — Para realizar chamadas a partir dos atalhos
  • -\n -\nÉ um software livre com distribuição gratuita (Copyleft); verifique, mude e compartilhe com todos(as). -\n -\nGestos: -\n
  • Deslizar para cima — Acesso rápido
  • -\n
  • Deslizar para baixo — Painel de notificações
  • -\n
  • Deslizar para direita— Feeds
  • -\n
  • Deslizar para esquerda — Gaveta de aplicativos
  • -\n
  • Toque e segure dentro do indicador de bateria — Configurações do Launcher
  • -\n
  • Toque e segure na parte inferior da tela — Gerenciador de tarefas
  • -\n
  • Toque-duplo — Bloquear dispositivo/Colocar para dormir (ativar em configurações)
  • -\n
  • Toque e segure no item favorito — Remover favorito
  • -\n -\nMais informações na página wiki no GitHub.
    - Configurações do aplicativo - Direita - Número de entradas de tarefas na tela inicial - Tempo de atividade do dispositivo -\nSistema ativo -\nLimite de memória -\nTemperatura da bateria -\nTensão da bateria -\nArmazenamento raiz -\nIPv4 -\nIPv6 - Mover para baixo - Nenhuma loja de aplicativos instalada neste dispositivo. - Mover para cima - Chave da API OWM - Prosseguir - Início rápido - Resetar - Raiz - Reiniciar - Essa ação limpa todos os dados armazenados para este aplicativo e não pode ser desfeita. - Altura da barra de deslocamento A-Z - Feed RSS - Tarefas - Procurar com o teclado - Algo deu errado - Número de atalhos (URL/Contato) - Mostrar nome da cidade com previsão do tempo - Status do sistema - Apoie o desenvolvedor para manter este aplicativo gratuito e vivo. -\n -\n
  • Doe: Se possível, faça doações diretas para ajudar e encorajar o desenvolvedor.
  • -\n
  • Amazon: Use o link afiliado enquanto compra na Amazon para recompensar o desenvolvedor.
  • -\n
  • Estrela: Dê uma estrela no GitHub para mostrar o seu apoio.
  • -
    diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml deleted file mode 100644 index 47cce928..00000000 --- a/app/src/main/res/values-tr/strings.xml +++ /dev/null @@ -1,137 +0,0 @@ - - - Hakkında - Erişilebilirlik - - Lunar Launcher\'ın cihazı uyku moduna almasına izin veren erişilebilirlik servisi, - Android Pie (API 28) ve üstü için. - - Kilit Servisi - - Teşekkürler\n - https://github.com/cachapa/ExpandableLayout - - Yeni Ekle - Widget Ekle - Gelişmiş - Görünüm - Uygulama Teması - Uygulama Çekmecesi - Uygulama Bilgisi - Uygulama Mağazası - Kimlik doğrulama hatası - Kimlik doğrulama başarısız oldu - - Devam etmek için cihaz kimlik bilgilerinizle doğrulama yapın - - Arka Plan - Her zaman Ana Ekrana Geri Dön - Duvar Kağıdı Değiştir - Varsayılan Başlatıcıyı Seçin - Şehir Adı - İletişim - Panoya kopyalandı - Karanlık - Tarih Formatı - Yüksekliği Azalt - Varsayılan - Sil - Tümünü Sil - - Mevcut tüm görevleri silmek istediğinizden emin misiniz? - - Geliştirici Md Rasel Hossain - Cihaz Yöneticisi - - Çift dokunarak kilitleme özelliğini kullanmaya izin ver - - Bağış Yap - Çift Dokunma Kilitleme Yöntemi - Metin alanı boş - RSS Besleme URL\'si - İlk Yükleme - Sistemi Takip Et - Ücretsiz - Serbest form - Frekans - Anladım - Durum Çubuğunu Gizle - Resim alınamadı - Yüksekliği Arttır - Son Güncelleme - Aydınlık - Ay Ayarları - Çeşitli - - Cihaz Çalışma Süresi\nSistem Aktif\nBellek Eşiği\nBatarya Sıcaklığı\nBatarya Gerilimi - \nKök Depolama\nIPv4\nIPv6 - - Yukarı Taşı - Aşağı Taşı - Negatif - Bu cihazda yüklü hiçbir uygulama mağazası yok. - OWM API Anahtarı - Pozitif - Devam et - Hızlı Başlat - Sıfırla - - Bu işlem, bu uygulama için depolanan tüm verileri temizleyecek ve geri alınamaz. - - Yeniden Başlat - Kök - RSS Beslemesi - Klavyeyle Ara - Kısayol Sayısı (URL/Kişi) - Hava Durumu ile Şehir Adını Göster - Bir şeyler yanlış gitti - Kaynak Kodu - Yıldız - Destek - Geliştiricinin uygulamayı ücretsiz ve canlı tutmak için desteğini destekleyin.\n - \n
  • Bağış: Mümkünse, geliştiriciyi desteklemek ve teşvik etmek için doğrudan bağış yapın.
  • - \n
  • Amazon: Amazon\'da alışveriş yaparken ortaklık bağlantısını kullanarak geliştiriciyi ödüllendirebilirsiniz.
  • - \n
  • Yıldız: Destek göstermek için Github\'da yıldız verin.
  • -
    - Sistem İstatistikleri - Telegram Grubu - Sıcaklık - Sıcaklık Birimi - Zaman - Tarih - Zaman Biçimi - Yapılacaklar - Ana Ekran\'daki Yapılacak Sayısı - Yapılacaklar Yöneticisi - Yapılacaklar Yöneticisi Kilidi - Toplam - 12 Saat - 24 Saat - Başlatılamadı - Kaldır - Güncelle - URL - Kullanılmış - Versiyon - Arkaplan başarıyla değiştirildi - Hava Durumu - Hoş Geldiniz - Lunar Launcher\'a hoş geldiniz. İlk açılışınız; eğer yeni bir kullanıcısınız, - devam etmeden önce bu metinleri okuyun. - \n\nİlk olarak, bu iletişim kutusunu kapattıktan sonra aşağıdaki izinleri vermeniz istenecektir. Eğer izinleri vermezseniz, - uygulama beklenildiği gibi çalışmaz. - \n\n
  • Sistem ayarlarını değiştirin - Bir kaydırıcı kullanarak parlaklığı kontrol etmek için
  • - \n
  • Telefon - Kısayollardan arama yapmak için
  • - \n\nHala herhangi bir şüpheniz varsa, kaynak kodunu her zaman kontrol edebilirsiniz, tamamen açık kaynaklıdır. - \n\nJestler: - \n
  • Yukarı kaydır - hızlı erişim
  • - \n
  • Aşağı kaydır - bildirim paneli
  • - \n
  • Sağa kaydır - beslemeler
  • - \n
  • Sola kaydır - uygulama çekmecesi
  • - \n
  • Pil göstergesi içinde basılı tutun - launcher ayarları
  • - \n
  • Ekrandaki alt kısımda basılı tutun - yapılacaklar yöneticisi
  • - \n
  • Çift tıklayın - cihaz kilidi/uyku (Ayarlar\'dan etkinleştirin)
  • - \n
  • Favori öğeyi basılı tutun - favoriyi kaldırın
  • - \n\nDaha fazla bilgi için Github\'daki wiki sayfasını ziyaret edin. -
    - -
    diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index a8df5e73..a11a7c4d 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -17,4 +17,7 @@ #FF018786 #FF000000 #FFFFFFFF + + #994CAF50 + #99007ACC \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 0ce7f544..3aac45e8 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -36,4 +36,7 @@ 329dp 10dp + 30dp + 15dp + 45dp \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7d44e924..aa88d4a1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -177,5 +177,5 @@ 위치 정보 갱신 거리 차량 블루투스 이름 - + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 8929ea8c..1c5f51f7 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,5 +1,5 @@ - + + + \ No newline at end of file