Skip to content
This repository has been archived by the owner on Dec 15, 2023. It is now read-only.

Commit

Permalink
Switch remaining primary observables
Browse files Browse the repository at this point in the history
  • Loading branch information
AllanWang committed Dec 29, 2018
1 parent c970d70 commit e5e8373
Show file tree
Hide file tree
Showing 17 changed files with 150 additions and 95 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ android {
resValue "string", "frost_web", "Frost Web Debug"
ext.enableBugsnag = false

kotlinOptions.freeCompilerArgs += ["-Xuse-experimental=kotlin.Experimental"]
kotlinOptions.freeCompilerArgs += ["-Xuse-experimental=kotlin.Experimental", "-XXLanguage:+InlineClasses"]
}
releaseTest {
minifyEnabled true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ class AboutActivity : AboutActivityBase(null, {
}
val set = ConstraintSet()
set.clone(container)
set.createHorizontalChain(ConstraintSet.PARENT_ID,
set.createHorizontalChain(
ConstraintSet.PARENT_ID,
ConstraintSet.LEFT,
ConstraintSet.PARENT_ID,
ConstraintSet.RIGHT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,

private fun refreshAll() {
L.d { "Refresh all" }
fragmentSubject.onNext(REQUEST_REFRESH)
fragmentChannel.offer(REQUEST_REFRESH)
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
Expand Down Expand Up @@ -424,9 +424,9 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
/*
* These results can be stacked
*/
if (resultCode and REQUEST_REFRESH > 0) fragmentSubject.onNext(REQUEST_REFRESH)
if (resultCode and REQUEST_REFRESH > 0) fragmentChannel.offer(REQUEST_REFRESH)
if (resultCode and REQUEST_NAV > 0) frostNavigationBar()
if (resultCode and REQUEST_TEXT_ZOOM > 0) fragmentSubject.onNext(REQUEST_TEXT_ZOOM)
if (resultCode and REQUEST_TEXT_ZOOM > 0) fragmentChannel.offer(REQUEST_TEXT_ZOOM)
if (resultCode and REQUEST_SEARCH > 0) invalidateOptionsMenu()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@ import com.pitchedapps.frost.views.BadgedIcon
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.PublishSubject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.BroadcastChannel
import org.jsoup.Jsoup
import java.util.concurrent.TimeUnit

@UseExperimental(ExperimentalCoroutinesApi::class)
class MainActivity : BaseMainActivity() {

override val fragmentSubject = PublishSubject.create<Int>()
override val fragmentChannel = BroadcastChannel<Int>(10)
var lastPosition = -1
val headerBadgeObservable = PublishSubject.create<String>()

Expand All @@ -43,8 +46,8 @@ class MainActivity : BaseMainActivity() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
if (lastPosition == position) return
if (lastPosition != -1) fragmentSubject.onNext(-(lastPosition + 1))
fragmentSubject.onNext(position)
if (lastPosition != -1) fragmentChannel.offer(-(lastPosition + 1))
fragmentChannel.offer(position)
lastPosition = position
}

Expand All @@ -62,7 +65,7 @@ class MainActivity : BaseMainActivity() {
}
}
})
viewPager.post { fragmentSubject.onNext(0); lastPosition = 0 } //trigger hook so title is set
viewPager.post { fragmentChannel.offer(0); lastPosition = 0 } //trigger hook so title is set
}

private fun setupTabs() {
Expand Down Expand Up @@ -101,8 +104,9 @@ class MainActivity : BaseMainActivity() {
}
}.disposeOnDestroy()
adapter.pages.forEach {
tabs.addTab(tabs.newTab()
.setCustomView(BadgedIcon(this).apply { iicon = it.icon })
tabs.addTab(
tabs.newTab()
.setCustomView(BadgedIcon(this).apply { iicon = it.icon })
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,12 @@ import com.pitchedapps.frost.utils.Showcase
import com.pitchedapps.frost.utils.frostSnackbar
import com.pitchedapps.frost.utils.materialDialogThemed
import com.pitchedapps.frost.utils.setFrostColors
import com.pitchedapps.frost.utils.uniqueOnly
import com.pitchedapps.frost.views.FrostContentWeb
import com.pitchedapps.frost.views.FrostVideoViewer
import com.pitchedapps.frost.views.FrostWebView
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.HttpUrl
Expand All @@ -91,6 +90,7 @@ import okhttp3.HttpUrl
* Used by notifications. Unlike the other overlays, this runs as a singleInstance
* Going back will bring you back to the previous app
*/
@UseExperimental(ExperimentalCoroutinesApi::class)
class FrostWebActivity : WebOverlayActivityBase(false) {

override fun onCreate(savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -151,6 +151,7 @@ class WebOverlayBasicActivity : WebOverlayActivityBase(true)
class WebOverlayActivity : WebOverlayActivityBase(false)

@SuppressLint("Registered")
@UseExperimental(ExperimentalCoroutinesApi::class)
open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseActivity(),
ActivityContract, FrostContentContainer,
VideoViewHolder, FileChooserContract by FileChooserDelegate() {
Expand Down Expand Up @@ -203,7 +204,7 @@ open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseAc

content.bind(this)

val titleReceiver = content.titleChannel.openSubscription()
val titleReceiver = content.titleChannel.openSubscription().uniqueOnly(this)

launch {
for (t in titleReceiver) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ package com.pitchedapps.frost.contracts
import com.mikepenz.iconics.typeface.IIcon
import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.fragments.BaseFragment
import io.reactivex.subjects.PublishSubject
import kotlinx.coroutines.channels.BroadcastChannel

/**
* All the contracts for [MainActivity]
*/
interface ActivityContract : FileChooserActivityContract

interface MainActivityContract : ActivityContract, MainFabContract {
val fragmentSubject: PublishSubject<Int>
val fragmentChannel: BroadcastChannel<Int>
fun setTitle(res: Int)
fun setTitle(text: CharSequence)
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@ package com.pitchedapps.frost.contracts

import android.view.View
import com.pitchedapps.frost.facebook.FbItem
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.PublishSubject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.BroadcastChannel
import kotlinx.coroutines.channels.Channel

/**
* Created by Allan Wang on 20/12/17.
Expand Down
56 changes: 31 additions & 25 deletions app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.REQUEST_REFRESH
import com.pitchedapps.frost.utils.REQUEST_TEXT_ZOOM
import com.pitchedapps.frost.utils.frostEvent
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlin.coroutines.CoroutineContext

/**
Expand Down Expand Up @@ -87,7 +88,7 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
override var valid: Boolean
get() = arguments!!.getBoolean(ARG_VALID, true)
set(value) {
if (value || this is WebFragment) return
if (!isActive || value || this is WebFragment) return
arguments!!.putBoolean(ARG_VALID, value)
L.e { "Invalidating position $position" }
frostEvent(
Expand All @@ -98,7 +99,7 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
}

override var firstLoad: Boolean = true
private var activityDisposable: Disposable? = null
private var activityReceiver: ReceiveChannel<Int>? = null
private var onCreateRunnable: ((FragmentContract) -> Unit)? = null

override var content: FrostContentParent? = null
Expand Down Expand Up @@ -154,29 +155,34 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
(context as? MainActivityContract)?.setTitle(title)
}

override fun attachMainObservable(contract: MainActivityContract): Disposable =
contract.fragmentSubject.observeOn(AndroidSchedulers.mainThread()).subscribe {
when (it) {
REQUEST_REFRESH -> {
core?.apply {
clearHistory()
firstLoad = true
firstLoadRequest()
override fun attachMainObservable(contract: MainActivityContract): ReceiveChannel<Int> {
val receiver = contract.fragmentChannel.openSubscription()
launch {
for (flag in receiver) {
when (flag) {
REQUEST_REFRESH -> {
core?.apply {
clearHistory()
firstLoad = true
firstLoadRequest()
}
}
position -> {
contract.setTitle(baseEnum.titleId)
updateFab(contract)
core?.active = true
}
-(position + 1) -> {
core?.active = false
}
REQUEST_TEXT_ZOOM -> {
reloadTextSize()
}
}
position -> {
contract.setTitle(baseEnum.titleId)
updateFab(contract)
core?.active = true
}
-(position + 1) -> {
core?.active = false
}
REQUEST_TEXT_ZOOM -> {
reloadTextSize()
}
}
}
return receiver
}

override fun updateFab(contract: MainFabContract) {
contract.hideFab() // default
Expand All @@ -195,14 +201,14 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
}

override fun detachMainObservable() {
activityDisposable?.dispose()
activityReceiver?.cancel()
}

override fun onAttach(context: Context) {
super.onAttach(context)
detachMainObservable()
if (context is MainActivityContract)
activityDisposable = attachMainObservable(context)
activityReceiver = attachMainObservable(context)
}

override fun onDetach() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import com.pitchedapps.frost.contracts.FrostContentParent
import com.pitchedapps.frost.contracts.MainActivityContract
import com.pitchedapps.frost.contracts.MainFabContract
import com.pitchedapps.frost.views.FrostRecyclerView
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.channels.ReceiveChannel

/**
* Created by Allan Wang on 2017-11-07.
Expand All @@ -34,8 +34,9 @@ interface FragmentContract : FrostContentContainer {

/**
* Defines whether the fragment is valid in the viewpager
* Or if it needs to be recreated
* May be called from any thread to toggle status
* or if it needs to be recreated
* May be called from any thread to toggle status.
* Note that calls beyond the fragment lifecycle will be ignored
*/
var valid: Boolean

Expand Down Expand Up @@ -75,9 +76,10 @@ interface FragmentContract : FrostContentContainer {

/**
* Call whenever a fragment is attached so that it may listen
* to activity emissions
* to activity emissions.
* Returns a means of closing the listener, which can be called from [detachMainObservable]
*/
fun attachMainObservable(contract: MainActivityContract): Disposable
fun attachMainObservable(contract: MainActivityContract): ReceiveChannel<Int>

/**
* Call when fragment is detached so that any existing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.IItem
import com.mikepenz.fastadapter.adapters.ItemAdapter
import com.mikepenz.fastadapter.adapters.ModelAdapter
import com.mikepenz.fastadapter_extensions.items.ProgressItem
import com.pitchedapps.frost.R
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.facebook.parsers.FrostParser
Expand Down Expand Up @@ -142,31 +141,3 @@ abstract class FrostParserFragment<T : Any, Item : IItem<*, *>> : RecyclerFragme
return@withContext items
}
}

//abstract class PagedRecyclerFragment<T : Any, Item : IItem<*, *>> : RecyclerFragment<T, Item>() {
//
// var allowPagedLoading = true
//
// val footerAdapter = ItemAdapter<FrostProgress>()
//
// val footerScrollListener = object : EndlessRecyclerOnScrollListener(footerAdapter) {
// override fun onLoadMore(currentPage: Int) {
// TODO("not implemented")
//
// }
//
// }
//
// override fun getAdapter() = fastAdapter(adapter, footerAdapter)
//
// override fun bindImpl(recyclerView: FrostRecyclerView) {
// recyclerView.addOnScrollListener(footerScrollListener)
// }
//
// override fun reload(progress: (Int) -> Unit, callback: (Boolean) -> Unit) {
// footerScrollListener.
// super.reload(progress, callback)
// }
//}

class FrostProgress : ProgressItem()
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import com.pitchedapps.frost.iitems.NotificationIItem
import com.pitchedapps.frost.utils.frostJsoup
import com.pitchedapps.frost.views.FrostRecyclerView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
Expand Down
20 changes: 20 additions & 0 deletions app/src/main/kotlin/com/pitchedapps/frost/utils/KotlinUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.pitchedapps.frost.utils

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.channels.produce
import kotlinx.coroutines.isActive

@UseExperimental(ExperimentalCoroutinesApi::class)
fun <T> ReceiveChannel<T>.uniqueOnly(scope: CoroutineScope): ReceiveChannel<T> = scope.produce {
var previous: T? = null
for (current in this@uniqueOnly) {
if (!scope.isActive) {
cancel()
} else if (previous != current) {
previous = current
send(current)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ import com.pitchedapps.frost.facebook.WEB_LOAD_DELAY
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import io.reactivex.disposables.Disposable
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.PublishSubject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.utils.circularReveal
import ca.allanwang.kau.utils.fadeOut
import com.pitchedapps.frost.R.string.reload
import com.pitchedapps.frost.contracts.FrostContentContainer
import com.pitchedapps.frost.contracts.FrostContentCore
import com.pitchedapps.frost.contracts.FrostContentParent
import com.pitchedapps.frost.fragments.RecyclerContentContract
import com.pitchedapps.frost.utils.Prefs
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

/**
Expand Down
Loading

0 comments on commit e5e8373

Please sign in to comment.