/* * Copyright (C) 2016 Simon Vig Therkildsen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.simonvt.cathode.ui.lists; import android.app.Dialog; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.DialogFragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.LinearLayout; import android.widget.TextView; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.Unbinder; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import javax.inject.Inject; import net.simonvt.cathode.CathodeApp; import net.simonvt.cathode.R; import net.simonvt.cathode.database.SimpleCursor; import net.simonvt.cathode.database.SimpleCursorLoader; import net.simonvt.cathode.provider.DatabaseContract.ListItemColumns; import net.simonvt.cathode.provider.DatabaseContract.ListsColumns; import net.simonvt.cathode.provider.ProviderSchematic; import net.simonvt.cathode.provider.ProviderSchematic.ListItems; import net.simonvt.cathode.scheduler.ListsTaskScheduler; import net.simonvt.schematic.Cursors; public class ListsDialog extends DialogFragment { private static class Item { long listId; String listName; boolean checked; public Item(long listId, String listName) { this.listId = listId; this.listName = listName; } } private static final String ARG_TYPE = "net.simonvt.cathode.ui.lists.ListsDialog.itemType"; private static final String ARG_ID = "net.simonvt.cathode.ui.lists.ListsDialog.itemId"; private static final int LOADER_DIALOG_LISTS = 1; private static final int LOADER_DIALOG_LISTS_STATUS = 2; @Inject ListsTaskScheduler listScheduler; private int itemType; private long itemId; private SimpleCursor listsCursor; private SimpleCursor listItemCursor; private List<Item> lists = new ArrayList<>(); private Unbinder unbinder; @BindView(R.id.container) LinearLayout container; private View loading; private View empty; public static ListsDialog newInstance(int itemType, long itemId) { ListsDialog dialog = new ListsDialog(); Bundle args = new Bundle(); args.putInt(ARG_TYPE, itemType); args.putLong(ARG_ID, itemId); dialog.setArguments(args); return dialog; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); CathodeApp.inject(getActivity(), this); Bundle args = getArguments(); itemType = args.getInt(ARG_TYPE); itemId = args.getLong(ARG_ID); getLoaderManager().initLoader(LOADER_DIALOG_LISTS, null, listsLoader); getLoaderManager().initLoader(LOADER_DIALOG_LISTS_STATUS, null, listItemLoader); } @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Dialog dialog = super.onCreateDialog(savedInstanceState); dialog.setTitle(R.string.action_list_add); return dialog; } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle inState) { return inflater.inflate(R.layout.dialog_lists, container, false); } @Override public void onViewCreated(View view, @Nullable Bundle inState) { super.onViewCreated(view, inState); unbinder = ButterKnife.bind(this, view); loading = getLayoutInflater(inState).inflate(R.layout.dialog_lists_loading, container, false); empty = getLayoutInflater(inState).inflate(R.layout.dialog_lists_empty, container, false); updateList(); } @Override public void onDestroyView() { unbinder.unbind(); unbinder = null; loading = null; empty = null; super.onDestroyView(); } private void setListsCursor(SimpleCursor listsCursor) { this.listsCursor = listsCursor; updateList(); } private void setListItemCursor(SimpleCursor listItemCursor) { this.listItemCursor = listItemCursor; updateList(); } private void updateList() { if (getView() == null) { return; } container.removeAllViews(); if (listsCursor == null || listItemCursor == null) { container.addView(loading); return; } if (listsCursor.getCount() == 0) { container.addView(empty); return; } listsCursor.moveToPosition(-1); while (listsCursor.moveToNext()) { final long id = Cursors.getLong(listsCursor, ListsColumns.ID); final String name = Cursors.getString(listsCursor, ListsColumns.NAME); Item item = getItem(id); if (item == null) { item = new Item(id, name); lists.add(item); } else { item.listName = name; } item.checked = false; } Collections.sort(lists, comparator); listItemCursor.moveToPosition(-1); while (listItemCursor.moveToNext()) { final long listId = Cursors.getLong(listItemCursor, ListItemColumns.LIST_ID); getItem(listId).checked = true; } for (final Item item : lists) { View v = createView(item.listId, item.listName, item.checked); container.addView(v); } } Comparator<Item> comparator = new Comparator<Item>() { @Override public int compare(Item lhs, Item rhs) { return lhs.listName.compareToIgnoreCase(rhs.listName); } }; private Item getItem(long id) { for (Item item : lists) { if (id == item.listId) { return item; } } return null; } private View createView(final long listId, String listName, boolean checked) { View v = LayoutInflater.from(getActivity()).inflate(R.layout.row_dialog_lists, container, false); final TextView name = (TextView) v.findViewById(R.id.name); final CheckBox checkBox = (CheckBox) v.findViewById(R.id.checkBox); name.setText(listName); checkBox.setChecked(checked); v.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Loader listsLoader = getLoaderManager().getLoader(LOADER_DIALOG_LISTS); Loader listItemLoader = getLoaderManager().getLoader(LOADER_DIALOG_LISTS_STATUS); ((SimpleCursorLoader) listsLoader).throttle(SimpleCursorLoader.DEFAULT_THROTTLE); ((SimpleCursorLoader) listItemLoader).throttle(SimpleCursorLoader.DEFAULT_THROTTLE); if (checkBox.isChecked()) { checkBox.setChecked(false); listScheduler.removeItem(listId, itemType, itemId); } else { checkBox.setChecked(true); listScheduler.addItem(listId, itemType, itemId); } } }); return v; } private static final String[] LISTS_PROJECTION = { ListsColumns.ID, ListsColumns.TRAKT_ID, ListsColumns.NAME, }; private static final String[] LIST_ITEM_PROJECTION = { ListItemColumns.ID, ListItemColumns.LIST_ID, }; private LoaderManager.LoaderCallbacks<SimpleCursor> listsLoader = new LoaderManager.LoaderCallbacks<SimpleCursor>() { @Override public Loader<SimpleCursor> onCreateLoader(int id, Bundle bundle) { return new SimpleCursorLoader(getActivity(), ProviderSchematic.Lists.LISTS, LISTS_PROJECTION, null, null, null); } @Override public void onLoadFinished(Loader<SimpleCursor> loader, SimpleCursor data) { setListsCursor(data); } @Override public void onLoaderReset(Loader<SimpleCursor> loader) { setListsCursor(null); } }; private LoaderManager.LoaderCallbacks<SimpleCursor> listItemLoader = new LoaderManager.LoaderCallbacks<SimpleCursor>() { @Override public Loader<SimpleCursor> onCreateLoader(int id, Bundle bundle) { return new SimpleCursorLoader(getActivity(), ListItems.LIST_ITEMS, LIST_ITEM_PROJECTION, ListItemColumns.ITEM_TYPE + "=? AND " + ListItemColumns.ITEM_ID + "=?", new String[] { String.valueOf(itemType), String.valueOf(itemId), }, null); } @Override public void onLoadFinished(Loader<SimpleCursor> loader, SimpleCursor data) { setListItemCursor(data); } @Override public void onLoaderReset(Loader<SimpleCursor> loader) { setListItemCursor(null); } }; }