From 91b7d53fb37b9939943c16b0bfd7a947d9f2363e Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Wed, 6 Feb 2019 12:12:10 -0500 Subject: Fix/open broadcast (#1345) * Convert jsi related channels to broadcasts * Close channel in debug activity --- .../frost/activities/BaseMainActivity.kt | 1 - .../pitchedapps/frost/activities/MainActivity.kt | 54 +++++++++++----------- .../frost/activities/WebOverlayActivity.kt | 10 ++-- .../frost/contracts/ActivityContract.kt | 3 +- .../com/pitchedapps/frost/kotlin/CoroutineUtils.kt | 23 +++++++++ .../kotlin/com/pitchedapps/frost/settings/Debug.kt | 1 + .../pitchedapps/frost/views/FrostContentView.kt | 38 ++++++--------- 7 files changed, 70 insertions(+), 60 deletions(-) create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/kotlin/CoroutineUtils.kt (limited to 'app/src/main/kotlin') diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt index b4215913..f1d88bc3 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt @@ -489,7 +489,6 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, controlWebview?.destroy() super.onDestroy() fragmentChannel.close() - headerBadgeChannel.close() } override fun collapseAppBar() { 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 044a1f37..c53e9055 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt @@ -21,6 +21,7 @@ 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.kotlin.subscribeDuringJob import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.views.BadgedIcon import kotlinx.coroutines.Dispatchers @@ -34,7 +35,7 @@ import org.jsoup.Jsoup class MainActivity : BaseMainActivity() { override val fragmentChannel = BroadcastChannel(10) - override val headerBadgeChannel = Channel(Channel.CONFLATED) + override val headerBadgeChannel = BroadcastChannel(Channel.CONFLATED) var lastPosition = -1 override fun onNestedCreate(savedInstanceState: Bundle?) { @@ -86,35 +87,34 @@ class MainActivity : BaseMainActivity() { (tab.customView as BadgedIcon).badgeText = null } }) - launch(Dispatchers.IO) { - for (html in headerBadgeChannel) { - try { - val doc = Jsoup.parse(html) - if (doc.select("[data-sigil=count]").isEmpty()) - continue // Header doesn't exist - val (feed, requests, messages, notifications) = listOf( - "feed", - "requests", - "messages", - "notifications" - ) - .map { "[data-sigil*=$it] [data-sigil=count]" } - .map { doc.select(it) } - .map { e -> e?.getOrNull(0)?.ownText() } - L.v { "Badges $feed $requests $messages $notifications" } - withMainContext { - tabsForEachView { _, view -> - when (view.iicon) { - FbItem.FEED.icon -> view.badgeText = feed - FbItem.FRIENDS.icon -> view.badgeText = requests - FbItem.MESSAGES.icon -> view.badgeText = messages - FbItem.NOTIFICATIONS.icon -> view.badgeText = notifications - } + headerBadgeChannel.subscribeDuringJob(this, Dispatchers.IO) { + html-> + try { + val doc = Jsoup.parse(html) + if (doc.select("[data-sigil=count]").isEmpty()) + return@subscribeDuringJob // Header doesn't exist + val (feed, requests, messages, notifications) = listOf( + "feed", + "requests", + "messages", + "notifications" + ) + .map { "[data-sigil*=$it] [data-sigil=count]" } + .map { doc.select(it) } + .map { e -> e?.getOrNull(0)?.ownText() } + L.v { "Badges $feed $requests $messages $notifications" } + withMainContext { + tabsForEachView { _, view -> + when (view.iicon) { + FbItem.FEED.icon -> view.badgeText = feed + FbItem.FRIENDS.icon -> view.badgeText = requests + FbItem.MESSAGES.icon -> view.badgeText = messages + FbItem.NOTIFICATIONS.icon -> view.badgeText = notifications } } - } catch (e: Exception) { - L.e(e) { "Header badge error" } } + } catch (e: Exception) { + L.e(e) { "Header badge error" } } } adapter.pages.forEach { diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt index a8c25050..b398e089 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt @@ -30,6 +30,7 @@ import androidx.appcompat.widget.Toolbar import androidx.coordinatorlayout.widget.CoordinatorLayout import ca.allanwang.kau.swipe.kauSwipeOnCreate import ca.allanwang.kau.swipe.kauSwipeOnDestroy +import ca.allanwang.kau.utils.ContextHelper import ca.allanwang.kau.utils.bindView import ca.allanwang.kau.utils.copyToClipboard import ca.allanwang.kau.utils.darken @@ -59,6 +60,7 @@ import com.pitchedapps.frost.facebook.FbCookie import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.facebook.USER_AGENT_BASIC import com.pitchedapps.frost.facebook.formattedFbUrl +import com.pitchedapps.frost.kotlin.subscribeDuringJob import com.pitchedapps.frost.services.FrostRunnable import com.pitchedapps.frost.utils.ARG_URL import com.pitchedapps.frost.utils.ARG_USER_ID @@ -204,12 +206,8 @@ open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseAc content.bind(this) - val titleReceiver = content.titleChannel.openSubscription().uniqueOnly(this) - - launch { - for (t in titleReceiver) { - toolbar.title = t - } + content.titleChannel.subscribeDuringJob(this, ContextHelper.coroutineContext) { + toolbar.title = it } with(web) { 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 81469ff3..385c2919 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt @@ -21,7 +21,6 @@ import com.pitchedapps.frost.activities.MainActivity import com.pitchedapps.frost.fragments.BaseFragment import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.BroadcastChannel -import kotlinx.coroutines.channels.Channel /** * All the contracts for [MainActivity] @@ -31,7 +30,7 @@ interface ActivityContract : FileChooserActivityContract @UseExperimental(ExperimentalCoroutinesApi::class) interface MainActivityContract : ActivityContract, MainFabContract { val fragmentChannel: BroadcastChannel - val headerBadgeChannel: Channel + val headerBadgeChannel: BroadcastChannel fun setTitle(res: Int) fun setTitle(text: CharSequence) /** diff --git a/app/src/main/kotlin/com/pitchedapps/frost/kotlin/CoroutineUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/kotlin/CoroutineUtils.kt new file mode 100644 index 00000000..0e09968d --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/kotlin/CoroutineUtils.kt @@ -0,0 +1,23 @@ +package com.pitchedapps.frost.kotlin + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.Job +import kotlinx.coroutines.channels.BroadcastChannel +import kotlinx.coroutines.launch +import kotlin.coroutines.CoroutineContext + +@UseExperimental(ExperimentalCoroutinesApi::class) +fun BroadcastChannel.subscribeDuringJob( + scope: CoroutineScope, + context: CoroutineContext, + onReceive: suspend (T) -> Unit +) { + val receiver = openSubscription() + scope.launch(context) { + for (r in receiver) { + onReceive(r) + } + } + scope.coroutineContext[Job]!!.invokeOnCompletion { receiver.cancel() } +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt index 08f13a10..e0ae6de5 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt @@ -142,6 +142,7 @@ fun SettingsActivity.sendDebug(url: String, html: String?) { progressChannel.offer(it) } md.dismiss() + progressChannel.close() if (success) { val zipUri = frostUriFromFile( File(downloader.baseDir, "$ZIP_NAME.zip") 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 575e5a4d..baf9421f 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt @@ -23,6 +23,7 @@ import android.view.View import android.widget.FrameLayout import android.widget.ProgressBar import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import ca.allanwang.kau.utils.ContextHelper import ca.allanwang.kau.utils.bindView import ca.allanwang.kau.utils.circularReveal import ca.allanwang.kau.utils.fadeIn @@ -38,6 +39,7 @@ import com.pitchedapps.frost.contracts.FrostContentCore import com.pitchedapps.frost.contracts.FrostContentParent import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.facebook.WEB_LOAD_DELAY +import com.pitchedapps.frost.kotlin.subscribeDuringJob import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.utils.Prefs import kotlinx.coroutines.CoroutineScope @@ -45,7 +47,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.BroadcastChannel import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.channels.ReceiveChannel -import kotlinx.coroutines.launch class FrostContentWeb @JvmOverloads constructor( context: Context, @@ -127,26 +128,18 @@ abstract class FrostContentView @JvmOverloads constructor( reload(true) } } - // Begin subscription in the main thread - val refreshReceiver = refreshChannel.openSubscription() - val progressReceiver = progressChannel.openSubscription() - - scope.launchMain { - launch { - for (r in refreshReceiver) { - refresh.isRefreshing = r - refresh.isEnabled = true - } - } - launch { - for (p in progressReceiver) { - progress.invisibleIf(p == 100) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) - progress.setProgress(p, true) - else - progress.progress = p - } - } + + refreshChannel.subscribeDuringJob(scope, ContextHelper.coroutineContext) { r -> + refresh.isRefreshing = r + refresh.isEnabled = true + } + + progressChannel.subscribeDuringJob(scope, ContextHelper.coroutineContext) { p -> + progress.invisibleIf(p == 100) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + progress.setProgress(p, true) + else + progress.progress = p } } @@ -170,9 +163,6 @@ abstract class FrostContentView @JvmOverloads constructor( } override fun destroy() { - titleChannel.close() - progressChannel.close() - refreshChannel.close() core.destroy() } -- cgit v1.2.3