Skip to content

Instantly share code, notes, and snippets.

View gumil's full-sized avatar
🌚
No Activity

Miguel Panelo gumil

🌚
No Activity
View GitHub Profile
@gumil
gumil / RecyclerLoadingView.java
Created May 25, 2016 07:17
RecyclerView with SwipeRefreshLayout, Loading, and Error Message
import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
@gumil
gumil / Component.kt
Last active December 19, 2019 14:52
Simple DI
import kotlin.reflect.KProperty
internal class Component(modules: List<Module>, private val parentComponent: Component? = null) {
private val providers: Map<Class<*>, Provider<*>> = hashMapOf<Class<*>, Provider<*>>().apply {
modules.forEach { putAll(it) }
}
inline fun <reified T> get() = get(T::class.java)
@gumil
gumil / actions.kt
Last active February 17, 2019 17:39
Giphy Kaskade Medium Article
internal sealed class ListAction : Action {
data class Refresh(
val limit: Int = DEFAULT_LIMIT
) : ListAction()
data class LoadMore(
val offset: Int
) : ListAction()
internal sealed class ListState : State {
data class Screen(
val giphies: List<GiphyItem> = emptyList(),
val loadingMode: Mode = Mode.IDLE_REFRESH
) : ListState()
data class Error(
val errorMessage: Int
) : ListState(), SingleEvent
@gumil
gumil / kaskade.kt
Last active February 17, 2019 21:15
Kaskade.create<ListAction, ListState>(ListState.Screen()) {
rx({
object : DisposableObserver<ListState>() {
override fun onComplete() {
Timber.d("flow completed")
}
override fun onNext(state: ListState) {
Timber.d("currentState = $state")
}
@gumil
gumil / reducers.kt
Last active February 17, 2019 22:05
on<ListAction.Refresh> {
flatMap {
if (it.action.limit > ListAction.DEFAULT_LIMIT) {
cache.get<List<GiphyItem>>(GiphyListViewModel.KEY_GIPHIES)?.let { giphies ->
return@flatMap ListState.Screen(giphies, ListState.Mode.IDLE_REFRESH).just()
}
}
loadTrending(ListState.Mode.REFRESH, limit = it.action.limit) { _, list ->
ListState.Screen(list, ListState.Mode.IDLE_REFRESH)
fun <A : ListAction> Observable<ActionState<A, ListState>>.loadTrending(
mode: ListState.Mode,
offset: Int = 0,
limit: Int = 10,
listStateFunction: (ListState.Screen, List<GiphyItem>) -> ListState.Screen
): Observable<ListState> = this
.map { it.state as ListState.Screen }
.flatMap { state ->
repository.getTrending(offset, limit)
.map { giphies ->
fun actions() = Observable.merge<ListAction>(
recyclerView.scrollEvents()
// filter when we do a scroll up
.filter { it.dy > 0 }
// filter when recyclerView is currently loading
.filter { !isLoading }
// filter threshold
.filter {
val layoutManager = it.view.layoutManager as StaggeredGridLayoutManager
val visibleItemCount = recyclerView.childCount
fun ListState.render(): Unit? = when (this) {
is ListState.Screen -> {
when(loadingMode) {
ListState.Mode.REFRESH -> { swipeRefreshLayout.isRefreshing = true }
ListState.Mode.LOAD_MORE -> adapter.showFooter()
ListState.Mode.IDLE_LOAD_MORE -> {
adapter.addItems(giphies)
isLoading = false
restoreRecyclerView(giphies)
package com.gumil.giphy.list
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer
import com.gumil.giphy.GiphyItem
import com.gumil.giphy.ImageItem
import com.gumil.giphy.R
import com.gumil.giphy.TestRepository
import com.gumil.giphy.UserItem
import com.gumil.giphy.util.just