aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-06-15 19:25:17 -0700
committerAllan Wang <me@allanwang.ca>2017-06-15 19:25:17 -0700
commitc8f76b5aa406f84f49789a50871c68a1a95a232d (patch)
tree7a47029f13dd023b2947eb294c8c9f7c7dbd3fe0
parent0d1f0e215b1890f2f5d45373b2746b7ef91da494 (diff)
downloadfrost-c8f76b5aa406f84f49789a50871c68a1a95a232d.tar.gz
frost-c8f76b5aa406f84f49789a50871c68a1a95a232d.tar.bz2
frost-c8f76b5aa406f84f49789a50871c68a1a95a232d.zip
Only animate webview when explicitly asked
-rw-r--r--app/src/main/assets/js/menu_click.js2
-rw-r--r--app/src/main/assets/js/menu_click.min.js2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt1
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt3
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt3
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt1
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/AnimUtils.kt119
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt39
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt16
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt6
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt40
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt4
14 files changed, 54 insertions, 190 deletions
diff --git a/app/src/main/assets/js/menu_click.js b/app/src/main/assets/js/menu_click.js
index 65c1c401..3e23617a 100644
--- a/app/src/main/assets/js/menu_click.js
+++ b/app/src/main/assets/js/menu_click.js
@@ -10,7 +10,7 @@ document.onclick = function(e) {
console.log(url);
if (url !== "https://m.facebook.com/settings" && url !== "https://m.facebook.com/settings#" && url !== "https://m.facebook.com/settings#!/settings?soft=bookmarks") {
Frost.loadUrl(url);
- Frost.reloadBaseUrl(); //temporary workaround
+ Frost.reloadBaseUrl(false); //reinject base view
}
}
};
diff --git a/app/src/main/assets/js/menu_click.min.js b/app/src/main/assets/js/menu_click.min.js
index 14ac7e76..580f0467 100644
--- a/app/src/main/assets/js/menu_click.min.js
+++ b/app/src/main/assets/js/menu_click.min.js
@@ -1 +1 @@
-document.onclick=function(c){c=c||window.event;var b=c.target||c.srcElement;if(b.tagName!=="A"){b=b.parentNode}if(b.tagName==="A"){var a=b.href;console.log("Click Intercept");console.log(a);if(a!=="https://m.facebook.com/settings"&&a!=="https://m.facebook.com/settings#"&&a!=="https://m.facebook.com/settings#!/settings?soft=bookmarks"){Frost.loadUrl(a);Frost.reloadBaseUrl()}}}; \ No newline at end of file
+document.onclick=function(c){c=c||window.event;var b=c.target||c.srcElement;if(b.tagName!=="A"){b=b.parentNode}if(b.tagName==="A"){var a=b.href;console.log("Click Intercept");console.log(a);if(a!=="https://m.facebook.com/settings"&&a!=="https://m.facebook.com/settings#"&&a!=="https://m.facebook.com/settings#!/settings?soft=bookmarks"){Frost.loadUrl(a);Frost.reloadBaseUrl(false)}}}; \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
index 09a54444..c18c007a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
@@ -48,7 +48,6 @@ class FrostApp : Application() {
Prefs.initialize(this, "${com.pitchedapps.frost.BuildConfig.APPLICATION_ID}.prefs")
FbCookie()
super.onCreate()
- requestNotifications(Prefs.userId)
//Drawer profile loading logic
DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String) {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt
index c4cf7a97..c3dad579 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt
@@ -23,9 +23,6 @@ import com.pitchedapps.frost.facebook.PROFILE_PICTURE_URL
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.launchNewTask
-import com.pitchedapps.frost.views.fadeIn
-import com.pitchedapps.frost.views.fadeOut
-import com.pitchedapps.frost.views.setTextWithFade
import com.pitchedapps.frost.web.LoginWebView
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
index 751658e9..bdac366e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
@@ -3,6 +3,7 @@ package com.pitchedapps.frost
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.pitchedapps.frost.dbflow.loadFbCookiesAsync
+import com.pitchedapps.frost.services.requestNotifications
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.launchNewTask
@@ -17,6 +18,8 @@ class StartActivity : AppCompatActivity() {
L.d("Load cookies ${System.currentTimeMillis()}")
loadFbCookiesAsync {
cookies ->
+ cookies.forEach { requestNotifications(it.id) }
+
L.d("Cookies loaded ${System.currentTimeMillis()} $cookies")
if (cookies.isNotEmpty())
launchNewTask(if (Prefs.userId != -1L) MainActivity::class.java else SelectorActivity::class.java, ArrayList(cookies))
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt
index 8cb189e7..244c1388 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt
@@ -6,6 +6,7 @@ import android.support.v7.widget.RecyclerView
import android.view.View
import android.widget.ImageView
import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.fadeIn
import ca.allanwang.kau.utils.toDrawable
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/AnimUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/AnimUtils.kt
deleted file mode 100644
index 3d212cc0..00000000
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/AnimUtils.kt
+++ /dev/null
@@ -1,119 +0,0 @@
-package com.pitchedapps.frost.views
-
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.support.annotation.StringRes
-import android.view.View
-import android.view.ViewAnimationUtils
-import android.view.animation.Animation
-import android.view.animation.AnimationUtils
-import android.view.animation.DecelerateInterpolator
-import android.widget.TextView
-
-
-/**
- * Created by Allan Wang on 2017-06-01.
- */
-
-fun View.rootCircularReveal(x: Int = 0, y: Int = 0, duration: Long = 500L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) {
- this.addOnLayoutChangeListener(object : View.OnLayoutChangeListener {
- override fun onLayoutChange(v: View, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int,
- oldRight: Int, oldBottom: Int) {
- v.removeOnLayoutChangeListener(this)
- var x2 = x
- var y2 = y
- if (x2 > right) x2 = 0
- if (y2 > bottom) y2 = 0
- val radius = Math.hypot(Math.max(x2, right - x2).toDouble(), Math.max(y2, bottom - y2).toDouble()).toInt()
- val reveal = ViewAnimationUtils.createCircularReveal(v, x2, y2, 0f, radius.toFloat())
- reveal.interpolator = DecelerateInterpolator(1f)
- reveal.duration = duration
- reveal.addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationStart(animation: Animator?) {
- visibility = View.VISIBLE
- onStart?.invoke()
- }
-
- override fun onAnimationEnd(animation: Animator?) = onFinish?.invoke() ?: Unit
- override fun onAnimationCancel(animation: Animator?) = onFinish?.invoke() ?: Unit
- })
- reveal.start()
- }
- })
-}
-
-fun View.circularReveal(x: Int = 0, y: Int = 0, offset: Long = 0L, radius: Float = -1.0f, duration: Long = 500L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) {
- if (!isAttachedToWindow) {
- visibility = View.VISIBLE
- return
- }
- var r = radius
- if (r < 0.0f) {
- r = Math.max(Math.hypot(x.toDouble(), y.toDouble()), Math.hypot((width - x.toDouble()), (height - y.toDouble()))).toFloat()
- }
- val anim = ViewAnimationUtils.createCircularReveal(this, x, y, 0f, r).setDuration(duration)
- anim.startDelay = offset
- anim.addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationStart(animation: Animator?) {
- visibility = View.VISIBLE
- onStart?.invoke()
- }
-
- override fun onAnimationEnd(animation: Animator?) = onFinish?.invoke() ?: Unit
- override fun onAnimationCancel(animation: Animator?) = onFinish?.invoke() ?: Unit
- })
- anim.start()
-}
-
-fun View.fadeIn(offset: Long = 0L, duration: Long = 200L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) {
- if (!isAttachedToWindow) {
- visibility = View.VISIBLE
- return
- }
- if (isAttachedToWindow) {
- val anim = AnimationUtils.loadAnimation(context, android.R.anim.fade_in)
- anim.startOffset = offset
- anim.duration = duration
- anim.setAnimationListener(object : Animation.AnimationListener {
- override fun onAnimationRepeat(animation: Animation?) {}
- override fun onAnimationEnd(animation: Animation?) = onFinish?.invoke() ?: Unit
- override fun onAnimationStart(animation: Animation?) {
- visibility = View.VISIBLE
- onStart?.invoke()
- }
- })
- startAnimation(anim)
- }
-}
-
-fun View.fadeOut(offset: Long = 0L, duration: Long = 200L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) {
- if (!isAttachedToWindow) {
- visibility = View.INVISIBLE
- return
- }
- val anim = AnimationUtils.loadAnimation(context, android.R.anim.fade_out)
- anim.startOffset = offset
- anim.duration = duration
- anim.setAnimationListener(object : Animation.AnimationListener {
- override fun onAnimationRepeat(animation: Animation?) {}
- override fun onAnimationEnd(animation: Animation?) {
- visibility = View.INVISIBLE
- onFinish?.invoke()
- }
-
- override fun onAnimationStart(animation: Animation?) {
- onStart?.invoke()
- }
- })
- startAnimation(anim)
-}
-
-fun TextView.setTextWithFade(text: String, duration: Long = 200, onFinish: (() -> Unit)? = null) {
- fadeOut(duration = duration, onFinish = {
- setText(text)
- fadeIn(duration = duration, onFinish = onFinish)
- })
-}
-
-fun TextView.setTextWithFade(@StringRes textId: Int, duration: Long = 200, onFinish: (() -> Unit)? = null) = setTextWithFade(context.getString(textId), duration, onFinish)
-
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt
deleted file mode 100644
index 8dc3f01f..00000000
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.pitchedapps.frost.views
-
-import android.content.res.ColorStateList
-import android.support.annotation.ColorInt
-import android.support.annotation.ColorRes
-import android.support.annotation.StringRes
-import android.support.design.widget.Snackbar
-import android.support.v4.content.ContextCompat
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ProgressBar
-
-
-/**
- * Created by Allan Wang on 2017-05-31.
- */
-fun View.matchParent() {
- with(layoutParams) {
- height = ViewGroup.LayoutParams.MATCH_PARENT
- width = ViewGroup.LayoutParams.MATCH_PARENT
- }
-}
-
-fun ProgressBar.tintRes(@ColorRes id: Int) = tint(ContextCompat.getColor(context, id))
-
-fun ProgressBar.tint(@ColorInt color: Int) {
- val sl = ColorStateList.valueOf(color)
- progressTintList = sl
- secondaryProgressTintList = sl
- indeterminateTintList = sl
-}
-
-fun View.snackbar(text: String, duration: Int = Snackbar.LENGTH_LONG) {
- Snackbar.make(this, text, duration).show()
-}
-
-fun View.snackbar(@StringRes textId: Int, duration: Int = Snackbar.LENGTH_LONG) {
- Snackbar.make(this, textId, duration).show()
-} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
index 14ea4df8..bb482c3c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
@@ -23,11 +23,11 @@ class FrostJSI(val context: Context, val webView: FrostWebViewCore) {
fun loadUrl(url: String) = context.launchWebOverlay(url)
@JavascriptInterface
- fun reloadBaseUrl() {
+ fun reloadBaseUrl(animate: Boolean) {
L.d("FrostJSI reload")
webView.post {
webView.stopLoading()
- webView.loadBaseUrl()
+ webView.loadBaseUrl(animate)
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt
index c99feaf5..a600489d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt
@@ -50,8 +50,8 @@ class FrostWebView @JvmOverloads constructor(context: Context, attrs: AttributeS
//Some urls have postJavascript injections so make sure we load the base url
override fun onRefresh() {
when (web.baseUrl) {
- FbTab.MENU.url -> web.loadBaseUrl()
- else -> web.reload()
+ FbTab.MENU.url -> web.loadBaseUrl(true)
+ else -> web.reload(true)
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
index c3eb0a1f..e4ff4e10 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
@@ -4,7 +4,6 @@ import android.content.Context
import android.graphics.Bitmap
import android.view.KeyEvent
import android.webkit.*
-import ca.allanwang.kau.utils.isVisible
import com.pitchedapps.frost.LoginActivity
import com.pitchedapps.frost.MainActivity
import com.pitchedapps.frost.SelectorActivity
@@ -18,9 +17,6 @@ import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.cookies
import com.pitchedapps.frost.utils.launchNewTask
-import com.pitchedapps.frost.views.circularReveal
-import com.pitchedapps.frost.views.fadeIn
-import com.pitchedapps.frost.views.fadeOut
import io.reactivex.subjects.Subject
/**
@@ -36,7 +32,6 @@ open class FrostWebViewClient(val refreshObservable: Subject<Boolean>) : WebView
if (!url.contains(FACEBOOK_COM)) return
if (url.contains("logout.php")) FbCookie.logout(Prefs.userId, { launchLogin(view.context) })
else if (url.contains("login.php")) FbCookie.reset({ launchLogin(view.context) })
- view.fadeOut(duration = 200L)
}
fun launchLogin(c: Context) {
@@ -50,19 +45,18 @@ open class FrostWebViewClient(val refreshObservable: Subject<Boolean>) : WebView
super.onPageFinished(view, url)
if (!url.contains(FACEBOOK_COM)) {
refreshObservable.onNext(false)
- if (!view.isVisible()) view.fadeIn(duration = 200L)
return
}
L.i("Page finished $url")
JsActions.LOGIN_CHECK.inject(view)
- onPageFinishedReveal(view as FrostWebViewCore, url)
+ onPageFinishedActions(view as FrostWebViewCore, url)
}
- open internal fun onPageFinishedReveal(view: FrostWebViewCore, url: String?) {
- onPageFinishedReveal(view, true)
+ open internal fun onPageFinishedActions(view: FrostWebViewCore, url: String?) {
+ onPageFinishedActions(view)
}
- internal fun onPageFinishedReveal(view: FrostWebViewCore, animate: Boolean) {
+ internal fun onPageFinishedActions(view: FrostWebViewCore) {
L.d("Page finished reveal")
view.jsInject(CssHider.HEADER,
Prefs.themeInjector,
@@ -70,8 +64,6 @@ open class FrostWebViewClient(val refreshObservable: Subject<Boolean>) : WebView
callback = {
L.d("Finished ${it.contentToString()}")
refreshObservable.onNext(false)
- if (animate) view.circularReveal(offset = 150L)
- else view.fadeIn(duration = 100L)
})
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt
index 3b032f62..f299b840 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt
@@ -45,18 +45,18 @@ class FrostWebViewClientMenu(refreshObservable: Subject<Boolean>) : FrostWebView
override fun emit(flag: Int) {
super.emit(flag)
- if (view != null) super.onPageFinishedReveal(view!!, true)
+ if (view != null) super.onPageFinishedActions(view!!)
view = null
}
- override fun onPageFinishedReveal(view: FrostWebViewCore, url: String?) {
+ override fun onPageFinishedActions(view: FrostWebViewCore, url: String?) {
when (url) {
"https://m.facebook.com/settings",
"https://m.facebook.com/settings#",
"https://m.facebook.com/settings#!/settings?soft=bookmarks" -> {
//do nothing; we will further inject before revealing
}
- else -> super.onPageFinishedReveal(view, false)
+ else -> super.onPageFinishedActions(view)
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt
index db5f877d..86d88e47 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt
@@ -12,8 +12,13 @@ import android.view.MotionEvent
import android.view.View
import android.view.animation.DecelerateInterpolator
import android.webkit.WebView
+import ca.allanwang.kau.utils.circularReveal
+import ca.allanwang.kau.utils.fadeIn
+import ca.allanwang.kau.utils.fadeOut
+import ca.allanwang.kau.utils.isVisible
import com.pitchedapps.frost.facebook.FbTab
import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
+import com.pitchedapps.frost.utils.L
import io.reactivex.Scheduler
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
@@ -65,13 +70,38 @@ class FrostWebViewCore @JvmOverloads constructor(
setBackgroundColor(Color.TRANSPARENT)
}
- override fun loadUrl(url: String?) {
- if (url != null)
- super.loadUrl(url)
+ fun loadUrl(url: String?, animate: Boolean) {
+ if (url == null) return
+ registerTransition(animate)
+ super.loadUrl(url)
}
- fun loadBaseUrl() {
- loadUrl(baseUrl)
+ fun reload(animate: Boolean) {
+ registerTransition(animate)
+ super.reload()
+ }
+
+ /**
+ * Hook onto the refresh observable for one cycle
+ * Note that this is a behaviour subject so the first 'false' emission should be ignored
+ */
+ fun registerTransition(animate: Boolean) {
+ var dispose: Disposable? = null
+ var loading = false
+ dispose = refreshObservable.subscribeOn(AndroidSchedulers.mainThread()).subscribe {
+ if (it) {
+ loading = true
+ if (isVisible()) fadeOut(duration = 200L)
+ } else if (loading) {
+ dispose?.dispose()
+ if (animate) circularReveal(offset = 150L)
+ else fadeIn(duration = 100L)
+ }
+ }
+ }
+
+ fun loadBaseUrl(animate: Boolean = true) {
+ loadUrl(baseUrl, animate)
}
fun addTitleListener(subscriber: (title: String) -> Unit, scheduler: Scheduler = AndroidSchedulers.mainThread()): Disposable
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
index aa10e602..8265f429 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
@@ -5,6 +5,8 @@ import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.webkit.*
+import ca.allanwang.kau.utils.fadeIn
+import ca.allanwang.kau.utils.snackbar
import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.facebook.FACEBOOK_COM
import com.pitchedapps.frost.facebook.FbCookie
@@ -12,8 +14,6 @@ import com.pitchedapps.frost.injectors.CssHider
import com.pitchedapps.frost.injectors.jsInject
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
-import com.pitchedapps.frost.views.fadeIn
-import com.pitchedapps.frost.views.snackbar
import io.reactivex.subjects.PublishSubject
import io.reactivex.subjects.SingleSubject
import io.reactivex.subjects.Subject