Convert navigation drawer to Kotlin

pull/996/head
Alex Baker 4 years ago
parent 20ca1c6486
commit 71721f982a

@ -1,176 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.adapter;
import static com.todoroo.andlib.utility.AndroidUtilities.assertMainThread;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.tasks.LocalBroadcastManager;
import org.tasks.billing.Inventory;
import org.tasks.data.CaldavDao;
import org.tasks.data.GoogleTaskDao;
import org.tasks.filters.NavigationDrawerSubheader;
import org.tasks.locale.Locale;
import org.tasks.preferences.Preferences;
import org.tasks.themes.ColorProvider;
public class FilterAdapter extends BaseAdapter {
private static final String TOKEN_FILTERS = "token_filters";
private static final String TOKEN_SELECTED = "token_selected";
private static final int VIEW_TYPE_COUNT = FilterListItem.Type.values().length;
private final Activity activity;
private final Locale locale;
private final Inventory inventory;
private final ColorProvider colorProvider;
private final Preferences preferences;
private final GoogleTaskDao googleTaskDao;
private final CaldavDao caldavDao;
private final LocalBroadcastManager localBroadcastManager;
private Filter selected = null;
private List<FilterListItem> items = new ArrayList<>();
@Inject
public FilterAdapter(
Activity activity,
Locale locale,
Inventory inventory,
ColorProvider colorProvider,
Preferences preferences,
GoogleTaskDao googleTaskDao,
CaldavDao caldavDao,
LocalBroadcastManager localBroadcastManager) {
this.activity = activity;
this.locale = locale;
this.inventory = inventory;
this.colorProvider = colorProvider;
this.preferences = preferences;
this.googleTaskDao = googleTaskDao;
this.caldavDao = caldavDao;
this.localBroadcastManager = localBroadcastManager;
}
public void save(Bundle outState) {
outState.putParcelableArrayList(TOKEN_FILTERS, getItems());
outState.putParcelable(TOKEN_SELECTED, selected);
}
public void restore(Bundle savedInstanceState) {
items = savedInstanceState.getParcelableArrayList(TOKEN_FILTERS);
selected = savedInstanceState.getParcelable(TOKEN_SELECTED);
}
public void setData(List<FilterListItem> items, @Nullable Filter selected) {
assertMainThread();
this.items = items;
this.selected = selected;
notifyDataSetChanged();
}
@Override
public int getCount() {
assertMainThread();
return items.size();
}
@Override
public FilterListItem getItem(int position) {
assertMainThread();
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
/** Create or reuse a view */
private View newView(View convertView, ViewGroup parent, FilterListItem.Type viewType) {
if (convertView == null) {
convertView =
LayoutInflater.from(parent.getContext()).inflate(viewType.layout, parent, false);
ViewHolder viewHolder;
switch (viewType) {
case ITEM:
viewHolder =
new FilterViewHolder(
convertView, false, locale, activity, inventory, colorProvider, null);
break;
case SEPARATOR:
viewHolder = new FilterViewHolder(convertView);
break;
case SUBHEADER:
viewHolder =
new SubheaderViewHolder(
convertView,
activity,
preferences,
googleTaskDao,
caldavDao,
localBroadcastManager);
break;
default:
throw new RuntimeException();
}
convertView.setTag(viewHolder);
}
return convertView;
}
private ArrayList<FilterListItem> getItems() {
assertMainThread();
return new ArrayList<>(items);
}
@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
FilterListItem item = getItem(position);
convertView = newView(convertView, parent, item.getItemType());
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
switch (item.getItemType()) {
case ITEM:
((FilterViewHolder) viewHolder).bind(item, item.equals(selected), 0);
break;
case SUBHEADER:
((SubheaderViewHolder) viewHolder).bind((NavigationDrawerSubheader) item);
break;
case SEPARATOR:
break;
}
return convertView;
}
@Override
public int getViewTypeCount() {
return VIEW_TYPE_COUNT;
}
@Override
public boolean isEnabled(int position) {
return getItem(position).getItemType() == FilterListItem.Type.ITEM;
}
@Override
public int getItemViewType(int position) {
return getItem(position).getItemType().ordinal();
}
}

@ -0,0 +1,121 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.adapter
import android.app.Activity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import androidx.recyclerview.widget.RecyclerView
import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.FilterListItem
import com.todoroo.astrid.api.FilterListItem.Type.*
import org.tasks.LocalBroadcastManager
import org.tasks.billing.Inventory
import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskDao
import org.tasks.filters.NavigationDrawerSubheader
import org.tasks.locale.Locale
import org.tasks.preferences.Preferences
import org.tasks.themes.ColorProvider
import java.util.*
import javax.inject.Inject
class FilterAdapter @Inject constructor(
private val activity: Activity,
private val locale: Locale,
private val inventory: Inventory,
private val colorProvider: ColorProvider,
private val preferences: Preferences,
private val googleTaskDao: GoogleTaskDao,
private val caldavDao: CaldavDao,
private val localBroadcastManager: LocalBroadcastManager) : BaseAdapter() {
private var selected: Filter? = null
private var items: List<FilterListItem> = ArrayList()
fun save(outState: Bundle) {
outState.putParcelableArrayList(TOKEN_FILTERS, getItems())
outState.putParcelable(TOKEN_SELECTED, selected)
}
fun restore(savedInstanceState: Bundle) {
items = savedInstanceState.getParcelableArrayList(TOKEN_FILTERS) ?: ArrayList()
selected = savedInstanceState.getParcelable(TOKEN_SELECTED)
}
fun setData(items: List<FilterListItem>, selected: Filter?) {
AndroidUtilities.assertMainThread()
this.items = items
this.selected = selected
notifyDataSetChanged()
}
override fun getCount(): Int {
AndroidUtilities.assertMainThread()
return items.size
}
override fun getItem(position: Int): FilterListItem {
AndroidUtilities.assertMainThread()
return items[position]
}
override fun getItemId(position: Int) = position.toLong()
/** Create or reuse a view */
private fun newView(convertView: View?, parent: ViewGroup, viewType: FilterListItem.Type): View {
return if (convertView != null) {
convertView
} else {
val newView = LayoutInflater.from(parent.context).inflate(viewType.layout, parent, false)
newView.tag = when (viewType) {
ITEM -> FilterViewHolder(
newView, false, locale, activity, inventory, colorProvider, null)
SEPARATOR -> FilterViewHolder(newView)
SUBHEADER -> SubheaderViewHolder(
newView,
activity,
preferences,
googleTaskDao,
caldavDao,
localBroadcastManager)
}
newView
}
}
private fun getItems(): ArrayList<FilterListItem> {
AndroidUtilities.assertMainThread()
return ArrayList(items)
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val item = getItem(position)
val view = newView(convertView, parent, item.itemType)
val viewHolder = view.tag as RecyclerView.ViewHolder
when (item.itemType) {
ITEM -> (viewHolder as FilterViewHolder).bind(item, item == selected, 0)
SUBHEADER -> (viewHolder as SubheaderViewHolder).bind((item as NavigationDrawerSubheader))
else -> {}
}
return view
}
override fun getViewTypeCount() = VIEW_TYPE_COUNT
override fun isEnabled(position: Int) = getItem(position).itemType == ITEM
override fun getItemViewType(position: Int) = getItem(position).itemType.ordinal
companion object {
private const val TOKEN_FILTERS = "token_filters"
private const val TOKEN_SELECTED = "token_selected"
private val VIEW_TYPE_COUNT = values().size
}
}

@ -1,137 +0,0 @@
package com.todoroo.astrid.adapter;
import android.app.Activity;
import android.view.View;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.todoroo.astrid.api.CaldavFilter;
import com.todoroo.astrid.api.CustomFilter;
import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.api.GtasksFilter;
import com.todoroo.astrid.api.TagFilter;
import org.tasks.R;
import org.tasks.billing.Inventory;
import org.tasks.filters.PlaceFilter;
import org.tasks.locale.Locale;
import org.tasks.themes.ColorProvider;
import org.tasks.themes.CustomIcons;
import org.tasks.themes.DrawableUtil;
import org.tasks.themes.ThemeColor;
public class FilterViewHolder extends RecyclerView.ViewHolder {
@Nullable
@BindView(R.id.row)
View row;
@BindView(R.id.text)
CheckedTextView text;
@BindView(R.id.icon)
ImageView icon;
@Nullable
@BindView(R.id.size)
TextView size;
private OnClick onClick;
private boolean navigationDrawer;
private Locale locale;
private Activity activity;
private View itemView;
private Inventory inventory;
private ColorProvider colorProvider;
FilterViewHolder(
@NonNull View itemView,
boolean navigationDrawer,
Locale locale,
Activity activity,
Inventory inventory,
ColorProvider colorProvider,
OnClick onClick) {
super(itemView);
this.inventory = inventory;
this.colorProvider = colorProvider;
ButterKnife.bind(this, itemView);
this.itemView = itemView;
this.navigationDrawer = navigationDrawer;
this.locale = locale;
this.activity = activity;
this.onClick = onClick;
if (navigationDrawer) {
text.setCheckMarkDrawable(null);
}
}
FilterViewHolder(@NonNull View itemView) {
super(itemView);
}
public void bind(FilterListItem filter, boolean selected, Integer count) {
if (navigationDrawer) {
itemView.setSelected(selected);
} else {
text.setChecked(selected);
}
int icon = getIcon(filter);
this.icon.setImageDrawable(DrawableUtil.getWrapped(activity, icon));
this.icon.getDrawable().setTint(getColor(filter));
text.setText(filter.listingTitle);
if (count == null || count == 0) {
size.setVisibility(View.GONE);
} else {
size.setText(locale.formatNumber(count));
size.setVisibility(View.VISIBLE);
}
if (onClick != null) {
row.setOnClickListener(v -> onClick.onClick(filter));
}
}
private int getColor(FilterListItem filter) {
if (filter.tint != 0) {
ThemeColor color = colorProvider.getThemeColor(filter.tint, true);
if (color.isFree() || inventory.purchasedThemes()) {
return color.getPrimaryColor();
}
}
return activity.getColor(R.color.text_primary);
}
private int getIcon(FilterListItem filter) {
if (filter.icon < 1000 || inventory.hasPro()) {
Integer icon = CustomIcons.getIconResId(filter.icon);
if (icon != null) {
return icon;
}
}
if (filter instanceof TagFilter) {
return R.drawable.ic_outline_label_24px;
} else if (filter instanceof GtasksFilter || filter instanceof CaldavFilter) {
return R.drawable.ic_outline_cloud_24px;
} else if (filter instanceof CustomFilter) {
return R.drawable.ic_outline_filter_list_24px;
} else if (filter instanceof PlaceFilter) {
return R.drawable.ic_outline_place_24px;
} else {
return filter.icon;
}
}
public interface OnClick {
void onClick(@Nullable FilterListItem item);
}
}

@ -0,0 +1,109 @@
package com.todoroo.astrid.adapter
import android.app.Activity
import android.view.View
import android.widget.CheckedTextView
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.ButterKnife
import com.todoroo.astrid.api.*
import org.tasks.R
import org.tasks.billing.Inventory
import org.tasks.filters.PlaceFilter
import org.tasks.locale.Locale
import org.tasks.themes.ColorProvider
import org.tasks.themes.CustomIcons.getIconResId
import org.tasks.themes.DrawableUtil
class FilterViewHolder : RecyclerView.ViewHolder {
@BindView(R.id.row)
lateinit var row: View
@BindView(R.id.text)
lateinit var text: CheckedTextView
@BindView(R.id.icon)
lateinit var icon: ImageView
@BindView(R.id.size)
lateinit var size: TextView
private var onClick: ((FilterListItem?) -> Unit)? = null
private var navigationDrawer = false
private var locale: Locale? = null
private var activity: Activity? = null
private var inventory: Inventory? = null
private var colorProvider: ColorProvider? = null
internal constructor(
itemView: View,
navigationDrawer: Boolean,
locale: Locale,
activity: Activity,
inventory: Inventory,
colorProvider: ColorProvider,
onClick: ((FilterListItem?) -> Unit)?) : super(itemView) {
this.inventory = inventory
this.colorProvider = colorProvider
ButterKnife.bind(this, itemView)
this.navigationDrawer = navigationDrawer
this.locale = locale
this.activity = activity
this.onClick = onClick
if (navigationDrawer) {
text.checkMarkDrawable = null
}
}
internal constructor(itemView: View) : super(itemView)
fun bind(filter: FilterListItem, selected: Boolean, count: Int?) {
if (navigationDrawer) {
itemView.isSelected = selected
} else {
text.isChecked = selected
}
val icon = getIcon(filter)
this.icon.setImageDrawable(DrawableUtil.getWrapped(activity, icon))
this.icon.drawable.setTint(getColor(filter))
text.text = filter.listingTitle
if (count == null || count == 0) {
size.visibility = View.GONE
} else {
size.text = locale!!.formatNumber(count)
size.visibility = View.VISIBLE
}
row.setOnClickListener {
onClick?.invoke(filter)
}
}
private fun getColor(filter: FilterListItem): Int {
if (filter.tint != 0) {
val color = colorProvider!!.getThemeColor(filter.tint, true)
if (color.isFree || inventory!!.purchasedThemes()) {
return color.primaryColor
}
}
return activity!!.getColor(R.color.text_primary)
}
private fun getIcon(filter: FilterListItem): Int {
if (filter.icon < 1000 || inventory!!.hasPro()) {
val icon = getIconResId(filter.icon)
if (icon != null) {
return icon
}
}
return when (filter) {
is TagFilter -> R.drawable.ic_outline_label_24px
is GtasksFilter -> R.drawable.ic_outline_cloud_24px
is CaldavFilter -> R.drawable.ic_outline_cloud_24px
is CustomFilter -> R.drawable.ic_outline_filter_list_24px
is PlaceFilter -> R.drawable.ic_outline_place_24px
else -> filter.icon
}
}
}

@ -1,161 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.adapter;
import static com.google.common.base.Objects.equal;
import static com.todoroo.astrid.api.FilterListItem.Type.ITEM;
import static com.todoroo.astrid.api.FilterListItem.Type.SUBHEADER;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.AsyncListDiffer;
import androidx.recyclerview.widget.DiffUtil.ItemCallback;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.todoroo.astrid.adapter.FilterViewHolder.OnClick;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.api.FilterListItem.Type;
import java.util.List;
import javax.inject.Inject;
import org.tasks.LocalBroadcastManager;
import org.tasks.billing.Inventory;
import org.tasks.data.CaldavDao;
import org.tasks.data.GoogleTaskDao;
import org.tasks.filters.NavigationDrawerSubheader;
import org.tasks.locale.Locale;
import org.tasks.preferences.Preferences;
import org.tasks.themes.ColorProvider;
public class NavigationDrawerAdapter extends RecyclerView.Adapter<ViewHolder> {
private static final String TOKEN_SELECTED = "token_selected";
private final Activity activity;
private final Locale locale;
private final Inventory inventory;
private final ColorProvider colorProvider;
private final Preferences preferences;
private final GoogleTaskDao googleTaskDao;
private final CaldavDao caldavDao;
private final LocalBroadcastManager localBroadcastManager;
private OnClick onClick;
private Filter selected = null;
private final AsyncListDiffer<FilterListItem> differ;
@Inject
public NavigationDrawerAdapter(
Activity activity,
Locale locale,
Inventory inventory,
ColorProvider colorProvider,
Preferences preferences,
GoogleTaskDao googleTaskDao,
CaldavDao caldavDao,
LocalBroadcastManager localBroadcastManager) {
this.activity = activity;
this.locale = locale;
this.inventory = inventory;
this.colorProvider = colorProvider;
this.preferences = preferences;
this.googleTaskDao = googleTaskDao;
this.caldavDao = caldavDao;
this.localBroadcastManager = localBroadcastManager;
differ = new AsyncListDiffer<>(this, new DiffCallback());
}
public void setOnClick(OnClick onClick) {
this.onClick = onClick;
}
public void save(Bundle outState) {
outState.putParcelable(TOKEN_SELECTED, selected);
}
public void restore(Bundle savedInstanceState) {
selected = savedInstanceState.getParcelable(TOKEN_SELECTED);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return differ.getCurrentList().size();
}
public void setSelected(Filter selected) {
this.selected = selected;
notifyDataSetChanged();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Type type = Type.values()[viewType];
View view = LayoutInflater.from(parent.getContext()).inflate(type.layout, parent, false);
if (type == ITEM) {
return new FilterViewHolder(
view, true, locale, activity, inventory, colorProvider, this::onClickFilter);
} else if (type == SUBHEADER) {
return new SubheaderViewHolder(
view, activity, preferences, googleTaskDao, caldavDao, localBroadcastManager);
} else {
return new FilterViewHolder(view);
}
}
private void onClickFilter(@Nullable FilterListItem filter) {
onClick.onClick(equal(filter, selected) ? null : filter);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
FilterListItem item = getItem(position);
Type type = item.getItemType();
if (type == ITEM) {
((FilterViewHolder) holder).bind(item, item.equals(selected), Math.max(item.count, 0));
} else if (type == SUBHEADER) {
((SubheaderViewHolder) holder).bind((NavigationDrawerSubheader) item);
}
}
@Override
public int getItemViewType(int position) {
return getItem(position).getItemType().ordinal();
}
private FilterListItem getItem(int position) {
return differ.getCurrentList().get(position);
}
public void submitList(List<FilterListItem> filterListItems) {
differ.submitList(filterListItems);
}
private static class DiffCallback extends ItemCallback<FilterListItem> {
@Override
public boolean areItemsTheSame(
@NonNull FilterListItem oldItem, @NonNull FilterListItem newItem) {
return oldItem.areItemsTheSame(newItem);
}
@Override
public boolean areContentsTheSame(
@NonNull FilterListItem oldItem, @NonNull FilterListItem newItem) {
return oldItem.areContentsTheSame(newItem);
}
}
}

@ -0,0 +1,103 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.adapter
import android.app.Activity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.FilterListItem
import org.tasks.LocalBroadcastManager
import org.tasks.billing.Inventory
import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskDao
import org.tasks.filters.NavigationDrawerSubheader
import org.tasks.locale.Locale
import org.tasks.preferences.Preferences
import org.tasks.themes.ColorProvider
import javax.inject.Inject
import kotlin.math.max
class NavigationDrawerAdapter @Inject constructor(
private val activity: Activity,
private val locale: Locale,
private val inventory: Inventory,
private val colorProvider: ColorProvider,
private val preferences: Preferences,
private val googleTaskDao: GoogleTaskDao,
private val caldavDao: CaldavDao,
private val localBroadcastManager: LocalBroadcastManager)
: RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private lateinit var onClick: (FilterListItem?) -> Unit
private var selected: Filter? = null
private val differ = AsyncListDiffer(this, DiffCallback())
fun setOnClick(onClick: (FilterListItem?) -> Unit) {
this.onClick = onClick
}
fun save(outState: Bundle) {
outState.putParcelable(TOKEN_SELECTED, selected)
}
fun restore(savedInstanceState: Bundle) {
selected = savedInstanceState.getParcelable(TOKEN_SELECTED)
}
override fun getItemId(position: Int) = position.toLong()
override fun getItemCount() = differ.currentList.size
fun setSelected(selected: Filter?) {
this.selected = selected
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val type = FilterListItem.Type.values()[viewType]
val view = LayoutInflater.from(parent.context).inflate(type.layout, parent, false)
return when (type) {
FilterListItem.Type.ITEM -> FilterViewHolder(
view, true, locale, activity, inventory, colorProvider) { filter: FilterListItem? -> onClickFilter(filter) }
FilterListItem.Type.SUBHEADER -> SubheaderViewHolder(
view, activity, preferences, googleTaskDao, caldavDao, localBroadcastManager)
else -> FilterViewHolder(view)
}
}
private fun onClickFilter(filter: FilterListItem?) = onClick.invoke(if (filter == selected) null else filter)
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = getItem(position)
val type = item.itemType
if (type == FilterListItem.Type.ITEM) {
(holder as FilterViewHolder).bind(item, item == selected, max(item.count, 0))
} else if (type == FilterListItem.Type.SUBHEADER) {
(holder as SubheaderViewHolder).bind((item as NavigationDrawerSubheader))
}
}
override fun getItemViewType(position: Int) = getItem(position).itemType.ordinal
private fun getItem(position: Int) = differ.currentList[position]
fun submitList(filterListItems: List<FilterListItem>) = differ.submitList(filterListItems)
private class DiffCallback : DiffUtil.ItemCallback<FilterListItem>() {
override fun areItemsTheSame(old: FilterListItem, new: FilterListItem) = old.areItemsTheSame(new)
override fun areContentsTheSame(old: FilterListItem, new: FilterListItem) = old.areContentsTheSame(new)
}
companion object {
private const val TOKEN_SELECTED = "token_selected"
}
}

@ -1,83 +0,0 @@
package com.todoroo.astrid.adapter;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import org.tasks.LocalBroadcastManager;
import org.tasks.R;
import org.tasks.data.CaldavDao;
import org.tasks.data.GoogleTaskDao;
import org.tasks.filters.NavigationDrawerSubheader;
import org.tasks.preferences.Preferences;
import org.tasks.preferences.SyncPreferences;
import org.tasks.themes.DrawableUtil;
class SubheaderViewHolder extends RecyclerView.ViewHolder {
private final Preferences preferences;
private final GoogleTaskDao googleTaskDao;
private final CaldavDao caldavDao;
private final LocalBroadcastManager localBroadcastManager;
@BindView(R.id.text)
TextView text;
@BindView(R.id.icon_error)
ImageView errorIcon;
private NavigationDrawerSubheader subheader;
SubheaderViewHolder(
@NonNull View itemView,
Activity activity,
Preferences preferences,
GoogleTaskDao googleTaskDao,
CaldavDao caldavDao,
LocalBroadcastManager localBroadcastManager) {
super(itemView);
this.preferences = preferences;
this.googleTaskDao = googleTaskDao;
this.caldavDao = caldavDao;
this.localBroadcastManager = localBroadcastManager;
ButterKnife.bind(this, itemView);
errorIcon.setOnClickListener(
v -> activity.startActivity(new Intent(activity, SyncPreferences.class)));
}
@OnClick(R.id.subheader_row)
public void onClick() {
boolean collapsed = !subheader.isCollapsed();
switch (subheader.getSubheaderType()) {
case PREFERENCE:
preferences.setBoolean((int) subheader.getId(), collapsed);
break;
case GOOGLE_TASKS:
googleTaskDao.setCollapsed(subheader.getId(), collapsed);
break;
case CALDAV:
caldavDao.setCollapsed(subheader.getId(), collapsed);
break;
}
localBroadcastManager.broadcastRefreshList();
}
public void bind(NavigationDrawerSubheader subheader) {
this.subheader = subheader;
text.setText(subheader.listingTitle);
errorIcon.setVisibility(subheader.error ? View.VISIBLE : View.GONE);
DrawableUtil.setRightDrawable(
itemView.getContext(),
text,
subheader.isCollapsed()
? R.drawable.ic_keyboard_arrow_up_black_18dp
: R.drawable.ic_keyboard_arrow_down_black_18dp);
}
}

@ -0,0 +1,66 @@
package com.todoroo.astrid.adapter
import android.app.Activity
import android.content.Intent
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskDao
import org.tasks.filters.NavigationDrawerSubheader
import org.tasks.filters.NavigationDrawerSubheader.SubheaderType
import org.tasks.preferences.Preferences
import org.tasks.preferences.SyncPreferences
import org.tasks.themes.DrawableUtil
internal class SubheaderViewHolder(
itemView: View,
activity: Activity,
private val preferences: Preferences,
private val googleTaskDao: GoogleTaskDao,
private val caldavDao: CaldavDao,
private val localBroadcastManager: LocalBroadcastManager)
: RecyclerView.ViewHolder(itemView) {
@BindView(R.id.text)
lateinit var text: TextView
@BindView(R.id.icon_error)
lateinit var errorIcon: ImageView
private lateinit var subheader: NavigationDrawerSubheader
@OnClick(R.id.subheader_row)
fun onClick() {
val collapsed = !subheader.isCollapsed
when (subheader.subheaderType) {
SubheaderType.PREFERENCE -> preferences.setBoolean(subheader.id.toInt(), collapsed)
SubheaderType.GOOGLE_TASKS -> googleTaskDao.setCollapsed(subheader.id, collapsed)
SubheaderType.CALDAV -> caldavDao.setCollapsed(subheader.id, collapsed)
}
localBroadcastManager.broadcastRefreshList()
}
fun bind(subheader: NavigationDrawerSubheader) {
this.subheader = subheader
text.text = subheader.listingTitle
errorIcon.visibility = if (subheader.error) View.VISIBLE else View.GONE
DrawableUtil.setRightDrawable(
itemView.context,
text,
if (subheader.isCollapsed) R.drawable.ic_keyboard_arrow_up_black_18dp else R.drawable.ic_keyboard_arrow_down_black_18dp)
}
init {
ButterKnife.bind(this, itemView)
errorIcon.setOnClickListener {
activity.startActivity(Intent(activity, SyncPreferences::class.java))
}
}
}

@ -1,114 +0,0 @@
package com.todoroo.astrid.adapter;
import static org.tasks.Strings.isNullOrEmpty;
import android.content.Context;
import com.todoroo.astrid.api.CaldavFilter;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.GtasksFilter;
import com.todoroo.astrid.api.TagFilter;
import com.todoroo.astrid.core.BuiltInFilterExposer;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.subtasks.SubtasksFilterUpdater;
import com.todoroo.astrid.subtasks.SubtasksHelper;
import javax.inject.Inject;
import org.tasks.LocalBroadcastManager;
import org.tasks.data.CaldavDao;
import org.tasks.data.GoogleTaskDao;
import org.tasks.data.TagData;
import org.tasks.data.TaskListMetadata;
import org.tasks.data.TaskListMetadataDao;
import org.tasks.injection.ForApplication;
import org.tasks.preferences.Preferences;
public class TaskAdapterProvider {
private final Context context;
private final Preferences preferences;
private final TaskListMetadataDao taskListMetadataDao;
private final TaskDao taskDao;
private final GoogleTaskDao googleTaskDao;
private final CaldavDao caldavDao;
private final SubtasksHelper subtasksHelper;
private final LocalBroadcastManager localBroadcastManager;
@Inject
public TaskAdapterProvider(
@ForApplication Context context,
Preferences preferences,
TaskListMetadataDao taskListMetadataDao,
TaskDao taskDao,
GoogleTaskDao googleTaskDao,
CaldavDao caldavDao,
SubtasksHelper subtasksHelper,
LocalBroadcastManager localBroadcastManager) {
this.context = context;
this.preferences = preferences;
this.taskListMetadataDao = taskListMetadataDao;
this.taskDao = taskDao;
this.googleTaskDao = googleTaskDao;
this.caldavDao = caldavDao;
this.subtasksHelper = subtasksHelper;
this.localBroadcastManager = localBroadcastManager;
}
public TaskAdapter createTaskAdapter(Filter filter) {
if (preferences.isManualSort()) {
if (filter instanceof TagFilter) {
return createManualTagTaskAdapter((TagFilter) filter);
} else if (filter instanceof GtasksFilter) {
return new GoogleTaskManualSortAdapter(googleTaskDao, caldavDao, taskDao, localBroadcastManager);
} else if (filter instanceof CaldavFilter) {
return new CaldavManualSortTaskAdapter(googleTaskDao, caldavDao, taskDao, localBroadcastManager);
} else if (subtasksHelper.shouldUseSubtasksFragmentForFilter(filter)) {
return createManualFilterTaskAdapter(filter);
}
}
return new TaskAdapter(preferences.addTasksToTop(), googleTaskDao, caldavDao, taskDao, localBroadcastManager);
}
private TaskAdapter createManualTagTaskAdapter(TagFilter filter) {
TagData tagData = filter.getTagData();
String tdId = tagData.getRemoteId();
TaskListMetadata list = taskListMetadataDao.fetchByTagOrFilter(tagData.getRemoteId());
if (list == null && !Task.isUuidEmpty(tdId)) {
list = new TaskListMetadata();
list.setTagUuid(tdId);
taskListMetadataDao.createNew(list);
}
SubtasksFilterUpdater updater = new SubtasksFilterUpdater(taskListMetadataDao, taskDao);
updater.initialize(list, filter);
return new AstridTaskAdapter(list, filter, updater, googleTaskDao, caldavDao, taskDao, localBroadcastManager);
}
private TaskAdapter createManualFilterTaskAdapter(Filter filter) {
String filterId = null;
String prefId = null;
if (BuiltInFilterExposer.isInbox(context, filter)) {
filterId = TaskListMetadata.FILTER_ID_ALL;
prefId = SubtasksFilterUpdater.ACTIVE_TASKS_ORDER;
} else if (BuiltInFilterExposer.isTodayFilter(context, filter)) {
filterId = TaskListMetadata.FILTER_ID_TODAY;
prefId = SubtasksFilterUpdater.TODAY_TASKS_ORDER;
}
if (isNullOrEmpty(filterId)) {
return null;
}
TaskListMetadata list = taskListMetadataDao.fetchByTagOrFilter(filterId);
if (list == null) {
String defaultOrder = preferences.getStringValue(prefId);
if (isNullOrEmpty(defaultOrder)) {
defaultOrder = "[]"; // $NON-NLS-1$
}
defaultOrder = SubtasksHelper.convertTreeToRemoteIds(taskDao, defaultOrder);
list = new TaskListMetadata();
list.setFilter(filterId);
list.setTaskIds(defaultOrder);
taskListMetadataDao.createNew(list);
}
SubtasksFilterUpdater updater = new SubtasksFilterUpdater(taskListMetadataDao, taskDao);
updater.initialize(list, filter);
return new AstridTaskAdapter(list, filter, updater, googleTaskDao, caldavDao, taskDao, localBroadcastManager);
}
}

@ -0,0 +1,92 @@
package com.todoroo.astrid.adapter
import android.content.Context
import com.todoroo.astrid.api.CaldavFilter
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.GtasksFilter
import com.todoroo.astrid.api.TagFilter
import com.todoroo.astrid.core.BuiltInFilterExposer
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task.Companion.isUuidEmpty
import com.todoroo.astrid.subtasks.SubtasksFilterUpdater
import com.todoroo.astrid.subtasks.SubtasksHelper
import org.tasks.LocalBroadcastManager
import org.tasks.Strings.isNullOrEmpty
import org.tasks.data.CaldavDao
import org.tasks.data.GoogleTaskDao
import org.tasks.data.TaskListMetadata
import org.tasks.data.TaskListMetadataDao
import org.tasks.injection.ForApplication
import org.tasks.preferences.Preferences
import javax.inject.Inject
class TaskAdapterProvider @Inject constructor(
@param:ForApplication private val context: Context,
private val preferences: Preferences,
private val taskListMetadataDao: TaskListMetadataDao,
private val taskDao: TaskDao,
private val googleTaskDao: GoogleTaskDao,
private val caldavDao: CaldavDao,
private val subtasksHelper: SubtasksHelper,
private val localBroadcastManager: LocalBroadcastManager) {
fun createTaskAdapter(filter: Filter): TaskAdapter {
if (preferences.isManualSort) {
when {
filter is TagFilter -> return createManualTagTaskAdapter(filter)
filter is GtasksFilter -> return GoogleTaskManualSortAdapter(googleTaskDao, caldavDao, taskDao, localBroadcastManager)
filter is CaldavFilter -> return CaldavManualSortTaskAdapter(googleTaskDao, caldavDao, taskDao, localBroadcastManager)
subtasksHelper.shouldUseSubtasksFragmentForFilter(filter) -> {
val adapter = createManualFilterTaskAdapter(filter)
if (adapter != null) {
return adapter
}
}
}
}
return TaskAdapter(preferences.addTasksToTop(), googleTaskDao, caldavDao, taskDao, localBroadcastManager)
}
private fun createManualTagTaskAdapter(filter: TagFilter): TaskAdapter {
val tagData = filter.tagData
val tdId = tagData.remoteId
var list = taskListMetadataDao.fetchByTagOrFilter(tagData.remoteId!!)
if (list == null && !isUuidEmpty(tdId)) {
list = TaskListMetadata()
list.tagUuid = tdId
taskListMetadataDao.createNew(list)
}
val updater = SubtasksFilterUpdater(taskListMetadataDao, taskDao)
updater.initialize(list, filter)
return AstridTaskAdapter(list!!, filter, updater, googleTaskDao, caldavDao, taskDao, localBroadcastManager)
}
private fun createManualFilterTaskAdapter(filter: Filter): TaskAdapter? {
var filterId: String? = null
var prefId: String? = null
if (BuiltInFilterExposer.isInbox(context, filter)) {
filterId = TaskListMetadata.FILTER_ID_ALL
prefId = SubtasksFilterUpdater.ACTIVE_TASKS_ORDER
} else if (BuiltInFilterExposer.isTodayFilter(context, filter)) {
filterId = TaskListMetadata.FILTER_ID_TODAY
prefId = SubtasksFilterUpdater.TODAY_TASKS_ORDER
}
if (filterId.isNullOrBlank()) {
return null
}
var list = taskListMetadataDao.fetchByTagOrFilter(filterId)
if (list == null) {
var defaultOrder = preferences.getStringValue(prefId)
if (isNullOrEmpty(defaultOrder)) {
defaultOrder = "[]" // $NON-NLS-1$
}
defaultOrder = SubtasksHelper.convertTreeToRemoteIds(taskDao, defaultOrder)
list = TaskListMetadata()
list.filter = filterId
list.taskIds = defaultOrder
taskListMetadataDao.createNew(list)
}
val updater = SubtasksFilterUpdater(taskListMetadataDao, taskDao)
updater.initialize(list, filter)
return AstridTaskAdapter(list, filter, updater, googleTaskDao, caldavDao, taskDao, localBroadcastManager)
}
}

@ -16,7 +16,7 @@ import org.tasks.billing.Inventory
import org.tasks.billing.PurchaseActivity import org.tasks.billing.PurchaseActivity
import org.tasks.injection.DialogFragmentComponent import org.tasks.injection.DialogFragmentComponent
import org.tasks.injection.InjectingDialogFragment import org.tasks.injection.InjectingDialogFragment
import org.tasks.ui.NavigationDrawerFragment.REQUEST_PURCHASE import org.tasks.ui.NavigationDrawerFragment.Companion.REQUEST_PURCHASE
import javax.inject.Inject import javax.inject.Inject
private const val REQUEST_PURCHASE = 10010 private const val REQUEST_PURCHASE = 10010

@ -38,7 +38,7 @@ import org.tasks.themes.ThemeBase.EXTRA_THEME_OVERRIDE
import org.tasks.themes.ThemeColor import org.tasks.themes.ThemeColor
import org.tasks.themes.ThemeColor.getLauncherColor import org.tasks.themes.ThemeColor.getLauncherColor
import org.tasks.ui.ChipProvider import org.tasks.ui.ChipProvider
import org.tasks.ui.NavigationDrawerFragment.REQUEST_PURCHASE import org.tasks.ui.NavigationDrawerFragment.Companion.REQUEST_PURCHASE
import org.tasks.ui.SingleCheckedArrayAdapter import org.tasks.ui.SingleCheckedArrayAdapter
import org.tasks.ui.Toaster import org.tasks.ui.Toaster
import javax.inject.Inject import javax.inject.Inject

@ -1,241 +0,0 @@
package org.tasks.ui;
import static com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread;
import static org.tasks.LocalBroadcastManager.REFRESH;
import static org.tasks.LocalBroadcastManager.REFRESH_LIST;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.drawerlayout.widget.DrawerLayout.SimpleDrawerListener;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.todoroo.astrid.adapter.NavigationDrawerAdapter;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.dao.TaskDao;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import java.util.List;
import javax.inject.Inject;
import org.tasks.LocalBroadcastManager;
import org.tasks.R;
import org.tasks.billing.PurchaseActivity;
import org.tasks.dialogs.NewFilterDialog;
import org.tasks.filters.FilterProvider;
import org.tasks.filters.NavigationDrawerAction;
import org.tasks.injection.FragmentComponent;
import org.tasks.injection.InjectingFragment;
import org.tasks.intents.TaskIntents;
public class NavigationDrawerFragment extends InjectingFragment {
public static final int FRAGMENT_NAVIGATION_DRAWER = R.id.navigation_drawer;
public static final int REQUEST_NEW_LIST = 10100;
public static final int REQUEST_SETTINGS = 10101;
public static final int REQUEST_PURCHASE = 10102;
public static final int REQUEST_DONATE = 10103;
public static final int REQUEST_NEW_PLACE = 10104;
public static final int REQUEST_NEW_FILTER = 101015;
private static final String FRAG_TAG_NEW_FILTER = "frag_tag_new_filter";
private final RefreshReceiver refreshReceiver = new RefreshReceiver();
@Inject LocalBroadcastManager localBroadcastManager;
@Inject NavigationDrawerAdapter adapter;
@Inject FilterProvider filterProvider;
@Inject TaskDao taskDao;
/** A pointer to the current callbacks instance (the Activity). */
private DrawerLayout mDrawerLayout;
private RecyclerView recyclerView;
private View mFragmentContainerView;
private CompositeDisposable disposables;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
adapter.restore(savedInstanceState);
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getActivity().setDefaultKeyMode(Activity.DEFAULT_KEYS_SEARCH_LOCAL);
setUpList();
}
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
recyclerView = layout.findViewById(R.id.recycler_view);
((ScrimInsetsFrameLayout) layout.findViewById(R.id.scrim_layout))
.setOnInsetsCallback(insets -> recyclerView.setPadding(0, insets.top, 0, 0));
return layout;
}
private void setUpList() {
adapter.setOnClick(this::onFilterItemSelected);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
}
private void onFilterItemSelected(@Nullable FilterListItem item) {
mDrawerLayout.addDrawerListener(
new SimpleDrawerListener() {
@Override
public void onDrawerClosed(View drawerView) {
mDrawerLayout.removeDrawerListener(this);
if (item instanceof Filter) {
FragmentActivity activity = getActivity();
if (activity != null) {
activity.startActivity(TaskIntents.getTaskListIntent(activity, (Filter) item));
}
} else if (item instanceof NavigationDrawerAction) {
NavigationDrawerAction action = (NavigationDrawerAction) item;
if (action.requestCode == REQUEST_PURCHASE) {
startActivity(new Intent(getContext(), PurchaseActivity.class));
} else if (action.requestCode == REQUEST_DONATE) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://tasks.org/donate")));
} else if (action.requestCode == REQUEST_NEW_FILTER) {
NewFilterDialog.Companion.newFilterDialog()
.show(getParentFragmentManager(), FRAG_TAG_NEW_FILTER);
} else {
getActivity().startActivityForResult(action.intent, action.requestCode);
}
}
}
});
if (item instanceof Filter) {
new ViewModelProvider(getActivity()).get(TaskListViewModel.class).setFilter((Filter) item);
}
close();
}
public boolean isDrawerOpen() {
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
}
/**
* Users of this fragment must call this method to set up the navigation drawer interactions.
*
* @param drawerLayout The DrawerLayout containing this fragment's UI.
*/
public void setUp(DrawerLayout drawerLayout) {
mFragmentContainerView = getActivity().findViewById(FRAGMENT_NAVIGATION_DRAWER);
mDrawerLayout = drawerLayout;
}
public void setSelected(Filter selected) {
adapter.setSelected(selected);
}
@Override
public void onPause() {
super.onPause();
localBroadcastManager.unregisterReceiver(refreshReceiver);
}
@Override
public void onStart() {
super.onStart();
disposables = new CompositeDisposable();
}
@Override
public void onStop() {
super.onStop();
disposables.dispose();
}
@Override
protected void inject(FragmentComponent component) {
component.inject(this);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
adapter.save(outState);
}
public void closeDrawer() {
if (mDrawerLayout != null) {
mDrawerLayout.setDrawerListener(null);
close();
}
}
private void close() {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
public void openDrawer() {
if (mDrawerLayout != null) {
mDrawerLayout.openDrawer(mFragmentContainerView);
}
}
@Override
public void onResume() {
super.onResume();
localBroadcastManager.registerRefreshListReceiver(refreshReceiver);
disposables.add(updateFilters());
}
private Disposable updateFilters() {
return Single.fromCallable(() -> filterProvider.getItems(true))
.map(this::refreshFilterCount)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(adapter::submitList);
}
private List<FilterListItem> refreshFilterCount(List<FilterListItem> items) {
assertNotMainThread();
for (FilterListItem item : items) {
if (item instanceof Filter && item.count == -1) {
item.count = taskDao.count((Filter) item);
}
}
return items;
}
private class RefreshReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null) {
return;
}
String action = intent.getAction();
if (REFRESH.equals(action) || REFRESH_LIST.equals(action)) {
disposables.add(updateFilters());
}
}
}
}

@ -0,0 +1,193 @@
package org.tasks.ui
import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.graphics.Rect
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.drawerlayout.widget.DrawerLayout
import androidx.drawerlayout.widget.DrawerLayout.SimpleDrawerListener
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.astrid.adapter.NavigationDrawerAdapter
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.FilterListItem
import com.todoroo.astrid.dao.TaskDao
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.billing.PurchaseActivity
import org.tasks.dialogs.NewFilterDialog.Companion.newFilterDialog
import org.tasks.filters.FilterProvider
import org.tasks.filters.NavigationDrawerAction
import org.tasks.injection.FragmentComponent
import org.tasks.injection.InjectingFragment
import org.tasks.intents.TaskIntents
import javax.inject.Inject
class NavigationDrawerFragment : InjectingFragment() {
private val refreshReceiver = RefreshReceiver()
@Inject lateinit var localBroadcastManager: LocalBroadcastManager
@Inject lateinit var adapter: NavigationDrawerAdapter
@Inject lateinit var filterProvider: FilterProvider
@Inject lateinit var taskDao: TaskDao
private lateinit var recyclerView: RecyclerView
private lateinit var mDrawerLayout: DrawerLayout
private var disposables: CompositeDisposable? = null
private var mFragmentContainerView: View? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState != null) {
adapter.restore(savedInstanceState)
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
requireActivity().setDefaultKeyMode(Activity.DEFAULT_KEYS_SEARCH_LOCAL)
setUpList()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false)
recyclerView = layout.findViewById(R.id.recycler_view)
(layout.findViewById<View>(R.id.scrim_layout) as ScrimInsetsFrameLayout)
.setOnInsetsCallback { insets: Rect -> recyclerView.setPadding(0, insets.top, 0, 0) }
return layout
}
private fun setUpList() {
adapter.setOnClick { item: FilterListItem? -> onFilterItemSelected(item) }
recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.adapter = adapter
}
private fun onFilterItemSelected(item: FilterListItem?) {
mDrawerLayout.addDrawerListener(
object : SimpleDrawerListener() {
override fun onDrawerClosed(drawerView: View) {
mDrawerLayout.removeDrawerListener(this)
if (item is Filter) {
activity?.startActivity(TaskIntents.getTaskListIntent(activity, item))
} else if (item is NavigationDrawerAction) {
when (item.requestCode) {
REQUEST_PURCHASE -> startActivity(Intent(context, PurchaseActivity::class.java))
REQUEST_DONATE -> startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://tasks.org/donate")))
REQUEST_NEW_FILTER -> newFilterDialog().show(parentFragmentManager, FRAG_TAG_NEW_FILTER)
else -> activity?.startActivityForResult(item.intent, item.requestCode)
}
}
}
})
if (item is Filter) {
ViewModelProvider(requireActivity()).get(TaskListViewModel::class.java).setFilter((item as Filter?)!!)
}
close()
}
val isDrawerOpen: Boolean
get() = mDrawerLayout.isDrawerOpen(mFragmentContainerView!!)
/**
* Users of this fragment must call this method to set up the navigation drawer interactions.
*
* @param drawerLayout The DrawerLayout containing this fragment's UI.
*/
fun setUp(drawerLayout: DrawerLayout) {
mFragmentContainerView = requireActivity().findViewById(FRAGMENT_NAVIGATION_DRAWER)
mDrawerLayout = drawerLayout
}
fun setSelected(selected: Filter?) = adapter.setSelected(selected)
override fun onPause() {
super.onPause()
localBroadcastManager.unregisterReceiver(refreshReceiver)
}
override fun onStart() {
super.onStart()
disposables = CompositeDisposable()
}
override fun onStop() {
super.onStop()
disposables?.dispose()
}
override fun inject(component: FragmentComponent) = component.inject(this)
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
adapter.save(outState)
}
fun closeDrawer() {
mDrawerLayout.setDrawerListener(null)
close()
}
private fun close() = mDrawerLayout.closeDrawer(mFragmentContainerView!!)
fun openDrawer() = mDrawerLayout.openDrawer(mFragmentContainerView!!)
override fun onResume() {
super.onResume()
localBroadcastManager.registerRefreshListReceiver(refreshReceiver)
disposables?.add(updateFilters())
}
private fun updateFilters() =
Single.fromCallable { filterProvider.getItems(true) }
.map { items: List<FilterListItem> -> refreshFilterCount(items) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(adapter::submitList)
private fun refreshFilterCount(items: List<FilterListItem>): List<FilterListItem> {
AndroidUtilities.assertNotMainThread()
for (item in items) {
if (item is Filter && item.count == -1) {
item.count = taskDao.count(item)
}
}
return items
}
private inner class RefreshReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
if (intent == null) {
return
}
val action = intent.action
if (LocalBroadcastManager.REFRESH == action || LocalBroadcastManager.REFRESH_LIST == action) {
disposables?.add(updateFilters())
}
}
}
companion object {
const val FRAGMENT_NAVIGATION_DRAWER = R.id.navigation_drawer
const val REQUEST_NEW_LIST = 10100
const val REQUEST_SETTINGS = 10101
const val REQUEST_PURCHASE = 10102
const val REQUEST_DONATE = 10103
const val REQUEST_NEW_PLACE = 10104
const val REQUEST_NEW_FILTER = 101015
private const val FRAG_TAG_NEW_FILTER = "frag_tag_new_filter"
}
}
Loading…
Cancel
Save