mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +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:
		@@ -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()
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user