aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-12-21 02:16:34 -0500
committerGitHub <noreply@github.com>2017-12-21 02:16:34 -0500
commitd683cae6ffe644a9f63eea6cf3b7e59d2bde617b (patch)
tree517fe1d44c27084ccd87507d9804ba28f15c1647 /app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt
parent82f9aca96493316bc62008f2b3167d34a6029b38 (diff)
downloadfrost-d683cae6ffe644a9f63eea6cf3b7e59d2bde617b.tar.gz
frost-d683cae6ffe644a9f63eea6cf3b7e59d2bde617b.tar.bz2
frost-d683cae6ffe644a9f63eea6cf3b7e59d2bde617b.zip
Enhancement/fragment interface (#564)
* Begin fragment interfaces and themable contracts * Prepare swiperefresh interface * Snapshot * Add compilable version * Revamp once more * Finalize layouts * Cleanup
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt140
1 files changed, 140 insertions, 0 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt
new file mode 100644
index 00000000..58449de3
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt
@@ -0,0 +1,140 @@
+package com.pitchedapps.frost.views
+
+import android.content.Context
+import android.os.Build
+import android.support.v4.widget.SwipeRefreshLayout
+import android.util.AttributeSet
+import android.view.View
+import android.widget.FrameLayout
+import android.widget.ProgressBar
+import ca.allanwang.kau.utils.*
+import com.pitchedapps.frost.R
+import com.pitchedapps.frost.contracts.FrostContentContainer
+import com.pitchedapps.frost.contracts.FrostContentCore
+import com.pitchedapps.frost.contracts.FrostContentParent
+import com.pitchedapps.frost.facebook.FbItem
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.web.WEB_LOAD_DELAY
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.Disposable
+import io.reactivex.subjects.BehaviorSubject
+import io.reactivex.subjects.PublishSubject
+
+class FrostContentWeb @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0
+) : FrostContentView<FrostWebView>(context, attrs, defStyleAttr, defStyleRes) {
+
+ override val layoutRes: Int = R.layout.view_content_base_web
+
+}
+
+class FrostContentRecycler @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0
+) : FrostContentView<FrostRecyclerView>(context, attrs, defStyleAttr, defStyleRes) {
+
+ override val layoutRes: Int = R.layout.view_content_base_recycler
+
+}
+
+abstract class FrostContentView<out T> @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0
+) : FrameLayout(context, attrs, defStyleAttr, defStyleRes),
+ FrostContentParent where T : View, T : FrostContentCore {
+
+ private val refresh: SwipeRefreshLayout by bindView(R.id.content_refresh)
+ private val progress: ProgressBar by bindView(R.id.content_progress)
+ val coreView: T by bindView(R.id.content_core)
+
+ override val core: FrostContentCore
+ get() = coreView
+
+ override val progressObservable: PublishSubject<Int> = PublishSubject.create()
+ override val refreshObservable: PublishSubject<Boolean> = PublishSubject.create()
+ override val titleObservable: BehaviorSubject<String> = BehaviorSubject.create()
+
+ override lateinit var baseUrl: String
+ override var baseEnum: FbItem? = null
+
+ protected abstract val layoutRes: Int
+
+ /**
+ * Sets up everything
+ * Called by [bind]
+ */
+ protected fun init() {
+ inflate(context, layoutRes, this)
+ coreView.parent = this
+
+ // bind observables
+ progressObservable.observeOn(AndroidSchedulers.mainThread()).subscribe {
+ progress.invisibleIf(it == 100)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ progress.setProgress(it, true)
+ else
+ progress.progress = it
+ }
+ refreshObservable.observeOn(AndroidSchedulers.mainThread()).subscribe {
+ refresh.isRefreshing = it
+ refresh.isEnabled = true
+ }
+ refresh.setOnRefreshListener { coreView.reload(true) }
+
+ reloadThemeSelf()
+
+ }
+
+ override fun bind(container: FrostContentContainer) {
+ baseUrl = container.baseUrl
+ baseEnum = container.baseEnum
+ init()
+ core.bind(container)
+ }
+
+ override fun reloadTheme() {
+ reloadThemeSelf()
+ coreView.reloadTheme()
+ }
+
+ override fun reloadTextSize() {
+ coreView.reloadTextSize()
+ }
+
+ override fun reloadThemeSelf() {
+ progress.tint(Prefs.textColor.withAlpha(180))
+ refresh.setColorSchemeColors(Prefs.iconColor)
+ refresh.setProgressBackgroundColorSchemeColor(Prefs.headerColor.withAlpha(255))
+ }
+
+ override fun reloadTextSizeSelf() {
+ // intentionally blank
+ }
+
+ override fun destroy() {
+ titleObservable.onComplete()
+ progressObservable.onComplete()
+ refreshObservable.onComplete()
+ core.destroy()
+ }
+
+ /**
+ * Hook onto the refresh observable for one cycle
+ * Animate toggles between the fancy ripple and the basic fade
+ * The cycle only starts on the first load since there may have been another process when this is registered
+ */
+ override fun registerTransition(animate: Boolean) {
+ with(coreView) {
+ 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 && Prefs.animate) circularReveal(offset = WEB_LOAD_DELAY)
+ else fadeIn(duration = 100L)
+ }
+ }
+ }
+ }
+} \ No newline at end of file