aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/fragments
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2018-12-27 02:15:10 -0500
committerAllan Wang <me@allanwang.ca>2018-12-27 02:15:10 -0500
commite6dcbd7b32dc49b11184b6beca598819c3f071fd (patch)
treea02691a1eaf1b1506930c7e50c5f43f6f0fc953a /app/src/main/kotlin/com/pitchedapps/frost/fragments
parent7d85262ada198501d2d5844e1196c9b45f4a38f5 (diff)
downloadfrost-e6dcbd7b32dc49b11184b6beca598819c3f071fd.tar.gz
frost-e6dcbd7b32dc49b11184b6beca598819c3f071fd.tar.bz2
frost-e6dcbd7b32dc49b11184b6beca598819c3f071fd.zip
Begin replacing observables with channels
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/fragments')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt9
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt66
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt33
3 files changed, 57 insertions, 51 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt
index e24e8308..95322c1c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt
@@ -23,6 +23,8 @@ import com.pitchedapps.frost.contracts.MainActivityContract
import com.pitchedapps.frost.contracts.MainFabContract
import com.pitchedapps.frost.views.FrostRecyclerView
import io.reactivex.disposables.Disposable
+import kotlinx.coroutines.channels.ReceiveChannel
+import kotlinx.coroutines.channels.SendChannel
/**
* Created by Allan Wang on 2017-11-07.
@@ -102,8 +104,9 @@ interface RecyclerContentContract {
/**
* Completely handle data reloading
- * Optional progress emission update
- * Callback returns [true] for success, [false] otherwise
+ * The progress function allows optional emission of progress values (between 0 and 100).
+ * This can be called from any thread.
+ * Returns [true] for success, [false] otherwise
*/
- fun reload(progress: (Int) -> Unit, callback: (Boolean) -> Unit)
+ suspend fun reload(progress: (Int) -> Unit): Boolean
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt
index f77f83ea..98c8f750 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt
@@ -29,16 +29,18 @@ import com.pitchedapps.frost.facebook.parsers.ParseResponse
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.frostJsoup
import com.pitchedapps.frost.views.FrostRecyclerView
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
/**
* Created by Allan Wang on 27/12/17.
*/
-abstract class RecyclerFragment : BaseFragment(), RecyclerContentContract {
+abstract class RecyclerFragment<T, Item : IItem<*, *>> : BaseFragment(), RecyclerContentContract {
override val layoutRes: Int = R.layout.view_content_recycler
+ abstract val adapter: ModelAdapter<T, Item>
+
override fun firstLoadRequest() {
val core = core ?: return
if (firstLoad) {
@@ -47,23 +49,30 @@ abstract class RecyclerFragment : BaseFragment(), RecyclerContentContract {
}
}
- final override fun reload(progress: (Int) -> Unit, callback: (Boolean) -> Unit) {
- reloadImpl(progress) {
- if (it)
- callback(it)
- else
- valid = false
+ final override suspend fun reload(progress: (Int) -> Unit): Boolean {
+ val data = try {
+ reloadImpl(progress)
+ } catch (e: Exception) {
+ null
+ }
+ if (data == null) {
+ valid = false
+ return false
+ }
+ withContext(Dispatchers.Main) {
+ adapter.setNewList(data)
}
+ return true
}
- protected abstract fun reloadImpl(progress: (Int) -> Unit, callback: (Boolean) -> Unit)
+ protected abstract suspend fun reloadImpl(progress: (Int) -> Unit): List<T>?
}
-abstract class GenericRecyclerFragment<T, Item : IItem<*, *>> : RecyclerFragment() {
+abstract class GenericRecyclerFragment<T, Item : IItem<*, *>> : RecyclerFragment<T, Item>() {
abstract fun mapper(data: T): Item
- val adapter: ModelAdapter<T, Item> = ModelAdapter { this.mapper(it) }
+ override val adapter: ModelAdapter<T, Item> = ModelAdapter { this.mapper(it) }
final override fun bind(recyclerView: FrostRecyclerView) {
recyclerView.adapter = getAdapter()
@@ -83,7 +92,7 @@ abstract class GenericRecyclerFragment<T, Item : IItem<*, *>> : RecyclerFragment
open fun getAdapter(): FastAdapter<IItem<*, *>> = fastAdapter(this.adapter)
}
-abstract class FrostParserFragment<T : Any, Item : IItem<*, *>> : RecyclerFragment() {
+abstract class FrostParserFragment<T : Any, Item : IItem<*, *>> : RecyclerFragment<Item, Item>() {
/**
* The parser to make this all happen
@@ -94,7 +103,7 @@ abstract class FrostParserFragment<T : Any, Item : IItem<*, *>> : RecyclerFragme
abstract fun toItems(response: ParseResponse<T>): List<Item>
- val adapter: ItemAdapter<Item> = ItemAdapter()
+ override val adapter: ItemAdapter<Item> = ItemAdapter()
final override fun bind(recyclerView: FrostRecyclerView) {
recyclerView.adapter = getAdapter()
@@ -113,23 +122,20 @@ abstract class FrostParserFragment<T : Any, Item : IItem<*, *>> : RecyclerFragme
*/
open fun getAdapter(): FastAdapter<IItem<*, *>> = fastAdapter(this.adapter)
- override fun reloadImpl(progress: (Int) -> Unit, callback: (Boolean) -> Unit) {
- doAsync {
- progress(10)
- val cookie = FbCookie.webCookie
- val doc = getDoc(cookie)
- progress(60)
- val response = parser.parse(cookie, doc)
- if (response == null) {
- L.i { "RecyclerFragment failed for ${baseEnum.name}" }
- return@doAsync callback(false)
- }
- progress(80)
- val items = toItems(response)
- progress(97)
- uiThread { adapter.setNewList(items) }
- callback(true)
+ override suspend fun reloadImpl(progress: (Int) -> Unit): List<Item>? = withContext(Dispatchers.IO) {
+ progress(10)
+ val cookie = FbCookie.webCookie
+ val doc = getDoc(cookie)
+ progress(60)
+ val response = parser.parse(cookie, doc)
+ if (response == null) {
+ L.i { "RecyclerFragment failed for ${baseEnum.name}" }
+ return@withContext null
}
+ progress(80)
+ val items = toItems(response)
+ progress(97)
+ return@withContext items
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt
index ff37b66d..45cf2290 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt
@@ -26,7 +26,7 @@ import com.pitchedapps.frost.facebook.requests.MenuFooterItem
import com.pitchedapps.frost.facebook.requests.MenuHeader
import com.pitchedapps.frost.facebook.requests.MenuItem
import com.pitchedapps.frost.facebook.requests.MenuItemData
-import com.pitchedapps.frost.facebook.requests.fbRequest
+import com.pitchedapps.frost.facebook.requests.fbAuth
import com.pitchedapps.frost.facebook.requests.getMenuData
import com.pitchedapps.frost.iitems.ClickableIItemContract
import com.pitchedapps.frost.iitems.MenuContentIItem
@@ -36,8 +36,9 @@ import com.pitchedapps.frost.iitems.MenuHeaderIItem
import com.pitchedapps.frost.iitems.NotificationIItem
import com.pitchedapps.frost.utils.frostJsoup
import com.pitchedapps.frost.views.FrostRecyclerView
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
/**
* Created by Allan Wang on 27/12/17.
@@ -71,20 +72,16 @@ class MenuFragment : GenericRecyclerFragment<MenuItemData, IItem<*, *>>() {
ClickableIItemContract.bindEvents(adapter)
}
- override fun reloadImpl(progress: (Int) -> Unit, callback: (Boolean) -> Unit) {
- doAsync {
- val cookie = FbCookie.webCookie
- progress(10)
- cookie.fbRequest({ callback(false) }) {
- progress(30)
- val data = getMenuData().invoke() ?: return@fbRequest callback(false)
- if (data.data.isEmpty()) return@fbRequest callback(false)
- progress(70)
- val items = data.flatMapValid()
- progress(90)
- uiThread { adapter.add(items) }
- callback(true)
- }
- }
+ override suspend fun reloadImpl(progress: (Int) -> Unit): List<MenuItemData>? = withContext(Dispatchers.IO) {
+ val cookie = FbCookie.webCookie ?: return@withContext null
+ progress(10)
+ val auth = fbAuth.fetch(cookie)
+ progress(30)
+ val data = auth.getMenuData().invoke() ?: return@withContext null
+ if (data.data.isEmpty()) return@withContext null
+ progress(70)
+ val items = data.flatMapValid()
+ progress(90)
+ return@withContext items
}
}