From dcd0db9282d92beacd35b3418d924ff3c607dead Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Mon, 22 Nov 2021 23:21:34 -0800 Subject: Convert header channel to flow --- .../pitchedapps/frost/activities/MainActivity.kt | 39 ++++++++++++++++------ .../frost/contracts/ActivityContract.kt | 7 +++- .../pitchedapps/frost/views/FrostContentView.kt | 2 -- .../kotlin/com/pitchedapps/frost/web/FrostJSI.kt | 5 ++- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt index 755064cd..4b18088c 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt @@ -18,23 +18,33 @@ package com.pitchedapps.frost.activities import android.os.Bundle import androidx.viewpager.widget.ViewPager -import ca.allanwang.kau.utils.withMainContext import com.google.android.material.tabs.TabLayout import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.facebook.parsers.BadgeParser -import com.pitchedapps.frost.kotlin.subscribeDuringJob import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.views.BadgedIcon +import com.pitchedapps.frost.web.FrostEmitter import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.BroadcastChannel -import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.onEach @UseExperimental(ExperimentalCoroutinesApi::class) class MainActivity : BaseMainActivity() { override val fragmentChannel = BroadcastChannel(10) - override val headerBadgeChannel = BroadcastChannel(Channel.CONFLATED) + + private val headerMutableFlow = MutableStateFlow("") + override val headerFlow: SharedFlow = headerMutableFlow.asSharedFlow() + override val headerEmit: FrostEmitter = FrostEmitter { headerMutableFlow.tryEmit(it) } override fun onNestedCreate(savedInstanceState: Bundle?) { with(contentBinding) { @@ -90,12 +100,18 @@ class MainActivity : BaseMainActivity() { (tab.customView as BadgedIcon).badgeText = null } }) - headerBadgeChannel.subscribeDuringJob(this@MainActivity, Dispatchers.IO) { html -> - val data = - BadgeParser.parseFromData(cookie = fbCookie.webCookie, text = html)?.data - ?: return@subscribeDuringJob - L.v { "Badges $data" } - withMainContext { + headerFlow + .filter { it.isNotBlank() } + .mapNotNull { html -> + BadgeParser.parseFromData( + cookie = fbCookie.webCookie, + text = html + )?.data + } + .distinctUntilChanged() + .flowOn(Dispatchers.IO) + .onEach { data -> + L.v { "Badges $data" } tabsForEachView { _, view -> when (view.iicon) { FbItem.FEED.icon -> view.badgeText = data.feed @@ -105,6 +121,7 @@ class MainActivity : BaseMainActivity() { } } } - } + .flowOn(Dispatchers.Main) + .launchIn(this@MainActivity) } } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt index 756b1f3d..83110417 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt @@ -18,13 +18,18 @@ package com.pitchedapps.frost.contracts import com.mikepenz.iconics.typeface.IIcon import com.pitchedapps.frost.fragments.BaseFragment +import com.pitchedapps.frost.web.FrostEmitter import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.BroadcastChannel +import kotlinx.coroutines.flow.SharedFlow @UseExperimental(ExperimentalCoroutinesApi::class) interface MainActivityContract : MainFabContract { val fragmentChannel: BroadcastChannel - val headerBadgeChannel: BroadcastChannel + + val headerFlow: SharedFlow + val headerEmit: FrostEmitter + fun setTitle(res: Int) fun setTitle(text: CharSequence) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt index b76f6e39..75d1ffe4 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt @@ -44,9 +44,7 @@ import com.pitchedapps.frost.web.FrostEmitter import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.channels.BroadcastChannel import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.channels.ReceiveChannel import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow 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 f43f3b81..4d92e8c2 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt @@ -32,7 +32,6 @@ import com.pitchedapps.frost.utils.isIndependent import com.pitchedapps.frost.utils.launchImageActivity import com.pitchedapps.frost.utils.showWebContextMenu import com.pitchedapps.frost.views.FrostWebView -import kotlinx.coroutines.channels.SendChannel import kotlinx.coroutines.launch import javax.inject.Inject @@ -50,7 +49,7 @@ class FrostJSI @Inject internal constructor( private val mainActivity: MainActivity? = activity as? MainActivity private val webActivity: WebOverlayActivityBase? = activity as? WebOverlayActivityBase - private val header: SendChannel? = mainActivity?.headerBadgeChannel + private val headerEmit: FrostEmitter? = mainActivity?.headerEmit private val cookies: List = activity.cookies() /** @@ -159,7 +158,7 @@ class FrostJSI @Inject internal constructor( @JavascriptInterface fun handleHeader(html: String?) { html ?: return - header?.offer(html) + headerEmit?.invoke(html) } @JavascriptInterface -- cgit v1.2.3