mirror of
https://github.com/mihonapp/mihon.git
synced 2025-03-13 16:20:08 +01:00
Add fingerprint to lock UI
Migrate login UI to conductor Fix batch add controller not saving EditText content onResume Prevent double-locking of lock UI Remove back button from lock UI Fix login preference not updating
This commit is contained in:
parent
32d02f9329
commit
b20b3d6f5c
@ -219,9 +219,16 @@ dependencies {
|
||||
//JVE (Regex) (EH)
|
||||
compile 'ru.lanwen.verbalregex:java-verbal-expressions:1.4'
|
||||
|
||||
//Pin lock view
|
||||
//Pin lock view (EXH)
|
||||
compile 'com.andrognito.pinlockview:pinlockview:1.0.1'
|
||||
|
||||
//Reprint (EXH)
|
||||
compile 'com.github.ajalt.reprint:core:3.1.0@aar' // required: supports marshmallow devices
|
||||
compile 'com.github.ajalt.reprint:rxjava:3.1.0@aar' // optional: the RxJava 1 interface
|
||||
|
||||
//Swirl (EXH)
|
||||
compile 'com.mattprecious.swirl:swirl:1.0.0'
|
||||
|
||||
// Tests
|
||||
//Paper DB screws up tests
|
||||
/*testCompile 'junit:junit:4.12'
|
||||
|
@ -10,6 +10,7 @@
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.GET_TASKS"/>
|
||||
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
@ -106,7 +107,7 @@
|
||||
|
||||
<!-- EH -->
|
||||
<activity
|
||||
android:name="exh.ui.login.LoginActivity"
|
||||
android:name="exh.ui.login.LoginController"
|
||||
android:label="@string/label_login">
|
||||
<!-- TODO parent activity -->
|
||||
</activity>
|
||||
|
@ -5,6 +5,7 @@ import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.support.multidex.MultiDex
|
||||
import com.evernote.android.job.JobManager
|
||||
import com.github.ajalt.reprint.core.Reprint
|
||||
import eu.kanade.tachiyomi.data.backup.BackupCreatorJob
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
||||
import eu.kanade.tachiyomi.data.updater.UpdateCheckerJob
|
||||
@ -26,6 +27,7 @@ open class App : Application() {
|
||||
|
||||
setupJobManager()
|
||||
Paper.init(this) //Setup metadata DB (EH)
|
||||
Reprint.initialize(this) //Setup fingerprint (EH)
|
||||
|
||||
LocaleHelper.updateConfiguration(this, resources.configuration)
|
||||
}
|
||||
|
@ -199,5 +199,7 @@ class PreferencesHelper(val context: Context) {
|
||||
fun lockSalt() = rxPrefs.getString("lock_salt", null)
|
||||
|
||||
fun lockLength() = rxPrefs.getInteger("lock_length", -1)
|
||||
|
||||
fun lockUseFingerprint() = rxPrefs.getBoolean("lock_finger", false)
|
||||
// <-- EH
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import rx.Observable
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.net.URLEncoder
|
||||
import java.util.*
|
||||
import exh.ui.login.LoginActivity
|
||||
import exh.ui.login.LoginController
|
||||
import exh.util.UriFilter
|
||||
import exh.util.UriGroup
|
||||
import okhttp3.CacheControl
|
||||
@ -323,9 +323,9 @@ class EHentai(override val id: Long,
|
||||
val cookiesHeader by lazy {
|
||||
val cookies: MutableMap<String, String> = mutableMapOf()
|
||||
if(prefs.enableExhentai().getOrDefault()) {
|
||||
cookies.put(LoginActivity.MEMBER_ID_COOKIE, prefs.memberIdVal().get()!!)
|
||||
cookies.put(LoginActivity.PASS_HASH_COOKIE, prefs.passHashVal().get()!!)
|
||||
cookies.put(LoginActivity.IGNEOUS_COOKIE, prefs.igneousVal().get()!!)
|
||||
cookies.put(LoginController.MEMBER_ID_COOKIE, prefs.memberIdVal().get()!!)
|
||||
cookies.put(LoginController.PASS_HASH_COOKIE, prefs.passHashVal().get()!!)
|
||||
cookies.put(LoginController.IGNEOUS_COOKIE, prefs.igneousVal().get()!!)
|
||||
}
|
||||
|
||||
//Setup settings
|
||||
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.main
|
||||
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.graphics.Color
|
||||
@ -15,8 +14,6 @@ import android.support.v7.graphics.drawable.DrawerArrowDrawable
|
||||
import android.view.ViewGroup
|
||||
import com.bluelinelabs.conductor.*
|
||||
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.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
@ -40,7 +37,6 @@ import exh.ui.lock.lockEnabled
|
||||
import exh.ui.lock.notifyLockSecurity
|
||||
import kotlinx.android.synthetic.main.main_activity.*
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.*
|
||||
|
||||
|
||||
class MainActivity : BaseActivity() {
|
||||
@ -49,7 +45,7 @@ class MainActivity : BaseActivity() {
|
||||
|
||||
val preferences: PreferencesHelper by injectLazy()
|
||||
|
||||
private var drawerArrow: DrawerArrowDrawable? = null
|
||||
var drawerArrow: DrawerArrowDrawable? = null
|
||||
|
||||
private var secondaryDrawer: ViewGroup? = null
|
||||
|
||||
@ -153,6 +149,8 @@ class MainActivity : BaseActivity() {
|
||||
if (savedInstanceState == null) {
|
||||
val lockEnabled = lockEnabled(preferences)
|
||||
if (lockEnabled) {
|
||||
//Special case first lock
|
||||
toolbar.navigationIcon = null
|
||||
doLock()
|
||||
|
||||
//Check lock security
|
||||
@ -236,6 +234,16 @@ class MainActivity : BaseActivity() {
|
||||
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||
}
|
||||
|
||||
// --> EH
|
||||
//Special case and hide drawer arrow for lock controller
|
||||
if(to is LockController) {
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(false)
|
||||
} else {
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
toolbar.navigationIcon = drawerArrow
|
||||
}
|
||||
// <-- EH
|
||||
|
||||
ObjectAnimator.ofFloat(drawerArrow, "progress", if (showHamburger) 0f else 1f).start()
|
||||
|
||||
if (from is TabbedController) {
|
||||
@ -270,10 +278,9 @@ class MainActivity : BaseActivity() {
|
||||
// --> EH
|
||||
//Lock code
|
||||
var willLock = false
|
||||
var disableLock = false
|
||||
override fun onRestart() {
|
||||
super.onRestart()
|
||||
if(willLock && lockEnabled() && !disableLock) {
|
||||
if(willLock && lockEnabled()) {
|
||||
doLock()
|
||||
}
|
||||
|
||||
@ -286,6 +293,10 @@ class MainActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
fun tryLock() {
|
||||
//Do not double-lock
|
||||
if(router.backstack.lastOrNull()?.controller() is LockController)
|
||||
return
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
val mUsageStatsManager = getSystemService("usagestats") as UsageStatsManager
|
||||
val time = System.currentTimeMillis()
|
||||
|
@ -1,9 +1,11 @@
|
||||
package eu.kanade.tachiyomi.ui.setting
|
||||
|
||||
import android.content.Intent
|
||||
import android.support.v7.preference.PreferenceScreen
|
||||
import com.bluelinelabs.conductor.RouterTransaction
|
||||
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
||||
import exh.ui.migration.MetadataFetchDialog
|
||||
import exh.ui.login.LoginActivity
|
||||
import exh.ui.login.LoginController
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
|
||||
/**
|
||||
* EH Settings fragment
|
||||
@ -20,9 +22,11 @@ class SettingsEhController : SettingsController() {
|
||||
isPersistent = false
|
||||
defaultValue = false
|
||||
preferences.enableExhentai()
|
||||
.asObservable().subscribeUntilDestroy {
|
||||
.asObservable()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeUntilDestroy {
|
||||
isChecked = it
|
||||
}
|
||||
}
|
||||
|
||||
onChange { newVal ->
|
||||
newVal as Boolean
|
||||
@ -30,7 +34,9 @@ class SettingsEhController : SettingsController() {
|
||||
preferences.enableExhentai().set(false)
|
||||
true
|
||||
} else {
|
||||
startActivity(Intent(context, LoginActivity::class.java))
|
||||
router.pushController(RouterTransaction.with(LoginController())
|
||||
.pushChangeHandler(FadeChangeHandler())
|
||||
.popChangeHandler(FadeChangeHandler()))
|
||||
false
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.support.v7.preference.PreferenceScreen
|
||||
import android.support.v7.preference.SwitchPreference
|
||||
import android.view.View
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import eu.kanade.tachiyomi.R
|
||||
@ -13,6 +14,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.util.LocaleHelper
|
||||
import exh.ui.lock.FingerLockPreference
|
||||
import exh.ui.lock.LockPreference
|
||||
import kotlinx.android.synthetic.main.pref_library_columns.view.*
|
||||
import rx.Observable
|
||||
@ -176,12 +178,25 @@ class SettingsGeneralController : SettingsController() {
|
||||
true
|
||||
}
|
||||
}
|
||||
LockPreference(context).apply {
|
||||
key = "pref_app_lock"
|
||||
preferenceCategory {
|
||||
title = "Application lock"
|
||||
isPersistent = false
|
||||
|
||||
addPreference(this)
|
||||
LockPreference(context).apply {
|
||||
key = "pref_app_lock"
|
||||
isPersistent = false
|
||||
|
||||
addPreference(this)
|
||||
}
|
||||
|
||||
FingerLockPreference(context).apply {
|
||||
key = "pref_lock_finger"
|
||||
isPersistent = false
|
||||
|
||||
addPreference(this)
|
||||
|
||||
//Call after addPreference
|
||||
dependency = "pref_app_lock"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ class BatchAddController : NucleusController<BatchAddPresenter>() {
|
||||
}
|
||||
|
||||
progress_dismiss_btn.clicks().subscribeUntilDestroy {
|
||||
presenter.currentlyAddingRelay.call(false)
|
||||
presenter.currentlyAddingRelay.call(BatchAddPresenter.STATE_PROGRESS_TO_INPUT)
|
||||
}
|
||||
|
||||
val progressSubscriptions = CompositeSubscription()
|
||||
@ -44,7 +44,7 @@ class BatchAddController : NucleusController<BatchAddPresenter>() {
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeUntilDestroy {
|
||||
progressSubscriptions.clear()
|
||||
if(it) {
|
||||
if(it == BatchAddPresenter.STATE_INPUT_TO_PROGRESS) {
|
||||
showProgress(this)
|
||||
progressSubscriptions += presenter.progressRelay
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -79,7 +79,10 @@ class BatchAddController : NucleusController<BatchAddPresenter>() {
|
||||
}?.let {
|
||||
progressSubscriptions += it
|
||||
}
|
||||
} else hideProgress(this)
|
||||
} else if(it == BatchAddPresenter.STATE_PROGRESS_TO_INPUT) {
|
||||
hideProgress(this)
|
||||
presenter.currentlyAddingRelay.call(BatchAddPresenter.STATE_IDLE)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,18 +15,18 @@ class BatchAddPresenter: BasePresenter<BatchAddController>() {
|
||||
val progressTotalRelay = BehaviorRelay.create(0)!!
|
||||
val progressRelay = BehaviorRelay.create(0)!!
|
||||
var eventRelay: ReplayRelay<String>? = null
|
||||
val currentlyAddingRelay = BehaviorRelay.create(false)!!
|
||||
val currentlyAddingRelay = BehaviorRelay.create(STATE_IDLE)!!
|
||||
|
||||
fun addGalleries(galleries: String) {
|
||||
eventRelay = ReplayRelay.create()
|
||||
val splitGalleries = galleries.split("\n").map {
|
||||
val splitGalleries = galleries.split("\n").mapNotNull {
|
||||
it.trim().nullIfBlank()
|
||||
}.filterNotNull()
|
||||
}
|
||||
|
||||
progressRelay.call(0)
|
||||
progressTotalRelay.call(splitGalleries.size)
|
||||
|
||||
currentlyAddingRelay.call(true)
|
||||
currentlyAddingRelay.call(STATE_INPUT_TO_PROGRESS)
|
||||
|
||||
thread {
|
||||
val succeeded = mutableListOf<String>()
|
||||
@ -48,4 +48,10 @@ class BatchAddPresenter: BasePresenter<BatchAddController>() {
|
||||
eventRelay?.call(summary)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val STATE_IDLE = 0
|
||||
const val STATE_INPUT_TO_PROGRESS = 1
|
||||
const val STATE_PROGRESS_TO_INPUT = 2
|
||||
}
|
||||
}
|
||||
|
149
app/src/main/java/exh/ui/lock/FingerLockPreference.kt
Normal file
149
app/src/main/java/exh/ui/lock/FingerLockPreference.kt
Normal file
@ -0,0 +1,149 @@
|
||||
package exh.ui.lock
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.support.v7.preference.SwitchPreferenceCompat
|
||||
import android.support.v7.widget.LinearLayoutCompat
|
||||
import android.util.AttributeSet
|
||||
import android.view.Gravity
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.github.ajalt.reprint.core.AuthenticationResult
|
||||
import com.github.ajalt.reprint.core.Reprint
|
||||
import com.github.ajalt.reprint.rxjava.RxReprint
|
||||
import com.mattprecious.swirl.SwirlView
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.setting.onChange
|
||||
import exh.util.dpToPx
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class FingerLockPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
SwitchPreferenceCompat(context, attrs) {
|
||||
|
||||
val prefs: PreferencesHelper by injectLazy()
|
||||
|
||||
val fingerprintSupported
|
||||
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& Reprint.isHardwarePresent()
|
||||
&& Reprint.hasFingerprintRegistered()
|
||||
|
||||
val useFingerprint
|
||||
get() = fingerprintSupported
|
||||
&& prefs.lockUseFingerprint().getOrDefault()
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
override fun onAttached() {
|
||||
super.onAttached()
|
||||
if(fingerprintSupported) {
|
||||
updateSummary()
|
||||
onChange {
|
||||
if(it as Boolean)
|
||||
tryChange()
|
||||
else
|
||||
prefs.lockUseFingerprint().set(false)
|
||||
!it
|
||||
}
|
||||
} else {
|
||||
title = "Fingerprint unsupported"
|
||||
shouldDisableView = true
|
||||
summary = if(!Reprint.hasFingerprintRegistered())
|
||||
"No fingerprints enrolled!"
|
||||
else
|
||||
"Fingerprint unlock is unsupported on this device!"
|
||||
onChange { false }
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSummary() {
|
||||
isChecked = useFingerprint
|
||||
title = if(isChecked)
|
||||
"Fingerprint enabled"
|
||||
else
|
||||
"Fingerprint disabled"
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.M)
|
||||
fun tryChange() {
|
||||
val statusTextView = TextView(context).apply {
|
||||
text = "Please touch the fingerprint sensor"
|
||||
val size = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
layoutParams = (layoutParams ?: ViewGroup.LayoutParams(
|
||||
size, size
|
||||
)).apply {
|
||||
width = size
|
||||
height = size
|
||||
setPadding(0, 0, dpToPx(context, 8), 0)
|
||||
}
|
||||
}
|
||||
val iconView = SwirlView(context).apply {
|
||||
val size = dpToPx(context, 30)
|
||||
layoutParams = (layoutParams ?: ViewGroup.LayoutParams(
|
||||
size, size
|
||||
)).apply {
|
||||
width = size
|
||||
height = size
|
||||
}
|
||||
setState(SwirlView.State.OFF, false)
|
||||
}
|
||||
val linearLayout = LinearLayoutCompat(context).apply {
|
||||
orientation = LinearLayoutCompat.HORIZONTAL
|
||||
gravity = Gravity.CENTER_VERTICAL
|
||||
val size = LinearLayoutCompat.LayoutParams.WRAP_CONTENT
|
||||
layoutParams = (layoutParams ?: LinearLayoutCompat.LayoutParams(
|
||||
size, size
|
||||
)).apply {
|
||||
width = size
|
||||
height = size
|
||||
val pSize = dpToPx(context, 24)
|
||||
setPadding(pSize, 0, pSize, 0)
|
||||
}
|
||||
|
||||
addView(statusTextView)
|
||||
addView(iconView)
|
||||
}
|
||||
val dialog = MaterialDialog.Builder(context)
|
||||
.title("Fingerprint verification")
|
||||
.customView(linearLayout, false)
|
||||
.negativeText("Cancel")
|
||||
.autoDismiss(true)
|
||||
.cancelable(true)
|
||||
.canceledOnTouchOutside(true)
|
||||
.show()
|
||||
iconView.setState(SwirlView.State.ON)
|
||||
val subscription = RxReprint.authenticate()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { result ->
|
||||
when (result.status) {
|
||||
AuthenticationResult.Status.SUCCESS -> {
|
||||
iconView.setState(SwirlView.State.ON)
|
||||
prefs.lockUseFingerprint().set(true)
|
||||
dialog.dismiss()
|
||||
updateSummary()
|
||||
}
|
||||
AuthenticationResult.Status.NONFATAL_FAILURE -> {
|
||||
iconView.setState(SwirlView.State.ERROR)
|
||||
statusTextView.text = result.errorMessage
|
||||
}
|
||||
AuthenticationResult.Status.FATAL_FAILURE, null -> {
|
||||
MaterialDialog.Builder(context)
|
||||
.title("Fingerprint verification failed!")
|
||||
.content(result.errorMessage)
|
||||
.positiveText("Ok")
|
||||
.autoDismiss(true)
|
||||
.cancelable(true)
|
||||
.canceledOnTouchOutside(false)
|
||||
.show()
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
dialog.setOnDismissListener {
|
||||
subscription.unsubscribe()
|
||||
}
|
||||
}
|
||||
}
|
@ -23,8 +23,8 @@ class LockChangeHandler : AnimatorChangeHandler {
|
||||
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.SCALE_X, 3f))
|
||||
viewAnimators.add(ObjectAnimator.ofFloat(from, View.SCALE_Y, 3f))
|
||||
viewAnimators.add(ObjectAnimator.ofFloat(from, View.ALPHA, 0f))
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,35 @@
|
||||
package exh.ui.lock
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.support.v4.hardware.fingerprint.FingerprintManagerCompat
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.CardView
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.andrognito.pinlockview.PinLockListener
|
||||
import com.github.ajalt.reprint.core.AuthenticationResult
|
||||
import com.github.ajalt.reprint.core.Reprint
|
||||
import com.github.ajalt.reprint.rxjava.RxReprint
|
||||
import com.mattprecious.swirl.SwirlView
|
||||
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 eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import exh.util.dpToPx
|
||||
import kotlinx.android.synthetic.main.activity_lock.view.*
|
||||
import kotlinx.android.synthetic.main.main_activity.view.*
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class LockController : NucleusController<LockPresenter>() {
|
||||
|
||||
val prefs: PreferencesHelper by injectLazy()
|
||||
|
||||
override fun inflateView(inflater: LayoutInflater, container: ViewGroup)
|
||||
= inflater.inflate(R.layout.activity_lock, container, false)!!
|
||||
|
||||
@ -21,8 +37,6 @@ class LockController : NucleusController<LockPresenter>() {
|
||||
|
||||
override fun getTitle() = "Application locked"
|
||||
|
||||
val prefs: PreferencesHelper by injectLazy()
|
||||
|
||||
override fun onViewCreated(view: View, savedViewState: Bundle?) {
|
||||
super.onViewCreated(view, savedViewState)
|
||||
|
||||
@ -32,6 +46,7 @@ class LockController : NucleusController<LockPresenter>() {
|
||||
}
|
||||
|
||||
with(view) {
|
||||
//Setup pin lock
|
||||
pin_lock_view.attachIndicatorDots(indicator_dots)
|
||||
|
||||
pin_lock_view.pinLength = prefs.lockLength().getOrDefault()
|
||||
@ -60,6 +75,61 @@ class LockController : NucleusController<LockPresenter>() {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
override fun onAttach(view: View) {
|
||||
super.onAttach(view)
|
||||
|
||||
with(view) {
|
||||
//Fingerprint
|
||||
if (presenter.useFingerprint) {
|
||||
swirl_container.removeAllViews()
|
||||
val icon = SwirlView(context).apply {
|
||||
val size = dpToPx(context, 60)
|
||||
layoutParams = (layoutParams ?: ViewGroup.LayoutParams(
|
||||
size, size
|
||||
)).apply {
|
||||
width = size
|
||||
height = size
|
||||
|
||||
val pSize = dpToPx(context, 8)
|
||||
setPadding(pSize, pSize, pSize, pSize)
|
||||
}
|
||||
val typedVal = TypedValue()
|
||||
activity!!.theme!!.resolveAttribute(android.R.attr.windowBackground, typedVal, true)
|
||||
setBackgroundColor(typedVal.data)
|
||||
//Disable elevation if dark theme is active
|
||||
if (typedVal.data == resources.getColor(R.color.backgroundDark, activity!!.theme!!))
|
||||
this@with.swirl_container.cardElevation = 0f
|
||||
setState(SwirlView.State.OFF, false)
|
||||
}
|
||||
swirl_container.addView(icon)
|
||||
icon.setState(SwirlView.State.ON)
|
||||
RxReprint.authenticate()
|
||||
.subscribeUntilDetach {
|
||||
when (it.status) {
|
||||
AuthenticationResult.Status.SUCCESS -> closeLock()
|
||||
AuthenticationResult.Status.NONFATAL_FAILURE -> icon.setState(SwirlView.State.ERROR)
|
||||
AuthenticationResult.Status.FATAL_FAILURE, null -> {
|
||||
MaterialDialog.Builder(context)
|
||||
.title("Fingerprint error!")
|
||||
.content(it.errorMessage)
|
||||
.cancelable(false)
|
||||
.canceledOnTouchOutside(false)
|
||||
.positiveText("Ok")
|
||||
.autoDismiss(true)
|
||||
.show()
|
||||
icon.setState(SwirlView.State.OFF)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetach(view: View) {
|
||||
super.onDetach(view)
|
||||
}
|
||||
|
||||
fun closeLock() {
|
||||
router.popCurrentController()
|
||||
}
|
||||
|
@ -2,11 +2,14 @@ package exh.ui.lock
|
||||
|
||||
import android.content.Context
|
||||
import android.support.v7.preference.Preference
|
||||
import android.support.v7.preference.SwitchPreference
|
||||
import android.support.v7.preference.SwitchPreferenceCompat
|
||||
import android.text.InputType
|
||||
import android.util.AttributeSet
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.ui.setting.onChange
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import rx.schedulers.Schedulers
|
||||
@ -15,7 +18,7 @@ import java.math.BigInteger
|
||||
import java.security.SecureRandom
|
||||
|
||||
class LockPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
Preference(context, attrs) {
|
||||
SwitchPreferenceCompat(context, attrs) {
|
||||
|
||||
private val secureRandom by lazy { SecureRandom() }
|
||||
|
||||
@ -24,17 +27,24 @@ class LockPreference @JvmOverloads constructor(context: Context, attrs: Attribut
|
||||
override fun onAttached() {
|
||||
super.onAttached()
|
||||
updateSummary()
|
||||
onChange {
|
||||
tryChange()
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSummary() {
|
||||
summary = if(lockEnabled(prefs))
|
||||
"Application is locked"
|
||||
else
|
||||
"Application is not locked, tap to lock"
|
||||
isChecked = lockEnabled(prefs)
|
||||
if(isChecked) {
|
||||
title = "Lock enabled"
|
||||
summary = "Tap to disable or change pin code"
|
||||
} else {
|
||||
title = "Lock disabled"
|
||||
summary = "Tap to enable"
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick() {
|
||||
super.onClick()
|
||||
fun tryChange() {
|
||||
if(!notifyLockSecurity(context)) {
|
||||
MaterialDialog.Builder(context)
|
||||
.title("Lock application")
|
||||
|
@ -1,6 +1,19 @@
|
||||
package exh.ui.lock
|
||||
|
||||
import android.os.Build
|
||||
import com.github.ajalt.reprint.core.Reprint
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class LockPresenter: BasePresenter<LockController>()
|
||||
class LockPresenter: BasePresenter<LockController>() {
|
||||
val prefs: PreferencesHelper by injectLazy()
|
||||
|
||||
val useFingerprint
|
||||
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& Reprint.isHardwarePresent()
|
||||
&& Reprint.hasFingerprintRegistered()
|
||||
&& prefs.lockUseFingerprint().getOrDefault()
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,9 @@ package exh.ui.login
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.CookieManager
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
@ -12,9 +14,9 @@ import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.online.all.EHentai
|
||||
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||
import exh.EXH_SOURCE_ID
|
||||
import kotlinx.android.synthetic.main.eh_activity_login.*
|
||||
import kotlinx.android.synthetic.main.eh_activity_login.view.*
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import rx.schedulers.Schedulers
|
||||
@ -23,70 +25,75 @@ import uy.kohesive.injekt.injectLazy
|
||||
import java.net.HttpCookie
|
||||
|
||||
/**
|
||||
* LoginActivity
|
||||
* LoginController
|
||||
*/
|
||||
|
||||
class LoginActivity : BaseActivity() {
|
||||
|
||||
class LoginController : NucleusController<LoginPresenter>() {
|
||||
val preferenceManager: PreferencesHelper by injectLazy()
|
||||
|
||||
val sourceManager: SourceManager by injectLazy()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.eh_activity_login)
|
||||
override fun getTitle() = "ExHentai login"
|
||||
|
||||
setup()
|
||||
}
|
||||
override fun createPresenter() = LoginPresenter()
|
||||
|
||||
fun setup() {
|
||||
btn_cancel.setOnClickListener { onBackPressed() }
|
||||
btn_recheck.setOnClickListener { webview.loadUrl("http://exhentai.org/") }
|
||||
override fun inflateView(inflater: LayoutInflater, container: ViewGroup) =
|
||||
inflater.inflate(R.layout.eh_activity_login, container, false)!!
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
CookieManager.getInstance().removeAllCookies {
|
||||
runOnUiThread {
|
||||
startWebview()
|
||||
override fun onViewCreated(view: View, savedViewState: Bundle?) {
|
||||
super.onViewCreated(view, savedViewState)
|
||||
|
||||
with(view) {
|
||||
btn_cancel.setOnClickListener { router.popCurrentController() }
|
||||
btn_recheck.setOnClickListener { webview.loadUrl("http://exhentai.org/") }
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
CookieManager.getInstance().removeAllCookies {
|
||||
Observable.fromCallable {
|
||||
startWebview(view)
|
||||
}.subscribeOn(AndroidSchedulers.mainThread()).subscribe()
|
||||
}
|
||||
} else {
|
||||
CookieManager.getInstance().removeAllCookie()
|
||||
startWebview(view)
|
||||
}
|
||||
} else {
|
||||
CookieManager.getInstance().removeAllCookie()
|
||||
startWebview()
|
||||
}
|
||||
}
|
||||
|
||||
fun startWebview() {
|
||||
webview.settings.javaScriptEnabled = true
|
||||
webview.settings.domStorageEnabled = true
|
||||
fun startWebview(view: View) {
|
||||
with(view) {
|
||||
webview.settings.javaScriptEnabled = true
|
||||
webview.settings.domStorageEnabled = true
|
||||
|
||||
webview.loadUrl("https://forums.e-hentai.org/index.php?act=Login")
|
||||
webview.loadUrl("https://forums.e-hentai.org/index.php?act=Login")
|
||||
|
||||
webview.setWebViewClient(object : WebViewClient() {
|
||||
override fun onPageFinished(view: WebView, url: String) {
|
||||
super.onPageFinished(view, url)
|
||||
Timber.d(url)
|
||||
val parsedUrl = Uri.parse(url)
|
||||
if(parsedUrl.host.equals("forums.e-hentai.org", ignoreCase = true)) {
|
||||
//Hide distracting content
|
||||
view.loadUrl(HIDE_JS)
|
||||
webview.setWebViewClient(object : WebViewClient() {
|
||||
override fun onPageFinished(view: WebView, url: String) {
|
||||
super.onPageFinished(view, url)
|
||||
Timber.d(url)
|
||||
val parsedUrl = Uri.parse(url)
|
||||
if (parsedUrl.host.equals("forums.e-hentai.org", ignoreCase = true)) {
|
||||
//Hide distracting content
|
||||
view.loadUrl(HIDE_JS)
|
||||
|
||||
//Check login result
|
||||
if(parsedUrl.getQueryParameter("code")?.toInt() != 0) {
|
||||
if(checkLoginCookies(url)) view.loadUrl("http://exhentai.org/")
|
||||
}
|
||||
} else if(parsedUrl.host.equals("exhentai.org", ignoreCase = true)) {
|
||||
//At ExHentai, check that everything worked out...
|
||||
if(applyExHentaiCookies(url)) {
|
||||
preferenceManager.enableExhentai().set(true)
|
||||
finishLogin()
|
||||
//Check login result
|
||||
if (parsedUrl.getQueryParameter("code")?.toInt() != 0) {
|
||||
if (checkLoginCookies(url)) view.loadUrl("http://exhentai.org/")
|
||||
}
|
||||
} else if (parsedUrl.host.equals("exhentai.org", ignoreCase = true)) {
|
||||
//At ExHentai, check that everything worked out...
|
||||
if (applyExHentaiCookies(url)) {
|
||||
preferenceManager.enableExhentai().set(true)
|
||||
finishLogin(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fun finishLogin() {
|
||||
val progressDialog = MaterialDialog.Builder(this)
|
||||
fun finishLogin(view: View) {
|
||||
val progressDialog = MaterialDialog.Builder(view.context)
|
||||
.title("Finalizing login")
|
||||
.progress(true, 0)
|
||||
.content("Please wait...")
|
||||
@ -108,7 +115,7 @@ class LoginActivity : BaseActivity() {
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
progressDialog.dismiss()
|
||||
onBackPressed()
|
||||
router.popCurrentController()
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,14 +171,6 @@ class LoginActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> onBackPressed()
|
||||
else -> return super.onOptionsItemSelected(item)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MEMBER_ID_COOKIE = "ipb_member_id"
|
||||
const val PASS_HASH_COOKIE = "ipb_pass_hash"
|
7
app/src/main/java/exh/ui/login/LoginPresenter.kt
Normal file
7
app/src/main/java/exh/ui/login/LoginPresenter.kt
Normal file
@ -0,0 +1,7 @@
|
||||
package exh.ui.login
|
||||
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
|
||||
class LoginPresenter: BasePresenter<LoginController>() {
|
||||
|
||||
}
|
8
app/src/main/java/exh/util/ViewUtil.kt
Normal file
8
app/src/main/java/exh/util/ViewUtil.kt
Normal file
@ -0,0 +1,8 @@
|
||||
package exh.util
|
||||
|
||||
import android.content.Context
|
||||
|
||||
fun dpToPx(context: Context, dp: Int): Int {
|
||||
val scale = context.resources.displayMetrics.density
|
||||
return (dp * scale + 0.5f).toInt()
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
android:background="@color/backgroundDark">
|
||||
|
||||
<com.andrognito.pinlockview.PinLockView
|
||||
@ -26,4 +27,19 @@
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
android:id="@+id/swirl_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
card_view:cardCornerRadius="30dp"
|
||||
card_view:cardElevation="4dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent">
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
</android.support.constraint.ConstraintLayout>
|
@ -11,7 +11,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:animateLayoutChanges="true"
|
||||
android:padding="16dp ">
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/input_title_view"
|
||||
@ -19,7 +19,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Enter the galleries to add (separated by a new line):"
|
||||
android:textAppearance="@style/TextAppearance.Medium.Title"
|
||||
android:visibility="gone"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@ -31,7 +31,7 @@
|
||||
android:ems="10"
|
||||
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:inputType="textMultiLine"
|
||||
android:visibility="gone"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btn_add_galleries"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/input_title_view"
|
||||
app:layout_constraintRight_toRightOf="@+id/input_title_view"
|
||||
@ -42,7 +42,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Add Galleries"
|
||||
android:visibility="gone"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/galleries_box"
|
||||
app:layout_constraintRight_toRightOf="@+id/galleries_box" />
|
||||
@ -58,7 +58,7 @@
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="Adding galleries..."
|
||||
android:textAppearance="@style/TextAppearance.Medium.Title"
|
||||
android:visibility="visible"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@ -71,7 +71,7 @@
|
||||
android:layout_marginBottom="0dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:visibility="visible"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toTopOf="@+id/progress_dismiss_btn"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/progress_log_wrapper"
|
||||
@ -85,7 +85,7 @@
|
||||
android:singleLine="true"
|
||||
android:text=""
|
||||
android:textAlignment="textEnd"
|
||||
android:visibility="visible"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintRight_toRightOf="@+id/progress_log_wrapper"
|
||||
app:layout_constraintTop_toTopOf="@+id/progress_bar" />
|
||||
|
||||
@ -93,15 +93,15 @@
|
||||
android:id="@+id/progress_dismiss_btn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="0dp"
|
||||
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"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/btn_add_galleries"
|
||||
android:layout_marginBottom="0dp" />
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/progress_log_wrapper"
|
||||
app:layout_constraintRight_toRightOf="@+id/progress_log_wrapper" />
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/progress_log_wrapper"
|
||||
@ -109,7 +109,7 @@
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:visibility="visible"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toTopOf="@+id/progress_bar"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/progress_title_view"
|
||||
|
@ -24,6 +24,10 @@
|
||||
<item name="android:divider">@color/dividerLight</item>
|
||||
<item name="android:listDivider">@drawable/line_divider_light</item>
|
||||
|
||||
<!-- Swirl (EH) -->
|
||||
<item name="swirl_ridgeColor">?android:attr/textColorSecondary</item>
|
||||
<item name="swirl_errorColor">?android:attr/colorAccent</item>
|
||||
|
||||
<!-- Themes -->
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
<item name="actionBarTheme">@style/Theme.ActionBar.Light</item>
|
||||
|
Loading…
x
Reference in New Issue
Block a user