Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlexanderBollbach/edbe81cfe0ea494585802b363bde9b07 to your computer and use it in GitHub Desktop.
Save AlexanderBollbach/edbe81cfe0ea494585802b363bde9b07 to your computer and use it in GitHub Desktop.
init<ItemType: ListItemDisplayable>(
menuItems: Observable<[ContextMenuItem]> = .just([]),
getTitle: @escaping () -> Single<String> = { .just("") },
getItems: @escaping ItemsFetcher<ItemType>,
externalReload: Observable<Void> = env.reload.asObservable(),
filteringEnabled: Bool = false,
emptyListMessage: String = "There are no items to show",
filterFunc: @escaping ListItemFilterFunction<ItemType> = { (items, _) in items }
) {
let filtersStream = inputs.filters.startWith([]).share()
let triggers = Observable.combineLatest(
filtersStream.debug("filters stream in combine", trimOutput: false),
inputs.reload
) { filters, _ in filters }//.share()
typealias FetchResultType = ([ItemType], Filters)
let fetchedData = triggers
.flatMap { filters -> Observable<Event<FetchResultType>> in
return (getItems(filters)
.asObservable()
.withLatestFrom(Observable.just(filters)) { ($0, $1) } as Observable<FetchResultType>)
.materialize()
}
let successSections = fetchedData
.elements()
.map { args -> [ListItemSectionModel] in
let filteredItems = filterFunc(args.0, args.1)
return createItems(
items: filteredItems.map { $0.asListItem() },
filteringEnabled: filteringEnabled,
filtersApplied: args.1.isApplied,
emptyListMessage: emptyListMessage
)
}
let finalSections = Observable.merge(
successSections,
fetchedData.errors().map(createErrorSections)
)
.asDriver(onErrorJustReturn: basicErrorSection())
let title = triggers
.map { _ in () }
.flatMap { getTitle() }
.asDriver(onErrorJustReturn: "")
let loadStarts = triggers.map { _ in true }
let loadEnds = fetchedData.elements().delay(0.3, scheduler: MainScheduler.instance).map { _ in false }
let isLoading = Observable.merge([loadStarts, loadEnds])
.startWith(false)
.distinctUntilChanged()
.asDriver(onErrorJustReturn: false)
let tappedChange = inputs.listItemTapped
.filterMap(ListItem.FilterMaps.applyFilters)
let changeFilters = tappedChange.withLatestFrom(filtersStream.debug("filters stram in change filters", trimOutput: false))
let listItemTapped = inputs.listItemTapped.filter {
if case ListItem.filter(_) = $0 {
return false
}
return true
}
outputs = Outputs(
sections: finalSections,
isLoading: isLoading,
title: title,
menuItems: menuItems,
changeFilters: changeFilters,
itemSelected: listItemTapped
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment