aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2018-12-28 21:12:07 -0500
committerAllan Wang <me@allanwang.ca>2018-12-28 21:12:07 -0500
commit5393f171e4b489b90fa93df1b23288178d9daaef (patch)
treea2490479f4d639553657509f2414c4660b491c62
parent1e2fc927b10ae933005afa12ceb7a2832af4b95b (diff)
downloadfrost-5393f171e4b489b90fa93df1b23288178d9daaef.tar.gz
frost-5393f171e4b489b90fa93df1b23288178d9daaef.tar.bz2
frost-5393f171e4b489b90fa93df1b23288178d9daaef.zip
Update badge channel
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt1
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt59
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt21
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt5
5 files changed, 47 insertions, 41 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 2d1ec7d6..7f69cc27 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
@@ -473,6 +473,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
override fun onDestroy() {
fragmentChannel.close()
+ headerBadgeChannel.close()
controlWebview?.destroy()
super.onDestroy()
}
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 cc375800..e5eb1907 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
@@ -20,21 +20,23 @@ import android.os.Bundle
import androidx.viewpager.widget.ViewPager
import com.google.android.material.tabs.TabLayout
import com.pitchedapps.frost.facebook.FbItem
+import com.pitchedapps.frost.utils.L
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.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.BroadcastChannel
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import org.jsoup.Jsoup
-import java.util.concurrent.TimeUnit
@UseExperimental(ExperimentalCoroutinesApi::class)
class MainActivity : BaseMainActivity() {
override val fragmentChannel = BroadcastChannel<Int>(10)
+ override val headerBadgeChannel = Channel<String>(Channel.RENDEZVOUS)
var lastPosition = -1
- val headerBadgeObservable = PublishSubject.create<String>()
override fun onNestedCreate(savedInstanceState: Bundle?) {
setupTabs()
@@ -81,28 +83,37 @@ class MainActivity : BaseMainActivity() {
(tab.customView as BadgedIcon).badgeText = null
}
})
- headerBadgeObservable.throttleFirst(15, TimeUnit.SECONDS)
- .subscribeOn(Schedulers.newThread())
- .map { Jsoup.parse(it) }
- .filter { it.select("[data-sigil=count]").size >= 0 } //ensure headers exist
- .map {
- val feed = it.select("[data-sigil*=feed] [data-sigil=count]")
- val requests = it.select("[data-sigil*=requests] [data-sigil=count]")
- val messages = it.select("[data-sigil*=messages] [data-sigil=count]")
- val notifications = it.select("[data-sigil*=notifications] [data-sigil=count]")
- return@map arrayOf(feed, requests, messages, notifications).map { e -> e?.getOrNull(0)?.ownText() }
- }
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe { (feed, requests, messages, notifications) ->
- 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
+ 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._d { "Badges $feed $requests $messages $notifications" }
+ withContext(Dispatchers.Main) {
+ 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" }
}
- }.disposeOnDestroy()
+ }
+ }
adapter.pages.forEach {
tabs.addTab(
tabs.newTab()
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 9a70436e..483e49c5 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt
@@ -20,6 +20,7 @@ import com.mikepenz.iconics.typeface.IIcon
import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.fragments.BaseFragment
import kotlinx.coroutines.channels.BroadcastChannel
+import kotlinx.coroutines.channels.Channel
/**
* All the contracts for [MainActivity]
@@ -28,6 +29,7 @@ interface ActivityContract : FileChooserActivityContract
interface MainActivityContract : ActivityContract, MainFabContract {
val fragmentChannel: BroadcastChannel<Int>
+ val headerBadgeChannel : Channel<String>
fun setTitle(res: Int)
fun setTitle(text: CharSequence)
/**
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
index c5880840..72150ddd 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
@@ -16,7 +16,6 @@
*/
package com.pitchedapps.frost.fragments
-import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -41,6 +40,7 @@ import com.pitchedapps.frost.utils.REQUEST_TEXT_ZOOM
import com.pitchedapps.frost.utils.frostEvent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.channels.ReceiveChannel
@@ -54,6 +54,7 @@ import kotlin.coroutines.CoroutineContext
* All fragments pertaining to the main view
* Must be attached to activities implementing [MainActivityContract]
*/
+@UseExperimental(ExperimentalCoroutinesApi::class)
abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, DynamicUiContract {
companion object {
@@ -90,7 +91,6 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
set(value) {
if (!isActive || value || this is WebFragment) return
arguments!!.putBoolean(ARG_VALID, value)
- L.e { "Invalidating position $position" }
frostEvent(
"Native Fallback",
"Item" to baseEnum.name
@@ -132,6 +132,10 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
onCreateRunnable?.invoke(this)
onCreateRunnable = null
firstLoadRequest()
+ detachMainObservable()
+ (context as? MainActivityContract)?.let {
+ activityReceiver = attachMainObservable(it)
+ }
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
@@ -204,22 +208,11 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
activityReceiver?.cancel()
}
- override fun onAttach(context: Context) {
- super.onAttach(context)
- detachMainObservable()
- if (context is MainActivityContract)
- activityReceiver = attachMainObservable(context)
- }
-
- override fun onDetach() {
- detachMainObservable()
- super.onDetach()
- }
-
override fun onDestroyView() {
L.i { "Fragment on destroy $position ${hashCode()}" }
content?.destroy()
content = null
+ detachMainObservable()
super.onDestroyView()
}
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 3945a9a0..4611d27d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
@@ -29,7 +29,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 io.reactivex.subjects.Subject
import kotlinx.coroutines.channels.SendChannel
/**
@@ -39,7 +38,7 @@ class FrostJSI(val web: FrostWebView) {
private val context = web.context
private val activity = context as? MainActivity
- private val header: Subject<String>? = activity?.headerBadgeObservable
+ private val header: SendChannel<String>? = activity?.headerBadgeChannel
private val refresh: SendChannel<Boolean> = web.parent.refreshChannel
private val cookies = activity?.cookies() ?: arrayListOf()
@@ -133,6 +132,6 @@ class FrostJSI(val web: FrostWebView) {
@JavascriptInterface
fun handleHeader(html: String?) {
html ?: return
- header?.onNext(html)
+ header?.offer(html)
}
}