aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2018-12-31 18:57:28 -0500
committerGitHub <noreply@github.com>2018-12-31 18:57:28 -0500
commit149c6be1bfd4bd84381757940fece1be7b9801aa (patch)
tree85fe10e3ee3ea34ad717f0d61975ca0119dd36d5 /app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
parent7661bbfc9b8f34bf9d92dc08a9fcd7cc6ec7cbb3 (diff)
downloadfrost-149c6be1bfd4bd84381757940fece1be7b9801aa.tar.gz
frost-149c6be1bfd4bd84381757940fece1be7b9801aa.tar.bz2
frost-149c6be1bfd4bd84381757940fece1be7b9801aa.zip
Enhancement/coroutines (#1273)
* Convert rest of fbcookie to suspended methods * Replace active checks with yield * Apply spotless * Switch cookie domain to exact url * Optimize imports and enable travis tests again * Update proguard rules * Remove unnecessary yield * Remove unused flyweight * Remove unused disposable and method * Use contexthelper instead of dispatcher main * Convert login activity to coroutines * Use kau helper methods for coroutines * Enhancement/offline site (#1288) * Begin conversion of offline site logic * Fix offline tests and add validation tests * Ignore cookie in jsoup if it is blank * Force load and zip to be in io * Use different zip files to fix tests * Log all test output * Do not log stdout * Allow test skip for fb offline
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt169
1 files changed, 90 insertions, 79 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
index 8b5fe38d..9540636a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
@@ -18,7 +18,6 @@ package com.pitchedapps.frost.activities
import android.graphics.drawable.Drawable
import android.os.Bundle
-import android.os.Handler
import android.widget.ImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.appcompat.widget.Toolbar
@@ -26,6 +25,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import ca.allanwang.kau.utils.bindView
import ca.allanwang.kau.utils.fadeIn
import ca.allanwang.kau.utils.fadeOut
+import ca.allanwang.kau.utils.withMainContext
import com.bumptech.glide.RequestManager
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
@@ -34,7 +34,7 @@ import com.bumptech.glide.request.target.Target
import com.pitchedapps.frost.R
import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.dbflow.fetchUsername
-import com.pitchedapps.frost.dbflow.loadFbCookiesAsync
+import com.pitchedapps.frost.dbflow.loadFbCookiesSuspend
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.facebook.profilePictureUrl
import com.pitchedapps.frost.glide.FrostGlide
@@ -46,11 +46,16 @@ import com.pitchedapps.frost.utils.frostEvent
import com.pitchedapps.frost.utils.launchNewTask
import com.pitchedapps.frost.utils.logFrostEvent
import com.pitchedapps.frost.utils.setFrostColors
+import com.pitchedapps.frost.utils.uniqueOnly
import com.pitchedapps.frost.web.LoginWebView
-import io.reactivex.Single
-import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.functions.BiFunction
-import io.reactivex.subjects.SingleSubject
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.async
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.suspendCancellableCoroutine
+import kotlinx.coroutines.withContext
+import kotlin.coroutines.resume
/**
* Created by Allan Wang on 2017-06-01.
@@ -63,18 +68,8 @@ class LoginActivity : BaseActivity() {
private val textview: AppCompatTextView by bindView(R.id.textview)
private val profile: ImageView by bindView(R.id.profile)
- private val profileSubject = SingleSubject.create<Boolean>()
- private val usernameSubject = SingleSubject.create<String>()
private lateinit var profileLoader: RequestManager
-
- // Helper to set and enable swipeRefresh
- private var refresh: Boolean
- get() = swipeRefresh.isRefreshing
- set(value) {
- if (value) swipeRefresh.isEnabled = true
- swipeRefresh.isRefreshing = value
- if (!value) swipeRefresh.isEnabled = false
- }
+ private val refreshChannel = Channel<Boolean>(10)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -84,80 +79,96 @@ class LoginActivity : BaseActivity() {
setFrostColors {
toolbar(toolbar)
}
- web.loadLogin({ refresh = it != 100 }) { cookie ->
+ profileLoader = GlideApp.with(profile)
+ launch {
+ for (refreshing in refreshChannel.uniqueOnly(this)) {
+ if (refreshing) swipeRefresh.isEnabled = true
+ swipeRefresh.isRefreshing = refreshing
+ if (!refreshing) swipeRefresh.isEnabled = false
+ }
+ }
+ launch {
+ val cookie = web.loadLogin { refresh(it != 100) }
L.d { "Login found" }
FbCookie.save(cookie.id)
web.fadeOut(onFinish = {
profile.fadeIn()
- loadInfo(cookie)
+ launch { loadInfo(cookie) }
})
}
- profileLoader = GlideApp.with(profile)
}
- private fun loadInfo(cookie: CookieModel) {
- refresh = true
- Single.zip<Boolean, String, Pair<Boolean, String>>(
- profileSubject,
- usernameSubject,
- BiFunction(::Pair)
- )
- .observeOn(AndroidSchedulers.mainThread()).subscribe { (foundImage, name) ->
- refresh = false
- if (!foundImage) {
- L.e { "Could not get profile photo; Invalid userId?" }
- L._i { cookie }
- }
- textview.text = String.format(getString(R.string.welcome), name)
- textview.fadeIn()
- frostEvent("Login", "success" to true)
- /*
- * The user may have logged into an account that is already in the database
- * We will let the db handle duplicates and load it now after the new account has been saved
- */
- loadFbCookiesAsync {
- val cookies = ArrayList(it)
- Handler().postDelayed({
- if (Showcase.intro)
- launchNewTask<IntroActivity>(cookies, true)
- else
- launchNewTask<MainActivity>(cookies, true)
- }, 1000)
- }
- }.disposeOnDestroy()
- loadProfile(cookie.id)
- loadUsername(cookie)
+ private fun refresh(refreshing: Boolean) {
+ refreshChannel.offer(refreshing)
}
- private fun loadProfile(id: Long) {
- profileLoader.load(profilePictureUrl(id))
- .transform(FrostGlide.roundCorner).listener(object : RequestListener<Drawable> {
- override fun onResourceReady(
- resource: Drawable?,
- model: Any?,
- target: Target<Drawable>?,
- dataSource: DataSource?,
- isFirstResource: Boolean
- ): Boolean {
- profileSubject.onSuccess(true)
- return false
- }
-
- override fun onLoadFailed(
- e: GlideException?,
- model: Any?,
- target: Target<Drawable>?,
- isFirstResource: Boolean
- ): Boolean {
- e.logFrostEvent("Profile loading exception")
- profileSubject.onSuccess(false)
- return false
- }
- }).into(profile)
+ private suspend fun loadInfo(cookie: CookieModel): Unit = withMainContext {
+ refresh(true)
+
+ val imageDeferred = async { loadProfile(cookie.id) }
+ val nameDeferred = async { loadUsername(cookie) }
+
+ val foundImage = imageDeferred.await()
+ val name = nameDeferred.await()
+
+ refresh(false)
+
+ if (!foundImage) {
+ L.e { "Could not get profile photo; Invalid userId?" }
+ L._i { cookie }
+ }
+
+ textview.text = String.format(getString(R.string.welcome), name)
+ textview.fadeIn()
+ frostEvent("Login", "success" to true)
+
+ /*
+ * The user may have logged into an account that is already in the database
+ * We will let the db handle duplicates and load it now after the new account has been saved
+ */
+ val cookies = ArrayList(loadFbCookiesSuspend())
+ delay(1000)
+ if (Showcase.intro)
+ launchNewTask<IntroActivity>(cookies, true)
+ else
+ launchNewTask<MainActivity>(cookies, true)
+ }
+
+ private suspend fun loadProfile(id: Long): Boolean = withMainContext {
+ suspendCancellableCoroutine<Boolean> { cont ->
+ profileLoader.load(profilePictureUrl(id))
+ .transform(FrostGlide.roundCorner).listener(object : RequestListener<Drawable> {
+ override fun onResourceReady(
+ resource: Drawable?,
+ model: Any?,
+ target: Target<Drawable>?,
+ dataSource: DataSource?,
+ isFirstResource: Boolean
+ ): Boolean {
+ cont.resume(true)
+ return false
+ }
+
+ override fun onLoadFailed(
+ e: GlideException?,
+ model: Any?,
+ target: Target<Drawable>?,
+ isFirstResource: Boolean
+ ): Boolean {
+ e.logFrostEvent("Profile loading exception")
+ cont.resume(false)
+ return false
+ }
+ }).into(profile)
+ }
}
- private fun loadUsername(cookie: CookieModel) {
- cookie.fetchUsername(usernameSubject::onSuccess).disposeOnDestroy()
+ private suspend fun loadUsername(cookie: CookieModel): String = withContext(Dispatchers.IO) {
+ suspendCancellableCoroutine<String> { cont ->
+ cookie.fetchUsername {
+ cont.resume(it)
+ }
+ }
}
override fun backConsumer(): Boolean {