mirror of
https://github.com/mihonapp/mihon.git
synced 2025-03-13 16:20:08 +01:00
Migrate to Tachiyomi 6.1
Rewrite batch add UI Rewrite lock UI
This commit is contained in:
parent
3da7c47bf5
commit
32d02f9329
@ -42,8 +42,8 @@ android {
|
|||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
versionCode 5003
|
versionCode 6101
|
||||||
versionName "v5.0.3-EH"
|
versionName "v6.1.1-EH"
|
||||||
|
|
||||||
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
|
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
|
||||||
buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\""
|
buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\""
|
||||||
@ -214,7 +214,7 @@ dependencies {
|
|||||||
releaseCompile "com.google.firebase:firebase-crash:$firebase_version"
|
releaseCompile "com.google.firebase:firebase-crash:$firebase_version"
|
||||||
|
|
||||||
//SnappyDB (EH)
|
//SnappyDB (EH)
|
||||||
compile 'io.paperdb:paperdb:2.0'
|
compile 'io.paperdb:paperdb:2.1'
|
||||||
|
|
||||||
//JVE (Regex) (EH)
|
//JVE (Regex) (EH)
|
||||||
compile 'ru.lanwen.verbalregex:java-verbal-expressions:1.4'
|
compile 'ru.lanwen.verbalregex:java-verbal-expressions:1.4'
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="eu.kanade.tachiyomi">
|
package="eu.kanade.tachiyomi">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
@ -106,8 +107,8 @@
|
|||||||
<!-- EH -->
|
<!-- EH -->
|
||||||
<activity
|
<activity
|
||||||
android:name="exh.ui.login.LoginActivity"
|
android:name="exh.ui.login.LoginActivity"
|
||||||
android:label="@string/label_login"
|
android:label="@string/label_login">
|
||||||
android:parentActivityName=".ui.setting.SettingsActivity" >
|
<!-- TODO parent activity -->
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
@ -145,17 +146,8 @@
|
|||||||
android:scheme="https"/>
|
android:scheme="https"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
|
||||||
android:name="exh.ui.migration.MigrationCompletionActivity"
|
|
||||||
android:label="Complete migration">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.SEND" />
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<data android:mimeType="application/json"/>
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity android:name="exh.ui.lock.LockActivity"
|
<activity android:name="exh.ui.lock.LockController"
|
||||||
android:label="Application locked"/>
|
android:label="Application locked"/>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
@ -67,7 +67,7 @@ class NHentai(context: Context) : HttpSource() {
|
|||||||
= parseResultPage(response)
|
= parseResultPage(response)
|
||||||
|
|
||||||
override fun mangaDetailsParse(response: Response)
|
override fun mangaDetailsParse(response: Response)
|
||||||
= parseGallery(jsonParser.parse(response.body().string()).asJsonObject)
|
= parseGallery(jsonParser.parse(response.body()!!.string()).asJsonObject)
|
||||||
|
|
||||||
//Used so we can use a different URL for fetching manga details and opening the details in the browser
|
//Used so we can use a different URL for fetching manga details and opening the details in the browser
|
||||||
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
|
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
|
||||||
@ -85,7 +85,7 @@ class NHentai(context: Context) : HttpSource() {
|
|||||||
= nhGet(baseUrl + "/api/gallery/" + url.split("/").last())
|
= nhGet(baseUrl + "/api/gallery/" + url.split("/").last())
|
||||||
|
|
||||||
fun parseResultPage(response: Response): MangasPage {
|
fun parseResultPage(response: Response): MangasPage {
|
||||||
val res = jsonParser.parse(response.body().string()).asJsonObject
|
val res = jsonParser.parse(response.body()!!.string()).asJsonObject
|
||||||
|
|
||||||
val error = res.get("error")
|
val error = res.get("error")
|
||||||
if(error == null) {
|
if(error == null) {
|
||||||
@ -154,7 +154,7 @@ class NHentai(context: Context) : HttpSource() {
|
|||||||
?: client.newCall(urlToDetailsRequest(url))
|
?: client.newCall(urlToDetailsRequest(url))
|
||||||
.asObservableSuccess()
|
.asObservableSuccess()
|
||||||
.map {
|
.map {
|
||||||
rawParseGallery(jsonParser.parse(it.body().string()).asJsonObject)
|
rawParseGallery(jsonParser.parse(it.body()!!.string()).asJsonObject)
|
||||||
}.toBlocking().first()
|
}.toBlocking().first()
|
||||||
}!!
|
}!!
|
||||||
|
|
||||||
|
@ -4,54 +4,8 @@ import android.support.v7.app.AppCompatActivity
|
|||||||
import eu.kanade.tachiyomi.util.LocaleHelper
|
import eu.kanade.tachiyomi.util.LocaleHelper
|
||||||
|
|
||||||
abstract class BaseActivity : AppCompatActivity() {
|
abstract class BaseActivity : AppCompatActivity() {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
LocaleHelper.updateConfiguration(this)
|
LocaleHelper.updateConfiguration(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
var willLock = false
|
|
||||||
var disableLock = false
|
|
||||||
override fun onRestart() {
|
|
||||||
super.onRestart()
|
|
||||||
if(willLock && lockEnabled() && !disableLock) {
|
|
||||||
showLockActivity(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
willLock = false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStop() {
|
|
||||||
super.onStop()
|
|
||||||
tryLock()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun tryLock() {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
val mUsageStatsManager = getSystemService("usagestats") as UsageStatsManager
|
|
||||||
val time = System.currentTimeMillis()
|
|
||||||
// We get usage stats for the last 20 seconds
|
|
||||||
val stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 20, time)
|
|
||||||
// Sort the stats by the last time used
|
|
||||||
if (stats != null) {
|
|
||||||
val mySortedMap = TreeMap<Long, UsageStats>()
|
|
||||||
for (usageStats in stats) {
|
|
||||||
mySortedMap.put(usageStats.lastTimeUsed, usageStats)
|
|
||||||
}
|
|
||||||
if (!mySortedMap.isEmpty()) {
|
|
||||||
if(mySortedMap[mySortedMap.lastKey()]?.packageName != packageName) {
|
|
||||||
willLock = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val am = getSystemService(Service.ACTIVITY_SERVICE) as ActivityManager
|
|
||||||
val tasks: List<ActivityManager.RunningTaskInfo>
|
|
||||||
tasks = am.getRunningTasks(1)
|
|
||||||
val running = tasks[0]
|
|
||||||
if (running.topActivity.packageName != packageName) {
|
|
||||||
willLock = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,12 +16,6 @@ class LibraryCategoryAdapter(view: LibraryCategoryView) :
|
|||||||
*/
|
*/
|
||||||
private var mangas: List<LibraryItem> = emptyList()
|
private var mangas: List<LibraryItem> = emptyList()
|
||||||
|
|
||||||
//EH
|
|
||||||
private val sourceManager: SourceManager by injectLazy()
|
|
||||||
|
|
||||||
private val searchEngine = SearchEngine()
|
|
||||||
private val metadataHelper = MetadataHelper()
|
|
||||||
|
|
||||||
var asyncSearchText: String? = null
|
var asyncSearchText: String? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,49 +30,6 @@ class LibraryCategoryAdapter(view: LibraryCategoryView) :
|
|||||||
performFilter()
|
performFilter()
|
||||||
}
|
}
|
||||||
|
|
||||||
// --> EH
|
|
||||||
/**
|
|
||||||
* Filters the list of manga applying [filterObject] for each element.
|
|
||||||
*
|
|
||||||
* @param param the filter. Not used.
|
|
||||||
*/
|
|
||||||
override fun updateDataSet(param: String?) {
|
|
||||||
//Async search filter (EH)
|
|
||||||
val filtered = asyncSearchText?.let { search ->
|
|
||||||
mangas.filter {
|
|
||||||
filterObject(it, search)
|
|
||||||
}
|
|
||||||
} ?: mangas
|
|
||||||
//The rest of the filters run on the main loop
|
|
||||||
Handler(Looper.getMainLooper()).post {
|
|
||||||
filterItems(filtered)
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filters a manga depending on a query.
|
|
||||||
*
|
|
||||||
* @param manga the manga to filter.
|
|
||||||
* @param query the query to apply.
|
|
||||||
* @return true if the manga should be included, false otherwise.
|
|
||||||
*/
|
|
||||||
override fun filterObject(manga: Manga, query: String): Boolean = with(manga) {
|
|
||||||
if(!isLewdSource(manga.source)) {
|
|
||||||
//Regular searching for normal manga
|
|
||||||
title.toLowerCase().contains(query) ||
|
|
||||||
author != null && author!!.toLowerCase().contains(query)
|
|
||||||
} else {
|
|
||||||
//Use gallery search engine for EH manga
|
|
||||||
val metadata = metadataHelper.fetchMetadata(manga.url, manga.source)
|
|
||||||
metadata?.let {
|
|
||||||
searchEngine.matches(it, searchEngine.parseQuery(query))
|
|
||||||
} ?: title.contains(query, ignoreCase = true) //Use regular searching when the metadata is not set up for this gallery
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// <-- EH
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the position in the adapter for the given manga.
|
* Returns the position in the adapter for the given manga.
|
||||||
*
|
*
|
||||||
@ -89,7 +40,9 @@ class LibraryCategoryAdapter(view: LibraryCategoryView) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun performFilter() {
|
fun performFilter() {
|
||||||
updateDataSet(mangas.filter { it.filter(searchText) })
|
updateDataSet(mangas.filter {
|
||||||
|
it.filter(searchText)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -102,19 +102,6 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
fun onBind(category: Category) {
|
fun onBind(category: Category) {
|
||||||
this.category = category
|
this.category = category
|
||||||
|
|
||||||
//TODO Fix
|
|
||||||
// --> EH
|
|
||||||
val presenter = fragment.presenter
|
|
||||||
|
|
||||||
searchSubscription = presenter
|
|
||||||
.searchSubject
|
|
||||||
.debounce(10L, TimeUnit.MILLISECONDS)
|
|
||||||
.subscribe { text -> //Debounce search (EH)
|
|
||||||
adapter.asyncSearchText = text?.trim()?.toLowerCase()
|
|
||||||
adapter.updateDataSet()
|
|
||||||
}
|
|
||||||
// <-- EH
|
|
||||||
|
|
||||||
adapter.mode = if (controller.selectedMangas.isNotEmpty()) {
|
adapter.mode = if (controller.selectedMangas.isNotEmpty()) {
|
||||||
FlexibleAdapter.MODE_MULTI
|
FlexibleAdapter.MODE_MULTI
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,10 +12,18 @@ import eu.kanade.tachiyomi.R
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.util.inflate
|
import eu.kanade.tachiyomi.util.inflate
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||||
|
import exh.isLewdSource
|
||||||
|
import exh.metadata.MetadataHelper
|
||||||
|
import exh.search.SearchEngine
|
||||||
import kotlinx.android.synthetic.main.catalogue_grid_item.view.*
|
import kotlinx.android.synthetic.main.catalogue_grid_item.view.*
|
||||||
|
|
||||||
class LibraryItem(val manga: Manga) : AbstractFlexibleItem<LibraryHolder>(), IFilterable {
|
class LibraryItem(val manga: Manga) : AbstractFlexibleItem<LibraryHolder>(), IFilterable {
|
||||||
|
|
||||||
|
// --> EH
|
||||||
|
private val searchEngine = SearchEngine()
|
||||||
|
private val metadataHelper = MetadataHelper()
|
||||||
|
// <-- EH
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return R.layout.catalogue_grid_item
|
return R.layout.catalogue_grid_item
|
||||||
}
|
}
|
||||||
@ -53,6 +61,15 @@ class LibraryItem(val manga: Manga) : AbstractFlexibleItem<LibraryHolder>(), IFi
|
|||||||
* @return true if the manga should be included, false otherwise.
|
* @return true if the manga should be included, false otherwise.
|
||||||
*/
|
*/
|
||||||
override fun filter(constraint: String): Boolean {
|
override fun filter(constraint: String): Boolean {
|
||||||
|
// --> EH
|
||||||
|
if(!isLewdSource(manga.source)) {
|
||||||
|
//Use gallery search engine for EH manga
|
||||||
|
metadataHelper.fetchMetadata(manga.url, manga.source)?.let {
|
||||||
|
return searchEngine.matches(it, searchEngine.parseQuery(constraint))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// <-- EH
|
||||||
|
|
||||||
return manga.title.contains(constraint, true) ||
|
return manga.title.contains(constraint, true) ||
|
||||||
(manga.author?.contains(constraint, true) ?: false)
|
(manga.author?.contains(constraint, true) ?: false)
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
package eu.kanade.tachiyomi.ui.main
|
package eu.kanade.tachiyomi.ui.main
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
import android.animation.ObjectAnimator
|
||||||
|
import android.app.ActivityManager
|
||||||
|
import android.app.Service
|
||||||
|
import android.app.usage.UsageStats
|
||||||
|
import android.app.usage.UsageStatsManager
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.view.GravityCompat
|
import android.support.v4.view.GravityCompat
|
||||||
import android.support.v4.widget.DrawerLayout
|
import android.support.v4.widget.DrawerLayout
|
||||||
@ -10,6 +15,8 @@ import android.support.v7.graphics.drawable.DrawerArrowDrawable
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.bluelinelabs.conductor.*
|
import com.bluelinelabs.conductor.*
|
||||||
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
||||||
|
import com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler
|
||||||
|
import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler
|
||||||
import eu.kanade.tachiyomi.Migrations
|
import eu.kanade.tachiyomi.Migrations
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
@ -26,8 +33,14 @@ import eu.kanade.tachiyomi.ui.manga.MangaController
|
|||||||
import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController
|
import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController
|
||||||
import eu.kanade.tachiyomi.ui.recently_read.RecentlyReadController
|
import eu.kanade.tachiyomi.ui.recently_read.RecentlyReadController
|
||||||
import eu.kanade.tachiyomi.ui.setting.SettingsMainController
|
import eu.kanade.tachiyomi.ui.setting.SettingsMainController
|
||||||
|
import exh.ui.batchadd.BatchAddController
|
||||||
|
import exh.ui.lock.LockChangeHandler
|
||||||
|
import exh.ui.lock.LockController
|
||||||
|
import exh.ui.lock.lockEnabled
|
||||||
|
import exh.ui.lock.notifyLockSecurity
|
||||||
import kotlinx.android.synthetic.main.main_activity.*
|
import kotlinx.android.synthetic.main.main_activity.*
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : BaseActivity() {
|
class MainActivity : BaseActivity() {
|
||||||
@ -86,9 +99,8 @@ class MainActivity : BaseActivity() {
|
|||||||
R.id.nav_drawer_recently_read -> setRoot(RecentlyReadController(), id)
|
R.id.nav_drawer_recently_read -> setRoot(RecentlyReadController(), id)
|
||||||
R.id.nav_drawer_catalogues -> setRoot(CatalogueController(), id)
|
R.id.nav_drawer_catalogues -> setRoot(CatalogueController(), id)
|
||||||
R.id.nav_drawer_latest_updates -> setRoot(LatestUpdatesController(), id)
|
R.id.nav_drawer_latest_updates -> setRoot(LatestUpdatesController(), id)
|
||||||
//TODO
|
|
||||||
// --> EH
|
// --> EH
|
||||||
R.id.nav_drawer_batch_add -> setFragment(BatchAddFragment.newInstance(), id)
|
R.id.nav_drawer_batch_add -> setRoot(BatchAddController(), id)
|
||||||
// <-- EH
|
// <-- EH
|
||||||
R.id.nav_drawer_downloads -> {
|
R.id.nav_drawer_downloads -> {
|
||||||
router.pushController(RouterTransaction.with(DownloadController())
|
router.pushController(RouterTransaction.with(DownloadController())
|
||||||
@ -137,6 +149,17 @@ class MainActivity : BaseActivity() {
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//Show lock
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
val lockEnabled = lockEnabled(preferences)
|
||||||
|
if (lockEnabled) {
|
||||||
|
doLock()
|
||||||
|
|
||||||
|
//Check lock security
|
||||||
|
notifyLockSecurity(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
syncActivityViewWithController(router.backstack.lastOrNull()?.controller())
|
syncActivityViewWithController(router.backstack.lastOrNull()?.controller())
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
@ -144,15 +167,6 @@ class MainActivity : BaseActivity() {
|
|||||||
if (Migrations.upgrade(preferences)) {
|
if (Migrations.upgrade(preferences)) {
|
||||||
ChangelogDialogController().showDialog(router)
|
ChangelogDialogController().showDialog(router)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Show lock
|
|
||||||
val lockEnabled = lockEnabled(preferences)
|
|
||||||
if(lockEnabled) {
|
|
||||||
showLockActivity(this)
|
|
||||||
|
|
||||||
//Check lock security
|
|
||||||
notifyLockSecurity(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,6 +267,54 @@ class MainActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --> EH
|
||||||
|
//Lock code
|
||||||
|
var willLock = false
|
||||||
|
var disableLock = false
|
||||||
|
override fun onRestart() {
|
||||||
|
super.onRestart()
|
||||||
|
if(willLock && lockEnabled() && !disableLock) {
|
||||||
|
doLock()
|
||||||
|
}
|
||||||
|
|
||||||
|
willLock = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
tryLock()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tryLock() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
val mUsageStatsManager = getSystemService("usagestats") as UsageStatsManager
|
||||||
|
val time = System.currentTimeMillis()
|
||||||
|
// We get usage stats for the last 20 seconds
|
||||||
|
val sortedStats =
|
||||||
|
mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
|
||||||
|
time - 1000 * 20,
|
||||||
|
time)
|
||||||
|
?.associateBy {
|
||||||
|
it.lastTimeUsed
|
||||||
|
}?.toSortedMap()
|
||||||
|
if(sortedStats != null && sortedStats.isNotEmpty())
|
||||||
|
if(sortedStats[sortedStats.lastKey()]?.packageName != packageName)
|
||||||
|
willLock = true
|
||||||
|
} else {
|
||||||
|
val am = getSystemService(Service.ACTIVITY_SERVICE) as ActivityManager
|
||||||
|
val running = am.getRunningTasks(1)[0]
|
||||||
|
if (running.topActivity.packageName != packageName) {
|
||||||
|
willLock = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doLock() {
|
||||||
|
router.pushController(RouterTransaction.with(LockController())
|
||||||
|
.popChangeHandler(LockChangeHandler()))
|
||||||
|
}
|
||||||
|
// <-- EH
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// Shortcut actions
|
// Shortcut actions
|
||||||
const val SHORTCUT_LIBRARY = "eu.kanade.tachiyomi.SHOW_LIBRARY"
|
const val SHORTCUT_LIBRARY = "eu.kanade.tachiyomi.SHOW_LIBRARY"
|
||||||
|
@ -1,19 +1,15 @@
|
|||||||
package eu.kanade.tachiyomi.ui.setting
|
package eu.kanade.tachiyomi.ui.setting
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
|
||||||
import android.support.v7.preference.PreferenceScreen
|
import android.support.v7.preference.PreferenceScreen
|
||||||
import android.view.View
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
||||||
import exh.ui.migration.MetadataFetchDialog
|
import exh.ui.migration.MetadataFetchDialog
|
||||||
import exh.ui.login.LoginActivity
|
import exh.ui.login.LoginActivity
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EH Settings fragment
|
* EH Settings fragment
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SettingsEhFragment : SettingsController() {
|
class SettingsEhController : SettingsController() {
|
||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) {
|
override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) {
|
||||||
title = "E-Hentai"
|
title = "E-Hentai"
|
||||||
|
|
||||||
@ -27,13 +23,24 @@ class SettingsEhFragment : SettingsController() {
|
|||||||
.asObservable().subscribeUntilDestroy {
|
.asObservable().subscribeUntilDestroy {
|
||||||
isChecked = it
|
isChecked = it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onChange { newVal ->
|
||||||
|
newVal as Boolean
|
||||||
|
if(!newVal) {
|
||||||
|
preferences.enableExhentai().set(false)
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
startActivity(Intent(context, LoginActivity::class.java))
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switchPreference {
|
switchPreference {
|
||||||
title = "Use Hentai@Home Network"
|
title = "Use Hentai@Home Network"
|
||||||
summary = "Do you wish to load images through the Hentai@Home Network? Disabling this option will reduce the amount of pages you are able to view"
|
summary = "Do you wish to load images through the Hentai@Home Network? Disabling this option will reduce the amount of pages you are able to view"
|
||||||
key = "enable_hah"
|
key = "enable_hah"
|
||||||
defaultValue = "true"
|
defaultValue = true
|
||||||
}
|
}
|
||||||
|
|
||||||
switchPreference {
|
switchPreference {
|
||||||
@ -41,11 +48,11 @@ class SettingsEhFragment : SettingsController() {
|
|||||||
summaryOn = "Currently showing Japanese titles in search results. Clear the chapter cache after changing this (in the Advanced section)"
|
summaryOn = "Currently showing Japanese titles in search results. Clear the chapter cache after changing this (in the Advanced section)"
|
||||||
summaryOff = "Currently showing English/Romanized titles in search results. Clear the chapter cache after changing this (in the Advanced section)"
|
summaryOff = "Currently showing English/Romanized titles in search results. Clear the chapter cache after changing this (in the Advanced section)"
|
||||||
key = "use_jp_title"
|
key = "use_jp_title"
|
||||||
defaultValue = "false"
|
defaultValue = false
|
||||||
}
|
}
|
||||||
|
|
||||||
switchPreference {
|
switchPreference {
|
||||||
defaultValue = "true"
|
defaultValue = true
|
||||||
key = "secure_exh"
|
key = "secure_exh"
|
||||||
title = "Secure ExHentai/E-Hentai"
|
title = "Secure ExHentai/E-Hentai"
|
||||||
summary = "Use the HTTPS version of ExHentai/E-Hentai."
|
summary = "Use the HTTPS version of ExHentai/E-Hentai."
|
||||||
@ -91,15 +98,13 @@ class SettingsEhFragment : SettingsController() {
|
|||||||
"rc_2",
|
"rc_2",
|
||||||
"rc_3"
|
"rc_3"
|
||||||
)
|
)
|
||||||
dependency = "enable_exhentai"
|
}.dependency = "enable_exhentai"
|
||||||
}
|
|
||||||
|
|
||||||
listPreference {
|
listPreference {
|
||||||
defaultValue = "tr_2"
|
defaultValue = "tr_2"
|
||||||
title = "Thumbnail rows"
|
title = "Thumbnail rows"
|
||||||
summary = "Affects loading speeds. It is recommended to set this to the maximum size your hath perks allow"
|
summary = "Affects loading speeds. It is recommended to set this to the maximum size your hath perks allow"
|
||||||
key = "ex_thumb_rows"
|
key = "ex_thumb_rows"
|
||||||
dependency = "enable_exhentai"
|
|
||||||
entries = arrayOf(
|
entries = arrayOf(
|
||||||
"4",
|
"4",
|
||||||
"10 (requires 'More Thumbs' hath perk)",
|
"10 (requires 'More Thumbs' hath perk)",
|
||||||
@ -112,7 +117,7 @@ class SettingsEhFragment : SettingsController() {
|
|||||||
"tr_10",
|
"tr_10",
|
||||||
"tr_20"
|
"tr_20"
|
||||||
)
|
)
|
||||||
}
|
}.dependency = "enable_exhentai"
|
||||||
|
|
||||||
preferenceCategory {
|
preferenceCategory {
|
||||||
title = "Advanced"
|
title = "Advanced"
|
||||||
@ -122,48 +127,14 @@ class SettingsEhFragment : SettingsController() {
|
|||||||
title = "Migrate library metadata"
|
title = "Migrate library metadata"
|
||||||
isPersistent = false
|
isPersistent = false
|
||||||
key = "ex_migrate_library"
|
key = "ex_migrate_library"
|
||||||
summary = "Fetch the library metadata to enable tag searching in the library. This button will be visible even if you have already fetched the metadata" />
|
summary = "Fetch the library metadata to enable tag searching in the library. This button will be visible even if you have already fetched the metadata"
|
||||||
|
|
||||||
|
onClick {
|
||||||
|
activity?.let {
|
||||||
|
MetadataFetchDialog().askMigration(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val preferences: PreferencesHelper by injectLazy()
|
|
||||||
|
|
||||||
val enableExhentaiPref by lazy {
|
|
||||||
findPreference("enable_exhentai") as SwitchPreference
|
|
||||||
}
|
|
||||||
|
|
||||||
val migrateLibraryPref by lazy {
|
|
||||||
findPreference("ex_migrate_library") as Preference
|
|
||||||
}
|
|
||||||
|
|
||||||
val useJpTitlePref by lazy {
|
|
||||||
findPreference("use_jp_title") as SwitchPreference
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedState)
|
|
||||||
|
|
||||||
enableExhentaiPref.setOnPreferenceChangeListener { preference, newVal ->
|
|
||||||
newVal as Boolean
|
|
||||||
(activity as SettingsActivity).parentFlags = SettingsActivity.FLAG_EH_RECREATE
|
|
||||||
if(!newVal) {
|
|
||||||
preferences.enableExhentai().set(false)
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
startActivity(Intent(context, LoginActivity::class.java))
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
migrateLibraryPref.setOnPreferenceClickListener {
|
|
||||||
MetadataFetchDialog().askMigration(activity)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
useJpTitlePref.setOnPreferenceChangeListener { preference, any ->
|
|
||||||
(activity as SettingsActivity).parentFlags = SettingsActivity.FLAG_EH_RECREATE
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
import eu.kanade.tachiyomi.util.LocaleHelper
|
import eu.kanade.tachiyomi.util.LocaleHelper
|
||||||
|
import exh.ui.lock.LockPreference
|
||||||
import kotlinx.android.synthetic.main.pref_library_columns.view.*
|
import kotlinx.android.synthetic.main.pref_library_columns.view.*
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
@ -175,6 +176,13 @@ class SettingsGeneralController : SettingsController() {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LockPreference(context).apply {
|
||||||
|
key = "pref_app_lock"
|
||||||
|
title = "Application lock"
|
||||||
|
isPersistent = false
|
||||||
|
|
||||||
|
addPreference(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LibraryColumnsDialog : DialogController() {
|
class LibraryColumnsDialog : DialogController() {
|
||||||
|
@ -48,6 +48,12 @@ class SettingsMainController : SettingsController() {
|
|||||||
titleRes = R.string.backup
|
titleRes = R.string.backup
|
||||||
onClick { navigateTo(SettingsBackupController()) }
|
onClick { navigateTo(SettingsBackupController()) }
|
||||||
}
|
}
|
||||||
|
preference {
|
||||||
|
iconRes = R.drawable.eh_ic_ehlogo_red_24dp
|
||||||
|
iconTint = tintColor
|
||||||
|
titleRes = R.string.pref_category_eh
|
||||||
|
onClick { navigateTo(SettingsEhController()) }
|
||||||
|
}
|
||||||
preference {
|
preference {
|
||||||
iconRes = R.drawable.ic_code_black_24dp
|
iconRes = R.drawable.ic_code_black_24dp
|
||||||
iconTint = tintColor
|
iconTint = tintColor
|
||||||
|
@ -56,68 +56,75 @@ class GalleryAdder {
|
|||||||
val outJson = JsonParser().parse(networkHelper.client.newCall(Request.Builder()
|
val outJson = JsonParser().parse(networkHelper.client.newCall(Request.Builder()
|
||||||
.url(API_BASE)
|
.url(API_BASE)
|
||||||
.post(RequestBody.create(JSON, json.toString()))
|
.post(RequestBody.create(JSON, json.toString()))
|
||||||
.build()).execute().body().string()).obj
|
.build()).execute().body()!!.string()).obj
|
||||||
|
|
||||||
val obj = outJson["tokenlist"].array.first()
|
val obj = outJson["tokenlist"].array.first()
|
||||||
return "${uri.scheme}://${uri.host}/g/${obj["gid"].int}/${obj["token"].string}/"
|
return "${uri.scheme}://${uri.host}/g/${obj["gid"].int}/${obj["token"].string}/"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addGallery(url: String, fav: Boolean = false): Manga {
|
fun addGallery(url: String, fav: Boolean = false): GalleryAddEvent {
|
||||||
val urlObj = Uri.parse(url)
|
|
||||||
val source = when(urlObj.host) {
|
|
||||||
"g.e-hentai.org", "e-hentai.org" -> EH_SOURCE_ID
|
|
||||||
"exhentai.org" -> EXH_SOURCE_ID
|
|
||||||
else -> throw MalformedURLException("Not a valid gallery URL!")
|
|
||||||
}
|
|
||||||
|
|
||||||
val realUrl = when (urlObj.pathSegments.first().toLowerCase()) {
|
|
||||||
"g" -> {
|
|
||||||
//Is already gallery page, do nothing
|
|
||||||
url
|
|
||||||
}
|
|
||||||
"s" -> {
|
|
||||||
//Is page, fetch gallery token and use that
|
|
||||||
getGalleryUrlFromPage(url)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
throw MalformedURLException("Not a valid gallery URL!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val sourceObj = sourceManager.get(source)
|
|
||||||
?: throw IllegalStateException("Could not find EH source!")
|
|
||||||
|
|
||||||
val pathOnlyUrl = getUrlWithoutDomain(realUrl)
|
|
||||||
|
|
||||||
//Use manga in DB if possible, otherwise, make a new manga
|
|
||||||
val manga = db.getManga(pathOnlyUrl, source).executeAsBlocking()
|
|
||||||
?: Manga.create(source).apply {
|
|
||||||
this.url = pathOnlyUrl
|
|
||||||
title = realUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
//Copy basics
|
|
||||||
manga.copyFrom(sourceObj.fetchMangaDetails(manga).toBlocking().first())
|
|
||||||
|
|
||||||
//Apply metadata
|
|
||||||
metadataHelper.fetchEhMetadata(realUrl, isExSource(source))?.copyTo(manga)
|
|
||||||
|
|
||||||
if(fav) manga.favorite = true
|
|
||||||
|
|
||||||
db.insertManga(manga).executeAsBlocking().insertedId()?.let {
|
|
||||||
manga.id = it
|
|
||||||
}
|
|
||||||
|
|
||||||
//Fetch and copy chapters
|
|
||||||
try {
|
try {
|
||||||
sourceObj.fetchChapterList(manga).map {
|
val urlObj = Uri.parse(url)
|
||||||
syncChaptersWithSource(db, it, manga, sourceObj)
|
val source = when (urlObj.host) {
|
||||||
}.toBlocking().first()
|
"g.e-hentai.org", "e-hentai.org" -> EH_SOURCE_ID
|
||||||
} catch (e: Exception) {
|
"exhentai.org" -> EXH_SOURCE_ID
|
||||||
Timber.w(e, "Failed to update chapters for gallery: ${manga.title}!")
|
else -> return GalleryAddEvent.Fail.UnknownType(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
return manga
|
val realUrl = when (urlObj.pathSegments.first().toLowerCase()) {
|
||||||
|
"g" -> {
|
||||||
|
//Is already gallery page, do nothing
|
||||||
|
url
|
||||||
|
}
|
||||||
|
"s" -> {
|
||||||
|
//Is page, fetch gallery token and use that
|
||||||
|
getGalleryUrlFromPage(url)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
return GalleryAddEvent.Fail.UnknownType(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val sourceObj = sourceManager.get(source)
|
||||||
|
?: return GalleryAddEvent.Fail.Error(url, "Could not find EH source!")
|
||||||
|
|
||||||
|
val pathOnlyUrl = getUrlWithoutDomain(realUrl)
|
||||||
|
|
||||||
|
//Use manga in DB if possible, otherwise, make a new manga
|
||||||
|
val manga = db.getManga(pathOnlyUrl, source).executeAsBlocking()
|
||||||
|
?: Manga.create(source).apply {
|
||||||
|
this.url = pathOnlyUrl
|
||||||
|
title = realUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
//Copy basics
|
||||||
|
manga.copyFrom(sourceObj.fetchMangaDetails(manga).toBlocking().first())
|
||||||
|
|
||||||
|
//Apply metadata
|
||||||
|
metadataHelper.fetchEhMetadata(realUrl, isExSource(source))?.copyTo(manga)
|
||||||
|
|
||||||
|
if (fav) manga.favorite = true
|
||||||
|
|
||||||
|
db.insertManga(manga).executeAsBlocking().insertedId()?.let {
|
||||||
|
manga.id = it
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fetch and copy chapters
|
||||||
|
try {
|
||||||
|
sourceObj.fetchChapterList(manga).map {
|
||||||
|
syncChaptersWithSource(db, it, manga, sourceObj)
|
||||||
|
}.toBlocking().first()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e, "Failed to update chapters for gallery: ${manga.title}!")
|
||||||
|
return GalleryAddEvent.Fail.Error(url, "Failed to update chapters for gallery: $url")
|
||||||
|
}
|
||||||
|
|
||||||
|
return GalleryAddEvent.Success(url, manga)
|
||||||
|
} catch(e: Exception) {
|
||||||
|
Timber.e(e, "Could not add gallery!")
|
||||||
|
return GalleryAddEvent.Fail.Error(url,
|
||||||
|
((e.message ?: "Unknown error!") + " (Gallery: $url)").trim())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getUrlWithoutDomain(orig: String): String {
|
private fun getUrlWithoutDomain(orig: String): String {
|
||||||
@ -133,4 +140,28 @@ class GalleryAdder {
|
|||||||
return orig
|
return orig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class GalleryAddEvent {
|
||||||
|
abstract val logMessage: String
|
||||||
|
abstract val galleryUrl: String
|
||||||
|
open val galleryTitle: String? = null
|
||||||
|
|
||||||
|
class Success(override val galleryUrl: String,
|
||||||
|
val manga: Manga): GalleryAddEvent() {
|
||||||
|
override val logMessage = "[OK] Added gallery: $galleryTitle"
|
||||||
|
override val galleryTitle: String
|
||||||
|
get() = manga.title
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class Fail: GalleryAddEvent() {
|
||||||
|
class UnknownType(override val galleryUrl: String): Fail() {
|
||||||
|
override val logMessage = "[ERROR] Unknown gallery type for gallery: $galleryUrl"
|
||||||
|
}
|
||||||
|
|
||||||
|
class Error(override val galleryUrl: String,
|
||||||
|
val message: String): Fail() {
|
||||||
|
override val logMessage = "[ERROR] $message"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,131 +1,145 @@
|
|||||||
package exh.ui.batchadd
|
package exh.ui.batchadd
|
||||||
|
|
||||||
import android.content.pm.ActivityInfo
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.TextView
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
|
import com.jakewharton.rxbinding.view.clicks
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.base.fragment.BaseFragment
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
import exh.GalleryAdder
|
import eu.kanade.tachiyomi.util.combineLatest
|
||||||
import exh.metadata.nullIfBlank
|
import eu.kanade.tachiyomi.util.plusAssign
|
||||||
import kotlinx.android.synthetic.main.eh_fragment_batch_add.*
|
import kotlinx.android.synthetic.main.eh_fragment_batch_add.view.*
|
||||||
import timber.log.Timber
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
import kotlin.concurrent.thread
|
import rx.subscriptions.CompositeSubscription
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LoginActivity
|
* Batch add screen
|
||||||
*/
|
*/
|
||||||
|
class BatchAddController : NucleusController<BatchAddPresenter>() {
|
||||||
|
override fun inflateView(inflater: LayoutInflater, container: ViewGroup) =
|
||||||
|
inflater.inflate(R.layout.eh_fragment_batch_add, container, false)!!
|
||||||
|
|
||||||
class BatchAddFragment : BaseFragment() {
|
override fun getTitle() = "Batch add"
|
||||||
|
|
||||||
private val galleryAdder by lazy { GalleryAdder() }
|
override fun createPresenter() = BatchAddPresenter()
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedState: Bundle?)
|
override fun onViewCreated(view: View, savedViewState: Bundle?) {
|
||||||
= inflater.inflate(R.layout.eh_fragment_batch_add, container, false)!!
|
super.onViewCreated(view, savedViewState)
|
||||||
|
|
||||||
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
|
with(view) {
|
||||||
setToolbarTitle("Batch add")
|
btn_add_galleries.clicks().subscribeUntilDestroy {
|
||||||
|
addGalleries(galleries_box.text.toString())
|
||||||
setup()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setup() {
|
|
||||||
btn_add_galleries.setOnClickListener {
|
|
||||||
val galleries = galleries_box.text.toString()
|
|
||||||
//Check text box has content
|
|
||||||
if(galleries.isNullOrBlank()) {
|
|
||||||
noGalleriesSpecified()
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Too lazy to actually deal with orientation changes
|
progress_dismiss_btn.clicks().subscribeUntilDestroy {
|
||||||
activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
|
presenter.currentlyAddingRelay.call(false)
|
||||||
|
}
|
||||||
|
|
||||||
val splitGalleries = galleries.split("\n").map {
|
val progressSubscriptions = CompositeSubscription()
|
||||||
it.trim().nullIfBlank()
|
|
||||||
}.filterNotNull()
|
|
||||||
|
|
||||||
val dialog = MaterialDialog.Builder(context)
|
presenter.currentlyAddingRelay
|
||||||
.title("Adding galleries...")
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.progress(false, splitGalleries.size, true)
|
.subscribeUntilDestroy {
|
||||||
.cancelable(false)
|
progressSubscriptions.clear()
|
||||||
.canceledOnTouchOutside(false)
|
if(it) {
|
||||||
|
showProgress(this)
|
||||||
|
progressSubscriptions += presenter.progressRelay
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.combineLatest(presenter.progressTotalRelay, { progress, total ->
|
||||||
|
//Show hide dismiss button
|
||||||
|
progress_dismiss_btn.visibility =
|
||||||
|
if(progress == total)
|
||||||
|
View.VISIBLE
|
||||||
|
else View.GONE
|
||||||
|
|
||||||
|
formatProgress(progress, total)
|
||||||
|
}).subscribeUntilDestroy {
|
||||||
|
progress_text.text = it
|
||||||
|
}
|
||||||
|
|
||||||
|
progressSubscriptions += presenter.progressTotalRelay
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribeUntilDestroy {
|
||||||
|
progress_bar.max = it
|
||||||
|
}
|
||||||
|
|
||||||
|
progressSubscriptions += presenter.progressRelay
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribeUntilDestroy {
|
||||||
|
progress_bar.progress = it
|
||||||
|
}
|
||||||
|
|
||||||
|
presenter.eventRelay
|
||||||
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
?.subscribeUntilDestroy {
|
||||||
|
progress_log.append("$it\n")
|
||||||
|
}?.let {
|
||||||
|
progressSubscriptions += it
|
||||||
|
}
|
||||||
|
} else hideProgress(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val View.progressViews
|
||||||
|
get() = listOf(
|
||||||
|
progress_title_view,
|
||||||
|
progress_log_wrapper,
|
||||||
|
progress_bar,
|
||||||
|
progress_text,
|
||||||
|
progress_dismiss_btn
|
||||||
|
)
|
||||||
|
|
||||||
|
private val View.inputViews
|
||||||
|
get() = listOf(
|
||||||
|
input_title_view,
|
||||||
|
galleries_box,
|
||||||
|
btn_add_galleries
|
||||||
|
)
|
||||||
|
|
||||||
|
private var List<View>.visibility: Int
|
||||||
|
get() = throw UnsupportedOperationException()
|
||||||
|
set(v) { forEach { it.visibility = v } }
|
||||||
|
|
||||||
|
private fun showProgress(target: View? = view) {
|
||||||
|
target?.apply {
|
||||||
|
progressViews.visibility = View.VISIBLE
|
||||||
|
inputViews.visibility = View.GONE
|
||||||
|
}?.progress_log?.text = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hideProgress(target: View? = view) {
|
||||||
|
target?.apply {
|
||||||
|
progressViews.visibility = View.GONE
|
||||||
|
inputViews.visibility = View.VISIBLE
|
||||||
|
}?.galleries_box?.setText("", TextView.BufferType.EDITABLE)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun formatProgress(progress: Int, total: Int) = "$progress/$total"
|
||||||
|
|
||||||
|
private fun addGalleries(galleries: String) {
|
||||||
|
//Check text box has content
|
||||||
|
if(galleries.isBlank()) {
|
||||||
|
noGalleriesSpecified()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
presenter.addGalleries(galleries)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun noGalleriesSpecified() {
|
||||||
|
activity?.let {
|
||||||
|
MaterialDialog.Builder(it)
|
||||||
|
.title("No galleries to add!")
|
||||||
|
.content("You must specify at least one gallery to add!")
|
||||||
|
.positiveText("Ok")
|
||||||
|
.onPositive { materialDialog, _ -> materialDialog.dismiss() }
|
||||||
|
.cancelable(true)
|
||||||
|
.canceledOnTouchOutside(true)
|
||||||
.show()
|
.show()
|
||||||
|
|
||||||
val succeeded = mutableListOf<String>()
|
|
||||||
val failed = mutableListOf<String>()
|
|
||||||
|
|
||||||
thread {
|
|
||||||
splitGalleries.forEachIndexed { i, s ->
|
|
||||||
activity.runOnUiThread {
|
|
||||||
dialog.setContent("Processing: $s")
|
|
||||||
}
|
|
||||||
if(addGallery(s)) {
|
|
||||||
succeeded.add(s)
|
|
||||||
} else {
|
|
||||||
failed.add(s)
|
|
||||||
}
|
|
||||||
activity.runOnUiThread {
|
|
||||||
dialog.setProgress(i + 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Show report
|
|
||||||
val succeededCount = succeeded.size
|
|
||||||
val failedCount = failed.size
|
|
||||||
|
|
||||||
if(succeeded.isEmpty()) succeeded += "None"
|
|
||||||
if(failed.isEmpty()) failed += "None"
|
|
||||||
val succeededReport = succeeded.joinToString(separator = "\n", prefix = "Added:\n")
|
|
||||||
val failedReport = failed.joinToString(separator = "\n", prefix = "Failed:\n")
|
|
||||||
|
|
||||||
val summary = "Summary:\nAdded: $succeededCount gallerie(s)\nFailed: $failedCount gallerie(s)"
|
|
||||||
|
|
||||||
val report = listOf(succeededReport, failedReport, summary).joinToString(separator = "\n\n")
|
|
||||||
|
|
||||||
activity.runOnUiThread {
|
|
||||||
//Enable orientation changes again
|
|
||||||
activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR
|
|
||||||
|
|
||||||
dialog.dismiss()
|
|
||||||
|
|
||||||
MaterialDialog.Builder(context)
|
|
||||||
.title("Batch add report")
|
|
||||||
.content(report)
|
|
||||||
.positiveText("Ok")
|
|
||||||
.cancelable(true)
|
|
||||||
.canceledOnTouchOutside(true)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addGallery(url: String): Boolean {
|
|
||||||
try {
|
|
||||||
galleryAdder.addGallery(url, true)
|
|
||||||
} catch(t: Throwable) {
|
|
||||||
Timber.e(t, "Could not add gallery!")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun noGalleriesSpecified() {
|
|
||||||
MaterialDialog.Builder(context)
|
|
||||||
.title("No galleries to add!")
|
|
||||||
.content("You must specify at least one gallery to add!")
|
|
||||||
.positiveText("Ok")
|
|
||||||
.onPositive { materialDialog, _ -> materialDialog.dismiss() }
|
|
||||||
.cancelable(true)
|
|
||||||
.canceledOnTouchOutside(true)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun newInstance() = BatchAddFragment()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,51 @@
|
|||||||
package exh.ui.batchadd
|
package exh.ui.batchadd
|
||||||
|
|
||||||
/**
|
import com.jakewharton.rxrelay.BehaviorRelay
|
||||||
* Created by nulldev on 8/23/17.
|
import com.jakewharton.rxrelay.ReplayRelay
|
||||||
*/
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||||
|
import exh.GalleryAddEvent
|
||||||
|
import exh.GalleryAdder
|
||||||
|
import exh.metadata.nullIfBlank
|
||||||
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
|
class BatchAddPresenter: BasePresenter<BatchAddController>() {
|
||||||
|
|
||||||
|
private val galleryAdder by lazy { GalleryAdder() }
|
||||||
|
|
||||||
|
val progressTotalRelay = BehaviorRelay.create(0)!!
|
||||||
|
val progressRelay = BehaviorRelay.create(0)!!
|
||||||
|
var eventRelay: ReplayRelay<String>? = null
|
||||||
|
val currentlyAddingRelay = BehaviorRelay.create(false)!!
|
||||||
|
|
||||||
|
fun addGalleries(galleries: String) {
|
||||||
|
eventRelay = ReplayRelay.create()
|
||||||
|
val splitGalleries = galleries.split("\n").map {
|
||||||
|
it.trim().nullIfBlank()
|
||||||
|
}.filterNotNull()
|
||||||
|
|
||||||
|
progressRelay.call(0)
|
||||||
|
progressTotalRelay.call(splitGalleries.size)
|
||||||
|
|
||||||
|
currentlyAddingRelay.call(true)
|
||||||
|
|
||||||
|
thread {
|
||||||
|
val succeeded = mutableListOf<String>()
|
||||||
|
val failed = mutableListOf<String>()
|
||||||
|
|
||||||
|
splitGalleries.forEachIndexed { i, s ->
|
||||||
|
val result = galleryAdder.addGallery(s, true)
|
||||||
|
if(result is GalleryAddEvent.Success) {
|
||||||
|
succeeded.add(s)
|
||||||
|
} else {
|
||||||
|
failed.add(s)
|
||||||
|
}
|
||||||
|
progressRelay.call(i + 1)
|
||||||
|
eventRelay?.call(result.logMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Show report
|
||||||
|
val summary = "\nSummary:\nAdded: ${succeeded.size} gallerie(s)\nFailed: ${failed.size} gallerie(s)"
|
||||||
|
eventRelay?.call(summary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,12 +6,11 @@ import android.view.MenuItem
|
|||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaActivity
|
|
||||||
import exh.GalleryAdder
|
import exh.GalleryAdder
|
||||||
import kotlinx.android.synthetic.main.toolbar.*
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
|
//TODO :(
|
||||||
class InterceptActivity : BaseActivity() {
|
class InterceptActivity : BaseActivity() {
|
||||||
|
|
||||||
private val galleryAdder = GalleryAdder()
|
private val galleryAdder = GalleryAdder()
|
||||||
@ -19,12 +18,9 @@ class InterceptActivity : BaseActivity() {
|
|||||||
var finished = false
|
var finished = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setAppTheme()
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.eh_activity_intercept)
|
setContentView(R.layout.eh_activity_intercept)
|
||||||
|
|
||||||
setupToolbar(toolbar, backNavigation = false)
|
|
||||||
|
|
||||||
if(savedInstanceState == null)
|
if(savedInstanceState == null)
|
||||||
thread { setup() }
|
thread { setup() }
|
||||||
}
|
}
|
||||||
@ -54,8 +50,9 @@ class InterceptActivity : BaseActivity() {
|
|||||||
if(Intent.ACTION_VIEW == intent.action) {
|
if(Intent.ACTION_VIEW == intent.action) {
|
||||||
val manga = galleryAdder.addGallery(intent.dataString)
|
val manga = galleryAdder.addGallery(intent.dataString)
|
||||||
|
|
||||||
if(!finished)
|
//TODO
|
||||||
startActivity(MangaActivity.newIntent(this, manga, true))
|
// if(!finished)
|
||||||
|
// startActivity(MangaActivity.newIntent(this, manga, true))
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
package exh.ui.lock
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
|
||||||
import com.andrognito.pinlockview.PinLockListener
|
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
|
||||||
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
|
||||||
import kotlinx.android.synthetic.main.activity_lock.*
|
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
|
|
||||||
class LockActivity : BaseActivity() {
|
|
||||||
|
|
||||||
val prefs: PreferencesHelper by injectLazy()
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
disableLock = true
|
|
||||||
|
|
||||||
setTheme(R.style.Theme_Tachiyomi_Dark)
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
|
|
||||||
if(!lockEnabled(prefs)) {
|
|
||||||
finish()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
setContentView(R.layout.activity_lock)
|
|
||||||
|
|
||||||
pin_lock_view.attachIndicatorDots(indicator_dots)
|
|
||||||
|
|
||||||
pin_lock_view.pinLength = prefs.lockLength().getOrDefault()
|
|
||||||
pin_lock_view.setPinLockListener(object : PinLockListener {
|
|
||||||
override fun onEmpty() {}
|
|
||||||
|
|
||||||
override fun onComplete(pin: String) {
|
|
||||||
if(sha512(pin, prefs.lockSalt().get()!!) == prefs.lockHash().get()) {
|
|
||||||
//Yay!
|
|
||||||
finish()
|
|
||||||
} else {
|
|
||||||
MaterialDialog.Builder(this@LockActivity)
|
|
||||||
.title("PIN code incorrect")
|
|
||||||
.content("The PIN code you entered is incorrect. Please try again.")
|
|
||||||
.cancelable(true)
|
|
||||||
.canceledOnTouchOutside(true)
|
|
||||||
.positiveText("Ok")
|
|
||||||
.autoDismiss(true)
|
|
||||||
.show()
|
|
||||||
pin_lock_view.resetPinLockView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPinChange(pinLength: Int, intermediatePin: String?) {}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBackPressed() {
|
|
||||||
moveTaskToBack(true)
|
|
||||||
}
|
|
||||||
}
|
|
41
app/src/main/java/exh/ui/lock/LockChangeHandler.kt
Normal file
41
app/src/main/java/exh/ui/lock/LockChangeHandler.kt
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package exh.ui.lock
|
||||||
|
|
||||||
|
import android.animation.Animator
|
||||||
|
import android.animation.AnimatorSet
|
||||||
|
import android.animation.ObjectAnimator
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||||
|
import com.bluelinelabs.conductor.changehandler.AnimatorChangeHandler
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
|
class LockChangeHandler : AnimatorChangeHandler {
|
||||||
|
constructor(): super()
|
||||||
|
|
||||||
|
constructor(removesFromViewOnPush: Boolean) : super(removesFromViewOnPush)
|
||||||
|
|
||||||
|
constructor(duration: Long) : super(duration)
|
||||||
|
|
||||||
|
constructor(duration: Long, removesFromViewOnPush: Boolean) : super(duration, removesFromViewOnPush)
|
||||||
|
|
||||||
|
override fun getAnimator(container: ViewGroup, from: View?, to: View?, isPush: Boolean, toAddedToContainer: Boolean): Animator {
|
||||||
|
val animator = AnimatorSet()
|
||||||
|
val viewAnimators = ArrayList<Animator>()
|
||||||
|
|
||||||
|
if (!isPush && from != null) {
|
||||||
|
viewAnimators.add(ObjectAnimator.ofFloat(from, View.SCALE_X, 5f))
|
||||||
|
viewAnimators.add(ObjectAnimator.ofFloat(from, View.SCALE_Y, 5f))
|
||||||
|
viewAnimators.add(ObjectAnimator.ofFloat(from, View.ALPHA, 0f))
|
||||||
|
}
|
||||||
|
|
||||||
|
animator.playTogether(viewAnimators)
|
||||||
|
return animator
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resetFromView(from: View) {}
|
||||||
|
|
||||||
|
override fun copy(): ControllerChangeHandler =
|
||||||
|
LockChangeHandler(animationDuration, removesFromViewOnPush())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
68
app/src/main/java/exh/ui/lock/LockController.kt
Executable file
68
app/src/main/java/exh/ui/lock/LockController.kt
Executable file
@ -0,0 +1,68 @@
|
|||||||
|
package exh.ui.lock
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
|
import com.andrognito.pinlockview.PinLockListener
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
|
import kotlinx.android.synthetic.main.activity_lock.view.*
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
|
class LockController : NucleusController<LockPresenter>() {
|
||||||
|
override fun inflateView(inflater: LayoutInflater, container: ViewGroup)
|
||||||
|
= inflater.inflate(R.layout.activity_lock, container, false)!!
|
||||||
|
|
||||||
|
override fun createPresenter() = LockPresenter()
|
||||||
|
|
||||||
|
override fun getTitle() = "Application locked"
|
||||||
|
|
||||||
|
val prefs: PreferencesHelper by injectLazy()
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedViewState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedViewState)
|
||||||
|
|
||||||
|
if(!lockEnabled(prefs)) {
|
||||||
|
closeLock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
with(view) {
|
||||||
|
pin_lock_view.attachIndicatorDots(indicator_dots)
|
||||||
|
|
||||||
|
pin_lock_view.pinLength = prefs.lockLength().getOrDefault()
|
||||||
|
pin_lock_view.setPinLockListener(object : PinLockListener {
|
||||||
|
override fun onEmpty() {}
|
||||||
|
|
||||||
|
override fun onComplete(pin: String) {
|
||||||
|
if (sha512(pin, prefs.lockSalt().get()!!) == prefs.lockHash().get()) {
|
||||||
|
//Yay!
|
||||||
|
closeLock()
|
||||||
|
} else {
|
||||||
|
MaterialDialog.Builder(context)
|
||||||
|
.title("PIN code incorrect")
|
||||||
|
.content("The PIN code you entered is incorrect. Please try again.")
|
||||||
|
.cancelable(true)
|
||||||
|
.canceledOnTouchOutside(true)
|
||||||
|
.positiveText("Ok")
|
||||||
|
.autoDismiss(true)
|
||||||
|
.show()
|
||||||
|
pin_lock_view.resetPinLockView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPinChange(pinLength: Int, intermediatePin: String?) {}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun closeLock() {
|
||||||
|
router.popCurrentController()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun handleBack() = true
|
||||||
|
}
|
@ -17,7 +17,7 @@ import java.security.SecureRandom
|
|||||||
class LockPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
class LockPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
Preference(context, attrs) {
|
Preference(context, attrs) {
|
||||||
|
|
||||||
val secureRandom by lazy { SecureRandom() }
|
private val secureRandom by lazy { SecureRandom() }
|
||||||
|
|
||||||
val prefs: PreferencesHelper by injectLazy()
|
val prefs: PreferencesHelper by injectLazy()
|
||||||
|
|
||||||
@ -26,12 +26,11 @@ class LockPreference @JvmOverloads constructor(context: Context, attrs: Attribut
|
|||||||
updateSummary()
|
updateSummary()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateSummary() {
|
private fun updateSummary() {
|
||||||
if(lockEnabled(prefs)) {
|
summary = if(lockEnabled(prefs))
|
||||||
summary = "Application is locked"
|
"Application is locked"
|
||||||
} else {
|
else
|
||||||
summary = "Application is not locked, tap to lock"
|
"Application is not locked, tap to lock"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick() {
|
override fun onClick() {
|
||||||
@ -65,7 +64,7 @@ class LockPreference @JvmOverloads constructor(context: Context, attrs: Attribut
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun savePassword(password: String) {
|
private fun savePassword(password: String) {
|
||||||
val salt: String?
|
val salt: String?
|
||||||
val hash: String?
|
val hash: String?
|
||||||
val length: Int
|
val length: Int
|
||||||
|
6
app/src/main/java/exh/ui/lock/LockPresenter.kt
Normal file
6
app/src/main/java/exh/ui/lock/LockPresenter.kt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package exh.ui.lock
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||||
|
|
||||||
|
class LockPresenter: BasePresenter<LockController>()
|
||||||
|
|
@ -44,13 +44,6 @@ fun lockEnabled(prefs: PreferencesHelper = Injekt.get())
|
|||||||
&& prefs.lockSalt().get() != null
|
&& prefs.lockSalt().get() != null
|
||||||
&& prefs.lockLength().getOrDefault() != -1
|
&& prefs.lockLength().getOrDefault() != -1
|
||||||
|
|
||||||
/**
|
|
||||||
* Lock the screen
|
|
||||||
*/
|
|
||||||
fun showLockActivity(activity: Activity) {
|
|
||||||
activity.startActivity(Intent(activity, LockActivity::class.java))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the lock will function properly
|
* Check if the lock will function properly
|
||||||
*
|
*
|
||||||
|
@ -15,7 +15,6 @@ import eu.kanade.tachiyomi.source.online.all.EHentai
|
|||||||
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
||||||
import exh.EXH_SOURCE_ID
|
import exh.EXH_SOURCE_ID
|
||||||
import kotlinx.android.synthetic.main.eh_activity_login.*
|
import kotlinx.android.synthetic.main.eh_activity_login.*
|
||||||
import kotlinx.android.synthetic.main.toolbar.*
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
import rx.schedulers.Schedulers
|
import rx.schedulers.Schedulers
|
||||||
@ -34,13 +33,10 @@ class LoginActivity : BaseActivity() {
|
|||||||
val sourceManager: SourceManager by injectLazy()
|
val sourceManager: SourceManager by injectLazy()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setAppTheme()
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.eh_activity_login)
|
setContentView(R.layout.eh_activity_login)
|
||||||
|
|
||||||
setup()
|
setup()
|
||||||
|
|
||||||
setupToolbar(toolbar, backNavigation = false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setup() {
|
fun setup() {
|
||||||
@ -187,7 +183,7 @@ class LoginActivity : BaseActivity() {
|
|||||||
document.getElementsByName('submit')[0].style.visibility = 'visible';
|
document.getElementsByName('submit')[0].style.visibility = 'visible';
|
||||||
document.querySelector('td[width="60%"][valign="top"]').style.visibility = 'visible';
|
document.querySelector('td[width="60%"][valign="top"]').style.visibility = 'visible';
|
||||||
|
|
||||||
function hide(e) {if(e !== null && e !== undefined) e.style.display = 'none';}
|
function hide(e) {if(e != null) e.style.display = 'none';}
|
||||||
|
|
||||||
hide(document.querySelector(".errorwrap"));
|
hide(document.querySelector(".errorwrap"));
|
||||||
hide(document.querySelector('td[width="40%"][valign="top"]'));
|
hide(document.querySelector('td[width="40%"][valign="top"]'));
|
||||||
@ -202,7 +198,7 @@ class LoginActivity : BaseActivity() {
|
|||||||
hide(fd[2]);
|
hide(fd[2]);
|
||||||
hide(child.querySelector('br'));
|
hide(child.querySelector('br'));
|
||||||
var error = document.querySelector(".page > div > .borderwrap");
|
var error = document.querySelector(".page > div > .borderwrap");
|
||||||
if(error !== null) error.style.visibility = 'visible';
|
if(error != null) error.style.visibility = 'visible';
|
||||||
hide(fh[0]);
|
hide(fh[0]);
|
||||||
hide(fh[1]);
|
hide(fh[1]);
|
||||||
hide(document.querySelector("#gfooter"));
|
hide(document.querySelector("#gfooter"));
|
||||||
@ -211,7 +207,7 @@ class LoginActivity : BaseActivity() {
|
|||||||
e.style.color = "white";
|
e.style.color = "white";
|
||||||
});
|
});
|
||||||
var pc = document.querySelector(".postcolor");
|
var pc = document.querySelector(".postcolor");
|
||||||
if(pc !== null) pc.style.color = "#26353F";
|
if(pc != null) pc.style.color = "#26353F";
|
||||||
})()
|
})()
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/backgroundDark">
|
||||||
|
|
||||||
<com.andrognito.pinlockview.PinLockView
|
<com.andrognito.pinlockview.PinLockView
|
||||||
android:id="@+id/pin_lock_view"
|
android:id="@+id/pin_lock_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/indicator_dots"
|
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent" />
|
app:layout_constraintTop_toBottomOf="@+id/indicator_dots" />
|
||||||
|
|
||||||
<com.andrognito.pinlockview.IndicatorDots
|
<com.andrognito.pinlockview.IndicatorDots
|
||||||
android:id="@+id/indicator_dots"
|
android:id="@+id/indicator_dots"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/pin_lock_view"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintVertical_chainStyle="packed"
|
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/pin_lock_view"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent" />
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed" />
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
@ -17,8 +17,6 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<include layout="@layout/toolbar"/>
|
|
||||||
|
|
||||||
</android.support.design.widget.AppBarLayout>
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<include layout="@layout/toolbar"/>
|
|
||||||
|
|
||||||
</android.support.design.widget.AppBarLayout>
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
|
@ -9,46 +9,121 @@
|
|||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:animateLayoutChanges="true"
|
||||||
|
android:padding="16dp ">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:text="Enter the galleries to add (E-Hentai/ExHentai only, separated by a new line):"
|
android:id="@+id/input_title_view"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/textView"
|
android:text="Enter the galleries to add (separated by a new line):"
|
||||||
android:textAppearance="@style/TextAppearance.Medium.Title"
|
android:textAppearance="@style/TextAppearance.Medium.Title"
|
||||||
android:layout_marginTop="16dp"
|
android:visibility="gone"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
android:layout_marginRight="16dp" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
|
android:id="@+id/galleries_box"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:inputType="textMultiLine"
|
|
||||||
android:ems="10"
|
android:ems="10"
|
||||||
android:id="@+id/galleries_box"
|
android:hint="Example:\n\nhttp://e-hentai.org/g/12345/1a2b3c4e\nhttp://g.e-hentai.org/g/67890/6f7g8h9i\nhttp://exhentai.org/g/13579/1a3b5c7e\nhttps://exhentai.org/g/24680/2f4g6h8i\n"
|
||||||
android:layout_marginTop="8dp"
|
android:inputType="textMultiLine"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/textView"
|
android:visibility="gone"
|
||||||
app:layout_constraintLeft_toLeftOf="@+id/textView"
|
|
||||||
app:layout_constraintRight_toRightOf="@+id/textView"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/btn_add_galleries"
|
app:layout_constraintBottom_toTopOf="@+id/btn_add_galleries"
|
||||||
android:layout_marginBottom="8dp"
|
app:layout_constraintLeft_toLeftOf="@+id/input_title_view"
|
||||||
android:hint="Example:\n\nhttp://e-hentai.org/g/12345/1a2b3c4e\nhttp://g.e-hentai.org/g/67890/6f7g8h9i\nhttp://exhentai.org/g/13579/1a3b5c7e\nhttps://exhentai.org/g/24680/2f4g6h8i\n" />
|
app:layout_constraintRight_toRightOf="@+id/input_title_view"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/input_title_view" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:text="Add Galleries"
|
android:id="@+id/btn_add_galleries"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/btn_add_galleries"
|
android:text="Add Galleries"
|
||||||
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
app:layout_constraintLeft_toLeftOf="@+id/galleries_box"
|
app:layout_constraintLeft_toLeftOf="@+id/galleries_box"
|
||||||
app:layout_constraintRight_toRightOf="@+id/galleries_box" />
|
app:layout_constraintRight_toRightOf="@+id/galleries_box" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/progress_title_view"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginLeft="0dp"
|
||||||
|
android:layout_marginRight="0dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="0dp"
|
||||||
|
android:text="Adding galleries..."
|
||||||
|
android:textAppearance="@style/TextAppearance.Medium.Title"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_bar"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="0dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/progress_dismiss_btn"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintLeft_toLeftOf="@+id/progress_log_wrapper"
|
||||||
|
app:layout_constraintRight_toLeftOf="@+id/progress_text" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/progress_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="end"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text=""
|
||||||
|
android:textAlignment="textEnd"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintRight_toRightOf="@+id/progress_log_wrapper"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/progress_bar" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/progress_dismiss_btn"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="0dp"
|
||||||
|
android:layout_marginRight="0dp"
|
||||||
|
android:text="Finish"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintLeft_toLeftOf="@+id/progress_log_wrapper"
|
||||||
|
app:layout_constraintRight_toRightOf="@+id/progress_log_wrapper"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/btn_add_galleries"
|
||||||
|
android:layout_marginBottom="0dp" />
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/progress_log_wrapper"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/progress_bar"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintLeft_toLeftOf="@+id/progress_title_view"
|
||||||
|
app:layout_constraintRight_toRightOf="@+id/progress_title_view"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/progress_title_view"
|
||||||
|
app:layout_constraintVertical_bias="0.0">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/progress_log"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.Body1"
|
||||||
|
android:visibility="visible" />
|
||||||
|
</ScrollView>
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
|
@ -101,48 +101,4 @@
|
|||||||
<item>1</item>
|
<item>1</item>
|
||||||
<item>2</item>
|
<item>2</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<!-- EH -->
|
|
||||||
<string-array name="ehentai_quality">
|
|
||||||
<item>Auto</item>
|
|
||||||
<item>2400x</item>
|
|
||||||
<item>1600x</item>
|
|
||||||
<item>1280x</item>
|
|
||||||
<item>980x</item>
|
|
||||||
<item>780x</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="ehentai_quality_values">
|
|
||||||
<item>auto</item>
|
|
||||||
<item>ovrs_2400</item>
|
|
||||||
<item>ovrs_1600</item>
|
|
||||||
<item>high</item>
|
|
||||||
<item>med</item>
|
|
||||||
<item>low</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<string-array name="ehentai_search_result_count">
|
|
||||||
<item>25 results</item>
|
|
||||||
<item>50 results</item>
|
|
||||||
<item>100 results</item>
|
|
||||||
<item>200 results</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="ehentai_search_result_count_values">
|
|
||||||
<item>rc_0</item>
|
|
||||||
<item>rc_1</item>
|
|
||||||
<item>rc_2</item>
|
|
||||||
<item>rc_3</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<string-array name="ehentai_thumbnail_rows">
|
|
||||||
<item>4</item>
|
|
||||||
<item>10 (requires \'More Thumbs\' hath perk)</item>
|
|
||||||
<item>20 (requires \'Thumbs Up\' hath perk)</item>
|
|
||||||
<item>40 (requires \'All Thumbs\' hath perk)</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="ehentai_thumbnail_rows_values">
|
|
||||||
<item>tr_2</item>
|
|
||||||
<item>tr_5</item>
|
|
||||||
<item>tr_10</item>
|
|
||||||
<item>tr_20</item>
|
|
||||||
</string-array>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package eu.kanade.tachiyomi
|
package eu.kanade.tachiyomi
|
||||||
|
|
||||||
import org.robolectric.RobolectricTestRunner
|
//import org.robolectric.RobolectricTestRunner
|
||||||
import org.robolectric.annotation.Config
|
//import org.robolectric.annotation.Config
|
||||||
import org.robolectric.manifest.AndroidManifest
|
//import org.robolectric.manifest.AndroidManifest
|
||||||
|
|
||||||
class CustomRobolectricGradleTestRunner(klass: Class<*>) : RobolectricTestRunner(klass) {
|
//class CustomRobolectricGradleTestRunner(klass: Class<*>) : RobolectricTestRunner(klass) {
|
||||||
|
|
||||||
override fun getAppManifest(config: Config): AndroidManifest {
|
// override fun getAppManifest(config: Config): AndroidManifest {
|
||||||
return super.getAppManifest(config).apply { packageName = "eu.kanade.tachiyomi" }
|
// return super.getAppManifest(config).apply { packageName = "eu.kanade.tachiyomi" }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
Loading…
x
Reference in New Issue
Block a user