diff options
author | Allan Wang <me@allanwang.ca> | 2017-12-29 19:39:04 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-29 19:39:04 -0500 |
commit | 32e6b5be0e662bbac22806bcc87259fd1a2e2ed0 (patch) | |
tree | c97f7ef11b60231bbe7337f5960413b95da0a8c2 /app/src/main/kotlin/com/pitchedapps/frost/fragments | |
parent | 8fee0629c27edee847358efc82309118f3a9a3a5 (diff) | |
download | frost-32e6b5be0e662bbac22806bcc87259fd1a2e2ed0.tar.gz frost-32e6b5be0e662bbac22806bcc87259fd1a2e2ed0.tar.bz2 frost-32e6b5be0e662bbac22806bcc87259fd1a2e2ed0.zip |
Feature/native notifs (#579)
* Improve parser and add zip test
* Remove ActivityOptionsCompat, resolves #555
* Create native notifs
* Add animations
* Add image rounder
* Improve glide transformations
* Add request service
* Fix parser
* Fix parser
* Add thumbnail and fix notification text
* Update parsers and regex
* Auto mark as read
* Add request implementation in pending intent
* Remove unnecessary return data
* Simplify command retrieval
* Use name keys instead
* Revamp all bundle calls
* Fix up thumbnail layout
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/fragments')
4 files changed, 123 insertions, 56 deletions
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 58d9ebd4..963d00bb 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt @@ -6,27 +6,28 @@ import android.support.v4.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import ca.allanwang.kau.adapters.fastAdapter import ca.allanwang.kau.utils.withArguments +import com.mikepenz.fastadapter.FastAdapter import com.mikepenz.fastadapter.IItem -import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter +import com.mikepenz.fastadapter.adapters.ItemAdapter +import com.mikepenz.fastadapter_extensions.items.ProgressItem import com.pitchedapps.frost.R import com.pitchedapps.frost.contracts.DynamicUiContract import com.pitchedapps.frost.contracts.FrostContentParent import com.pitchedapps.frost.contracts.MainActivityContract -import com.pitchedapps.frost.dbflow.CookieModel import com.pitchedapps.frost.enums.FeedSort import com.pitchedapps.frost.facebook.FbCookie import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.parsers.FrostParser +import com.pitchedapps.frost.parsers.ParseResponse import com.pitchedapps.frost.utils.* import com.pitchedapps.frost.views.FrostRecyclerView -import com.pitchedapps.frost.views.FrostWebView -import com.pitchedapps.frost.web.FrostWebViewClient -import com.pitchedapps.frost.web.FrostWebViewClientMenu import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable import org.jetbrains.anko.doAsync import org.jetbrains.anko.toast +import org.jetbrains.anko.uiThread /** * Created by Allan Wang on 2017-11-07. @@ -37,7 +38,6 @@ import org.jetbrains.anko.toast abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract { companion object { - private const val ARG_URL_ENUM = "arg_url_enum" private const val ARG_POSITION = "arg_position" internal operator fun invoke(base: () -> BaseFragment, data: FbItem, position: Int): BaseFragment { @@ -45,15 +45,15 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract { val d = if (data == FbItem.FEED) FeedSort(Prefs.feedSort).item else data fragment.withArguments( ARG_URL to d.url, - ARG_POSITION to position, - ARG_URL_ENUM to d + ARG_POSITION to position ) + d.put(fragment.arguments!!) return fragment } } override val baseUrl: String by lazy { arguments!!.getString(ARG_URL) } - override val baseEnum: FbItem by lazy { arguments!!.getSerializable(ARG_URL_ENUM) as FbItem } + override val baseEnum: FbItem by lazy { FbItem[arguments]!! } override val position: Int by lazy { arguments!!.getInt(ARG_POSITION) } override var firstLoad: Boolean = true @@ -66,6 +66,7 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + firstLoad = true if (context !is MainActivityContract) throw IllegalArgumentException("${this::class.java.simpleName} is not attached to a context implementing MainActivityContract") } @@ -92,8 +93,9 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract { } override fun firstLoadRequest() { + val core = core ?: return if (userVisibleHint && isVisible && firstLoad) { - core?.reloadBase(true) + core.reloadBase(true) firstLoad = false } } @@ -182,64 +184,83 @@ abstract class RecyclerFragment<T : Any, Item : IItem<*, *>> : BaseFragment(), R */ abstract val parser: FrostParser<T> - abstract val adapter: FastItemAdapter<Item> + open fun getDoc(cookie: String?) = frostJsoup(cookie, parser.url) - abstract fun toItems(data: T): List<Item> + val adapter: ItemAdapter<Item> = ItemAdapter() - override fun bind(recyclerView: FrostRecyclerView) { - recyclerView.adapter = this.adapter + abstract fun toItems(response: ParseResponse<T>): List<Item> + + override final fun bind(recyclerView: FrostRecyclerView) { + recyclerView.adapter = getAdapter() + recyclerView.onReloadClear = { adapter.clear() } + bindImpl(recyclerView) } - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - val tail = tailMapper(baseEnum) - if (tail.isNotEmpty()) { - val baseUrl = baseEnum.url - L.d("Adding $tail to $baseUrl for RecyclerFragment") - arguments!!.putString(ARG_URL, "$baseUrl$tail") + override fun firstLoadRequest() { + val core = core ?: return + if (firstLoad) { + core.reloadBase(true) + firstLoad = false } } - private fun tailMapper(item: FbItem) = when (item) { - FbItem.NOTIFICATIONS, FbItem.MESSAGES -> "/?more" - else -> "" - } + /** + * Anything to call for one time bindings + * At this stage, all adapters will have FastAdapter references + */ + open fun bindImpl(recyclerView: FrostRecyclerView) = Unit + + /** + * Create the fast adapter to bind to the recyclerview + */ + open fun getAdapter(): FastAdapter<IItem<*, *>> = fastAdapter(this.adapter) override fun reload(progress: (Int) -> Unit, callback: (Boolean) -> Unit) { doAsync { progress(10) - val doc = frostJsoup(baseUrl) + val cookie = FbCookie.webCookie + val doc = getDoc(cookie) progress(60) - val data = parser.parse(FbCookie.webCookie, doc) - if (data == null) { - context?.toast(R.string.error_generic) + val response = parser.parse(cookie, doc) + if (response == null) { + uiThread { context?.toast(R.string.error_generic) } L.eThrow("RecyclerFragment failed for ${baseEnum.name}") Prefs.nativeViews = false return@doAsync callback(false) } progress(80) - val items = toItems(data.data) + val items = toItems(response) progress(97) - adapter.setNewList(items) + uiThread { adapter.setNewList(items) } + callback(true) } } } -open class WebFragment : BaseFragment(), FragmentContract { - - override val layoutRes: Int = R.layout.view_content_web - - /** - * Given a webview, output a client - */ - open fun client(web: FrostWebView) = FrostWebViewClient(web) - - override fun innerView(context: Context) = FrostWebView(context) - -} - -class WebFragmentMenu : WebFragment() { - - override fun client(web: FrostWebView) = FrostWebViewClientMenu(web) - -}
\ No newline at end of file +//abstract class PagedRecyclerFragment<T : Any, Item : IItem<*, *>> : RecyclerFragment<T, Item>() { +// +// var allowPagedLoading = true +// +// val footerAdapter = ItemAdapter<FrostProgress>() +// +// val footerScrollListener = object : EndlessRecyclerOnScrollListener(footerAdapter) { +// override fun onLoadMore(currentPage: Int) { +// TODO("not implemented") +// +// } +// +// } +// +// override fun getAdapter() = fastAdapter(adapter, footerAdapter) +// +// override fun bindImpl(recyclerView: FrostRecyclerView) { +// recyclerView.addOnScrollListener(footerScrollListener) +// } +// +// override fun reload(progress: (Int) -> Unit, callback: (Boolean) -> Unit) { +// footerScrollListener. +// super.reload(progress, callback) +// } +//} + +class FrostProgress : ProgressItem()
\ No newline at end of file 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 00429730..a78eb0d0 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt @@ -1,11 +1,9 @@ package com.pitchedapps.frost.fragments -import android.content.Context import com.pitchedapps.frost.contracts.FrostContentContainer import com.pitchedapps.frost.contracts.FrostContentCore import com.pitchedapps.frost.contracts.FrostContentParent import com.pitchedapps.frost.contracts.MainActivityContract -import com.pitchedapps.frost.dbflow.CookieModel import com.pitchedapps.frost.views.FrostRecyclerView import io.reactivex.disposables.Disposable @@ -56,11 +54,6 @@ interface FragmentContract : FrostContentContainer { fun attachMainObservable(contract: MainActivityContract): Disposable /** - * Load custom layout to container - */ - fun innerView(context: Context): FrostContentCore - - /** * Call when fragment is detached so that any existing * observable is disposed */ diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt new file mode 100644 index 00000000..4d4a6f8b --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt @@ -0,0 +1,27 @@ +package com.pitchedapps.frost.fragments + +import com.pitchedapps.frost.facebook.FbItem +import com.pitchedapps.frost.iitems.NotificationIItem +import com.pitchedapps.frost.parsers.FrostNotifs +import com.pitchedapps.frost.parsers.NotifParser +import com.pitchedapps.frost.parsers.ParseResponse +import com.pitchedapps.frost.utils.frostJsoup +import com.pitchedapps.frost.views.FrostRecyclerView + +/** + * Created by Allan Wang on 27/12/17. + */ +class NotificationFragment : RecyclerFragment<FrostNotifs, NotificationIItem>() { + + override val parser = NotifParser + + override fun getDoc(cookie: String?) = frostJsoup(cookie, "${FbItem.NOTIFICATIONS.url}?more") + + override fun toItems(response: ParseResponse<FrostNotifs>): List<NotificationIItem> = + response.data.notifs.map { NotificationIItem(it, response.cookie) } + + override fun bindImpl(recyclerView: FrostRecyclerView) { + NotificationIItem.bindEvents(adapter) + } + +}
\ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragments.kt new file mode 100644 index 00000000..2740a36f --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragments.kt @@ -0,0 +1,26 @@ +package com.pitchedapps.frost.fragments + +import com.pitchedapps.frost.R +import com.pitchedapps.frost.views.FrostWebView +import com.pitchedapps.frost.web.FrostWebViewClient +import com.pitchedapps.frost.web.FrostWebViewClientMenu + +/** + * Created by Allan Wang on 27/12/17. + */ +open class WebFragment : BaseFragment() { + + override val layoutRes: Int = R.layout.view_content_web + + /** + * Given a webview, output a client + */ + open fun client(web: FrostWebView) = FrostWebViewClient(web) + +} + +class WebFragmentMenu : WebFragment() { + + override fun client(web: FrostWebView) = FrostWebViewClientMenu(web) + +}
\ No newline at end of file |