package com.kickstarter.ui.adapters; import android.support.annotation.LayoutRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.view.View; import com.kickstarter.R; import com.kickstarter.models.User; import com.kickstarter.ui.adapters.data.NavigationDrawerData; import com.kickstarter.ui.viewholders.EmptyViewHolder; import com.kickstarter.ui.viewholders.KSViewHolder; import com.kickstarter.ui.viewholders.discoverydrawer.ChildFilterViewHolder; import com.kickstarter.ui.viewholders.discoverydrawer.LoggedInViewHolder; import com.kickstarter.ui.viewholders.discoverydrawer.LoggedOutViewHolder; import com.kickstarter.ui.viewholders.discoverydrawer.ParentFilterViewHolder; import com.kickstarter.ui.viewholders.discoverydrawer.TopFilterViewHolder; import java.util.ArrayList; import java.util.Collections; import java.util.List; import rx.Observable; public class DiscoveryDrawerAdapter extends KSAdapter { private @NonNull Delegate delegate; private @NonNull NavigationDrawerData drawerData; public DiscoveryDrawerAdapter(final @NonNull Delegate delegate) { this.delegate = delegate; setHasStableIds(true); } @Override public long getItemId(final int position) { return position; } public interface Delegate extends LoggedInViewHolder.Delegate, LoggedOutViewHolder.Delegate, TopFilterViewHolder.Delegate, ParentFilterViewHolder.Delegate, ChildFilterViewHolder.Delegate {} @Override protected int layout(final @NonNull SectionRow sectionRow) { final Object object = objectFromSectionRow(sectionRow); switch (sectionRow.section()) { case 0: return (object == null) ? R.layout.discovery_drawer_logged_out_view : R.layout.discovery_drawer_logged_in_view; default: return layoutForDatum(object, sectionRow); } } private int layoutForDatum(final @NonNull Object datum, final @NonNull SectionRow sectionRow) { if (datum instanceof NavigationDrawerData.Section.Row) { final NavigationDrawerData.Section.Row row = (NavigationDrawerData.Section.Row) datum; if (sectionRow.row() == 0) { return row.params().isCategorySet() ? R.layout.discovery_drawer_parent_filter_view : R.layout.discovery_drawer_top_filter_view; } else { return R.layout.discovery_drawer_child_filter_view; } } return R.layout.discovery_drawer_divider_view; } @Override protected @Nullable Object objectFromSectionRow(final @NonNull SectionRow sectionRow) { final Object object = super.objectFromSectionRow(sectionRow); if (object == null) { return null; } if (object instanceof User) { return object; } final NavigationDrawerData.Section.Row row = (NavigationDrawerData.Section.Row) object; final boolean expanded; if (row.params().category() == null || drawerData.expandedCategory() == null) { expanded = false; } else { expanded = row.params().category().rootId() == drawerData.expandedCategory().rootId(); } return row .toBuilder() .selected(row.params().equals(drawerData.selectedParams())) .rootIsExpanded(expanded) .build(); } @Override protected @NonNull KSViewHolder viewHolder(final @LayoutRes int layout, final @NonNull View view) { switch (layout) { case R.layout.discovery_drawer_logged_in_view: return new LoggedInViewHolder(view, delegate); case R.layout.discovery_drawer_logged_out_view: return new LoggedOutViewHolder(view, delegate); case R.layout.discovery_drawer_parent_filter_view: return new ParentFilterViewHolder(view, delegate); case R.layout.discovery_drawer_top_filter_view: return new TopFilterViewHolder(view, delegate); case R.layout.discovery_drawer_child_filter_view: return new ChildFilterViewHolder(view, delegate); case R.layout.discovery_drawer_divider_view: default: return new EmptyViewHolder(view); } } public void takeData(final @NonNull NavigationDrawerData data) { drawerData = data; this.sections().clear(); this.sections().addAll(sectionsFromData(data)); notifyDataSetChanged(); } private @NonNull List<List<Object>> sectionsFromData(final @NonNull NavigationDrawerData data) { final List<List<Object>> newSections = new ArrayList<>(); newSections.add(Collections.singletonList(data.user())); final List<NavigationDrawerData.Section> topFilterSections = Observable.from(data.sections()) .filter(NavigationDrawerData.Section::isTopFilter) .toList().toBlocking().single(); final List<NavigationDrawerData.Section> categoryFilterSections = Observable.from(data.sections()) .filter(NavigationDrawerData.Section::isCategoryFilter) .toList().toBlocking().single(); for (final NavigationDrawerData.Section section : topFilterSections) { newSections.add(new ArrayList<>(section.rows())); } newSections.add(Collections.singletonList(null)); // Divider for (final NavigationDrawerData.Section section : categoryFilterSections) { newSections.add(new ArrayList<>(section.rows())); } return newSections; } }