From 1dd7be9174f1740aa1cae29f6d62d6f83f5917ba Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Mon, 22 Nov 2021 22:24:17 -0800 Subject: Migrate refresh channel to flow --- .../com/pitchedapps/frost/contracts/FrostContentContract.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt') diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt index b8d0d86f..1d429138 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt @@ -18,9 +18,11 @@ package com.pitchedapps.frost.contracts import android.view.View import com.pitchedapps.frost.facebook.FbItem +import com.pitchedapps.frost.web.FrostEmitter import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.BroadcastChannel +import kotlinx.coroutines.flow.SharedFlow /** * Created by Allan Wang on 20/12/17. @@ -56,7 +58,9 @@ interface FrostContentParent : DynamicUiContract { /** * Observable to get data on whether view is refreshing or not */ - val refreshChannel: BroadcastChannel + val refreshFlow: SharedFlow + + val refreshEmit: FrostEmitter /** * Observable to get data on refresh progress, with range [0, 100] @@ -124,17 +128,15 @@ interface FrostContentCore : DynamicUiContract { * Reference to parent * Bound through calling [FrostContentParent.bind] */ - var parent: FrostContentParent + val parent: FrostContentParent /** * Initializes view through given [container] * * The content may be free to extract other data from * the container if necessary - * - * [parent] must be bounded before calling this! */ - fun bind(container: FrostContentContainer): View + fun bind(parent: FrostContentParent, container: FrostContentContainer): View /** * Call to reload wrapped data -- cgit v1.2.3 From 779ec08188f4bda736b3e0f2940570f1f7eb49e1 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Mon, 22 Nov 2021 22:53:00 -0800 Subject: Migrate progress channel to flow --- .../pitchedapps/frost/contracts/FrostContentContract.kt | 4 +++- .../com/pitchedapps/frost/views/FrostContentView.kt | 15 ++++++++++----- .../com/pitchedapps/frost/views/FrostRecyclerView.kt | 4 ++-- .../com/pitchedapps/frost/web/FrostChromeClients.kt | 6 +++--- 4 files changed, 18 insertions(+), 11 deletions(-) (limited to 'app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt') diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt index 1d429138..8ebf7af7 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt @@ -65,7 +65,9 @@ interface FrostContentParent : DynamicUiContract { /** * Observable to get data on refresh progress, with range [0, 100] */ - val progressChannel: BroadcastChannel + val progressFlow: SharedFlow + + val progressEmit: FrostEmitter /** * Observable to get new title data (unique values only) 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 1891a786..3ec80f36 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt @@ -22,7 +22,6 @@ import android.util.AttributeSet import android.view.View import android.widget.FrameLayout import android.widget.ProgressBar -import ca.allanwang.kau.utils.ContextHelper import ca.allanwang.kau.utils.bindView import ca.allanwang.kau.utils.circularReveal import ca.allanwang.kau.utils.fadeIn @@ -39,7 +38,6 @@ import com.pitchedapps.frost.contracts.FrostContentParent import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.facebook.WEB_LOAD_DELAY import com.pitchedapps.frost.injectors.ThemeProvider -import com.pitchedapps.frost.kotlin.subscribeDuringJob import com.pitchedapps.frost.prefs.Prefs import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.web.FrostEmitter @@ -51,6 +49,7 @@ 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 import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.collect @@ -146,7 +145,13 @@ abstract class FrostContentViewBase( override val refreshEmit: FrostEmitter = FrostEmitter { refreshMutableFlow.tryEmit(it) } - override val progressChannel: BroadcastChannel = ConflatedBroadcastChannel() + private val progressMutableFlow = MutableStateFlow(0) + + override val progressFlow: SharedFlow = progressMutableFlow.asSharedFlow() + + override val progressEmit: FrostEmitter = + FrostEmitter { progressMutableFlow.tryEmit(it) } + override val titleChannel: BroadcastChannel = ConflatedBroadcastChannel() override lateinit var scope: CoroutineScope @@ -200,13 +205,13 @@ abstract class FrostContentViewBase( refresh.isRefreshing = r }.launchIn(scope) - progressChannel.subscribeDuringJob(scope, ContextHelper.coroutineContext) { p -> + progressFlow.onEach { p -> progress.invisibleIf(p == 100) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) progress.setProgress(p, true) else progress.progress = p - } + }.launchIn(scope) } override fun reloadTheme() { diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt index a2b71572..9e21ede8 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt @@ -80,8 +80,8 @@ class FrostRecyclerView @JvmOverloads constructor( if (prefs.animate) fadeOut(onFinish = onReloadClear) scope.launch { parent.refreshEmit(true) - recyclerContract.reload { parent.progressChannel.offer(it) } - parent.progressChannel.offer(100) + recyclerContract.reload { parent.progressEmit(it) } + parent.progressEmit(100) parent.refreshEmit(false) if (prefs.animate) circularReveal() } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt index 372a7bad..9f2437b0 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt @@ -53,7 +53,7 @@ class FrostChromeClient( // private val refresh: SendChannel = web.parent.refreshChannel private val refreshEmit = web.parent.refreshEmit - private val progress: SendChannel = web.parent.progressChannel + private val progressEmit = web.parent.progressEmit private val title: SendChannel = web.parent.titleChannel private val context = web.context!! @@ -74,7 +74,7 @@ class FrostChromeClient( override fun onProgressChanged(view: WebView, newProgress: Int) { super.onProgressChanged(view, newProgress) - progress.offer(newProgress) + progressEmit(newProgress) } override fun onShowFileChooser( @@ -89,7 +89,7 @@ class FrostChromeClient( private fun JsResult.frostCancel() { cancel() refreshEmit(false) - progress.offer(100) + progressEmit(100) } override fun onJsAlert( -- cgit v1.2.3 From bbfac885b89a79af2c85f5f0df7635770b49a07a Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Mon, 22 Nov 2021 22:57:55 -0800 Subject: Convert title channel to flow --- .../kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt | 8 +++----- .../com/pitchedapps/frost/contracts/FrostContentContract.kt | 6 +++--- .../main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt | 8 ++++++-- .../main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt | 5 ++--- 4 files changed, 14 insertions(+), 13 deletions(-) (limited to 'app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt') 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 171583ed..ae8d442f 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt @@ -27,7 +27,6 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout import ca.allanwang.kau.swipe.SwipeBackContract 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 @@ -56,7 +55,6 @@ import com.pitchedapps.frost.facebook.USER_AGENT import com.pitchedapps.frost.facebook.USER_AGENT_DESKTOP_CONST import com.pitchedapps.frost.facebook.USER_AGENT_MOBILE_CONST import com.pitchedapps.frost.facebook.formattedFbUrl -import com.pitchedapps.frost.kotlin.subscribeDuringJob import com.pitchedapps.frost.utils.ARG_URL import com.pitchedapps.frost.utils.ARG_USER_ID import com.pitchedapps.frost.utils.BiometricUtils @@ -69,6 +67,8 @@ import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.take import kotlinx.coroutines.launch import okhttp3.HttpUrl.Companion.toHttpUrlOrNull @@ -215,9 +215,7 @@ abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT content.bind(this) - content.titleChannel.subscribeDuringJob(this, ContextHelper.coroutineContext) { - toolbar.title = it - } + content.titleFlow.onEach { toolbar.title = it }.launchIn(this) with(web) { userAgentString = userAgent diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt index 8ebf7af7..d32cb873 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt @@ -21,7 +21,6 @@ import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.web.FrostEmitter import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.channels.BroadcastChannel import kotlinx.coroutines.flow.SharedFlow /** @@ -72,8 +71,9 @@ interface FrostContentParent : DynamicUiContract { /** * Observable to get new title data (unique values only) */ - // todo note that this should be like a behavior subject vs publish subject - val titleChannel: BroadcastChannel + val titleFlow: SharedFlow + + val titleEmit: FrostEmitter var baseUrl: String 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 3ec80f36..b76f6e39 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt @@ -80,7 +80,6 @@ class FrostContentRecycler @JvmOverloads constructor( override val layoutRes: Int = R.layout.view_content_base_recycler } -@UseExperimental(ExperimentalCoroutinesApi::class) abstract class FrostContentView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, @@ -152,7 +151,12 @@ abstract class FrostContentViewBase( override val progressEmit: FrostEmitter = FrostEmitter { progressMutableFlow.tryEmit(it) } - override val titleChannel: BroadcastChannel = ConflatedBroadcastChannel() + private val titleMutableFlow = MutableStateFlow("") + + override val titleFlow: SharedFlow = titleMutableFlow.asSharedFlow() + + override val titleEmit: FrostEmitter = + FrostEmitter { titleMutableFlow.tryEmit(it) } override lateinit var scope: CoroutineScope diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt index 9f2437b0..90345aa2 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt @@ -34,7 +34,6 @@ import com.pitchedapps.frost.contracts.WebFileChooser import com.pitchedapps.frost.injectors.ThemeProvider import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.views.FrostWebView -import kotlinx.coroutines.channels.SendChannel /** * Created by Allan Wang on 2017-05-31. @@ -54,7 +53,7 @@ class FrostChromeClient( // private val refresh: SendChannel = web.parent.refreshChannel private val refreshEmit = web.parent.refreshEmit private val progressEmit = web.parent.progressEmit - private val title: SendChannel = web.parent.titleChannel + private val titleEmit = web.parent.titleEmit private val context = web.context!! override fun getDefaultVideoPoster(): Bitmap? = @@ -69,7 +68,7 @@ class FrostChromeClient( override fun onReceivedTitle(view: WebView, title: String) { super.onReceivedTitle(view, title) if (title.startsWith("http")) return - this.title.offer(title) + titleEmit(title) } override fun onProgressChanged(view: WebView, newProgress: Int) { -- cgit v1.2.3 From 3599803b05188b8f9f4758b43fe120578fa8cf06 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Tue, 23 Nov 2021 12:10:23 -0800 Subject: Remove all experimental annotations --- app/build.gradle | 1 - .../main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt | 3 --- .../main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt | 2 -- .../kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt | 2 -- app/src/main/kotlin/com/pitchedapps/frost/fragments/BaseFragment.kt | 2 -- app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt | 2 -- app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt | 2 -- 7 files changed, 14 deletions(-) (limited to 'app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt') diff --git a/app/build.gradle b/app/build.gradle index 7e064152..f13c71e1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -135,7 +135,6 @@ android { } def compilerArgs = [ - "-Xuse-experimental=kotlin.Experimental", // "-XXLanguage:+InlineClasses", "-Xopt-in=kotlin.RequiresOptIn", ] 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 ae8d442f..8dbf9d5c 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt @@ -65,7 +65,6 @@ import com.pitchedapps.frost.views.FrostVideoViewer import com.pitchedapps.frost.views.FrostWebView import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -87,7 +86,6 @@ import javax.inject.Inject * 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() { override fun onCreate(savedInstanceState: Bundle?) { @@ -151,7 +149,6 @@ class WebOverlayDesktopActivity : WebOverlayActivityBase(USER_AGENT_DESKTOP_CONS */ class WebOverlayActivity : WebOverlayActivityBase() -@UseExperimental(ExperimentalCoroutinesApi::class) @AndroidEntryPoint abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT) : BaseActivity(), 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 721282aa..2b7f7b2c 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt @@ -19,10 +19,8 @@ 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.flow.SharedFlow -@UseExperimental(ExperimentalCoroutinesApi::class) interface MainActivityContract : MainFabContract { val fragmentFlow: SharedFlow val fragmentEmit: FrostEmitter diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt index d32cb873..7f91f901 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt @@ -20,7 +20,6 @@ import android.view.View import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.web.FrostEmitter import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.SharedFlow /** @@ -47,7 +46,6 @@ interface FrostContentContainer : CoroutineScope { * Contract for components shared among * all content providers */ -@UseExperimental(ExperimentalCoroutinesApi::class) interface FrostContentParent : DynamicUiContract { val scope: CoroutineScope diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/BaseFragment.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/BaseFragment.kt index e10fd141..a3303638 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/BaseFragment.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/BaseFragment.kt @@ -44,7 +44,6 @@ import com.pitchedapps.frost.utils.REQUEST_TEXT_ZOOM import com.pitchedapps.frost.utils.frostEvent import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.flow.launchIn @@ -59,7 +58,6 @@ import kotlin.coroutines.CoroutineContext * All fragments pertaining to the main view * Must be attached to activities implementing [MainActivityContract] */ -@UseExperimental(ExperimentalCoroutinesApi::class) @AndroidEntryPoint abstract class BaseFragment : Fragment(), 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 d2083816..c77ae590 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt @@ -44,7 +44,6 @@ import com.pitchedapps.frost.web.FrostEmitter import com.pitchedapps.frost.web.asFrostEmitter import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.ReceiveChannel import kotlinx.coroutines.flow.MutableSharedFlow @@ -96,7 +95,6 @@ abstract class FrostContentView @JvmOverloads constructor( /** * Subsection of [FrostContentView] that is [AndroidEntryPoint] friendly (no generics) */ -@UseExperimental(ExperimentalCoroutinesApi::class) @AndroidEntryPoint abstract class FrostContentViewBase( context: Context, diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt index 9e21ede8..04ee7f3c 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt @@ -29,7 +29,6 @@ import com.pitchedapps.frost.contracts.FrostContentParent import com.pitchedapps.frost.fragments.RecyclerContentContract import com.pitchedapps.frost.prefs.Prefs import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.launch import javax.inject.Inject @@ -37,7 +36,6 @@ import javax.inject.Inject * Created by Allan Wang on 2017-05-29. * */ -@UseExperimental(ExperimentalCoroutinesApi::class) @AndroidEntryPoint class FrostRecyclerView @JvmOverloads constructor( context: Context, -- cgit v1.2.3