diff options
author | Allan Wang <me@allanwang.ca> | 2017-12-21 02:16:34 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-21 02:16:34 -0500 |
commit | d683cae6ffe644a9f63eea6cf3b7e59d2bde617b (patch) | |
tree | 517fe1d44c27084ccd87507d9804ba28f15c1647 /app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt | |
parent | 82f9aca96493316bc62008f2b3167d34a6029b38 (diff) | |
download | frost-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.kt | 140 |
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 |