aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/activities
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/activities')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt21
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt34
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt56
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt17
4 files changed, 80 insertions, 48 deletions
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 84352cb4..9d16c63a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
@@ -130,7 +130,6 @@ import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.qualifiers.ActivityContext
import dagger.hilt.android.scopes.ActivityScoped
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import javax.inject.Inject
import kotlin.math.abs
@@ -140,7 +139,6 @@ import kotlin.math.abs
*
* Most of the logic that is unrelated to handling fragments
*/
-@UseExperimental(ExperimentalCoroutinesApi::class)
@AndroidEntryPoint
abstract class BaseMainActivity :
BaseActivity(),
@@ -498,7 +496,10 @@ abstract class BaseMainActivity :
)
positiveButton(R.string.kau_yes) {
this@BaseMainActivity.launch {
- fbCookie.logout(this@BaseMainActivity, deleteCookie = true)
+ fbCookie.logout(
+ this@BaseMainActivity,
+ deleteCookie = true
+ )
}
}
negativeButton(R.string.kau_no)
@@ -637,7 +638,7 @@ abstract class BaseMainActivity :
private fun refreshAll() {
L.d { "Refresh all" }
- fragmentChannel.offer(REQUEST_REFRESH)
+ fragmentEmit(REQUEST_REFRESH)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
@@ -737,19 +738,19 @@ abstract class BaseMainActivity :
* These results can be stacked
*/
if (hasRequest(REQUEST_REFRESH)) {
- fragmentChannel.offer(REQUEST_REFRESH)
+ fragmentEmit(REQUEST_REFRESH)
}
if (hasRequest(REQUEST_NAV)) {
frostNavigationBar(prefs, themeProvider)
}
if (hasRequest(REQUEST_TEXT_ZOOM)) {
- fragmentChannel.offer(REQUEST_TEXT_ZOOM)
+ fragmentEmit(REQUEST_TEXT_ZOOM)
}
if (hasRequest(REQUEST_SEARCH)) {
invalidateOptionsMenu()
}
if (hasRequest(REQUEST_FAB)) {
- fragmentChannel.offer(lastPosition)
+ fragmentEmit(lastPosition)
}
if (hasRequest(REQUEST_NOTIFICATION)) {
scheduleNotificationsFromPrefs(prefs)
@@ -792,7 +793,6 @@ abstract class BaseMainActivity :
override fun onDestroy() {
controlWebview?.destroy()
super.onDestroy()
- fragmentChannel.close()
}
override fun collapseAppBar() {
@@ -864,10 +864,9 @@ abstract class BaseMainActivity :
lastPosition = 0
viewpager.setCurrentItem(0, false)
viewpager.offscreenPageLimit = pages.size
+ // todo check if post is necessary
viewpager.post {
- if (!fragmentChannel.isClosedForSend) {
- fragmentChannel.offer(0)
- }
+ fragmentEmit(0)
} // trigger hook so title is set
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
index 949f1ddd..a95e931b 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
@@ -45,13 +45,20 @@ import com.pitchedapps.frost.utils.frostEvent
import com.pitchedapps.frost.utils.frostJsoup
import com.pitchedapps.frost.utils.launchNewTask
import com.pitchedapps.frost.utils.logFrostEvent
-import com.pitchedapps.frost.utils.uniqueOnly
+import com.pitchedapps.frost.web.FrostEmitter
import com.pitchedapps.frost.web.LoginWebView
+import com.pitchedapps.frost.web.asFrostEmitter
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
-import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.asSharedFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
@@ -76,7 +83,15 @@ class LoginActivity : BaseActivity() {
private val profile: ImageView by bindView(R.id.profile)
private lateinit var profileLoader: RequestManager
- private val refreshChannel = Channel<Boolean>(10)
+
+ private val refreshMutableFlow = MutableSharedFlow<Boolean>(
+ extraBufferCapacity = 10,
+ onBufferOverflow = BufferOverflow.DROP_OLDEST
+ )
+
+ private val refreshFlow: SharedFlow<Boolean> = refreshMutableFlow.asSharedFlow()
+
+ private val refreshEmit: FrostEmitter<Boolean> = refreshMutableFlow.asFrostEmitter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -87,11 +102,12 @@ class LoginActivity : BaseActivity() {
toolbar(toolbar)
}
profileLoader = GlideApp.with(profile)
- launch {
- for (refreshing in refreshChannel.uniqueOnly(this)) {
- swipeRefresh.isRefreshing = refreshing
- }
- }
+
+ refreshFlow
+ .distinctUntilChanged()
+ .onEach { swipeRefresh.isRefreshing = it }
+ .launchIn(this)
+
launch {
val cookie = web.loadLogin { refresh(it != 100) }.await()
L.d { "Login found" }
@@ -107,7 +123,7 @@ class LoginActivity : BaseActivity() {
}
private fun refresh(refreshing: Boolean) {
- refreshChannel.offer(refreshing)
+ refreshEmit(refreshing)
}
private suspend fun loadInfo(cookie: CookieEntity): Unit = withMainContext {
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..16606691 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,38 @@ 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 com.pitchedapps.frost.web.asFrostEmitter
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.channels.BroadcastChannel
-import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.channels.BufferOverflow
+import kotlinx.coroutines.flow.MutableSharedFlow
+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<Int>(10)
- override val headerBadgeChannel = BroadcastChannel<String>(Channel.CONFLATED)
+ private val fragmentMutableFlow = MutableSharedFlow<Int>(
+ extraBufferCapacity = 10,
+ onBufferOverflow = BufferOverflow.DROP_OLDEST
+ )
+ override val fragmentFlow: SharedFlow<Int> = fragmentMutableFlow.asSharedFlow()
+ override val fragmentEmit: FrostEmitter<Int> = fragmentMutableFlow.asFrostEmitter()
+
+ private val headerMutableFlow = MutableStateFlow("")
+ override val headerFlow: SharedFlow<String> = headerMutableFlow.asSharedFlow()
+ override val headerEmit: FrostEmitter<String> = headerMutableFlow.asFrostEmitter()
override fun onNestedCreate(savedInstanceState: Bundle?) {
with(contentBinding) {
@@ -51,9 +66,9 @@ class MainActivity : BaseMainActivity() {
return
}
if (lastPosition != -1) {
- fragmentChannel.offer(-(lastPosition + 1))
+ fragmentEmit(-(lastPosition + 1))
}
- fragmentChannel.offer(position)
+ fragmentEmit(position)
lastPosition = position
}
@@ -90,12 +105,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 +126,7 @@ class MainActivity : BaseMainActivity() {
}
}
}
- }
+ .flowOn(Dispatchers.Main)
+ .launchIn(this@MainActivity)
}
}
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 ef7579a8..8dbf9d5c 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
@@ -67,7 +65,10 @@ 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
+import kotlinx.coroutines.flow.take
import kotlinx.coroutines.launch
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import javax.inject.Inject
@@ -85,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?) {
@@ -97,10 +97,8 @@ class FrostWebActivity : WebOverlayActivityBase() {
* We will subscribe to the load cycle once,
* and pop a dialog giving the user the option to copy the shared text
*/
- val refreshReceiver = content.refreshChannel.openSubscription()
content.scope.launch(Dispatchers.IO) {
- refreshReceiver.receive()
- refreshReceiver.cancel()
+ content.refreshFlow.take(1).collect()
withMainContext {
materialDialog {
title(R.string.invalid_share_url)
@@ -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(),
@@ -215,9 +212,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