[bookmarks][android] Sections editing.

This commit is contained in:
Daria Volvenkova 2019-08-22 00:46:56 +03:00 committed by Aleksey Belousov
parent 94e1aff644
commit 04d3618614
6 changed files with 153 additions and 116 deletions

View file

@ -441,8 +441,10 @@ void OnBookmarksSearchResults(search::BookmarksSearchParams::Results const & res
JNIEnv * env = jni::GetEnv();
jni::ScopedLocalRef<jlongArray> jResults(env, env->NewLongArray(results.size()));
vector<jlong> const tmp(results.cbegin(), results.cend());
auto filteredResults = results;
g_framework->NativeFramework()->GetBookmarkManager().FilterInvalidBookmarks(filteredResults);
jni::ScopedLocalRef<jlongArray> jResults(env, env->NewLongArray(filteredResults.size()));
vector<jlong> const tmp(filteredResults.cbegin(), filteredResults.cend());
env->SetLongArrayRegion(jResults.get(), 0, tmp.size(), tmp.data());
auto const method = (status == search::BookmarksSearchParams::Status::InProgress) ?

View file

@ -10,6 +10,11 @@ namespace
Bookmark const * getBookmark(jlong bokmarkId)
{
Bookmark const * pBmk = frm()->GetBookmarkManager().GetBookmark(static_cast<kml::MarkId>(bokmarkId));
if (!pBmk)
{
int i = 0;
++i;
}
ASSERT(pBmk, ("Bookmark not found, id", bokmarkId));
return pBmk;
}

View file

@ -17,6 +17,8 @@ import com.mapswithme.maps.content.DataSource;
import com.mapswithme.maps.widget.recycler.RecyclerClickListener;
import com.mapswithme.maps.widget.recycler.RecyclerLongClickListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookmarkHolder>
@ -76,9 +78,12 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
mDataSource = dataSource;
}
public BookmarkCategory getCategory()
public BookmarkCategory getCategory() { return mDataSource.getData(); }
protected boolean hasDescription()
{
return mDataSource.getData();
return !mDataSource.getData().getAnnotation().isEmpty() ||
!mDataSource.getData().getDescription().isEmpty();
}
public abstract int getSectionsCount();
@ -112,10 +117,8 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
mTracksSectionIndex = SectionPosition.INVALID_POSITION;
mSectionsCount = 0;
if (!getCategory().getAnnotation().isEmpty() || !getCategory().getDescription().isEmpty())
{
if (hasDescription())
mDescriptionSectionIndex = mSectionsCount++;
}
if (getCategory().getTracksCount() > 0)
mTracksSectionIndex = mSectionsCount++;
if (getCategory().getBookmarksCount() > 0)
@ -123,10 +126,7 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
}
@Override
public int getSectionsCount()
{
return mSectionsCount;
}
public int getSectionsCount() { return mSectionsCount; }
@Override
public boolean isEditable(int sectionIndex)
@ -135,10 +135,7 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
}
@Override
public boolean hasTitle(int sectionIndex)
{
return true;
}
public boolean hasTitle(int sectionIndex) { return true; }
@Nullable
public String getTitle(int sectionIndex, Resources rs)
@ -210,57 +207,33 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
}
@Override
public int getSectionsCount()
{
return 1;
}
public int getSectionsCount() { return 1; }
@Override
public boolean isEditable(int sectionIndex)
{
return true;
}
public boolean isEditable(int sectionIndex) { return true; }
@Override
public boolean hasTitle(int sectionIndex)
{
return false;
}
public boolean hasTitle(int sectionIndex) { return false; }
@Nullable
public String getTitle(int sectionIndex, Resources rs)
{
return null;
}
public String getTitle(int sectionIndex, Resources rs) { return null; }
@Override
public int getItemsCount(int sectionIndex)
{
return mSearchResults.size();
}
public int getItemsCount(int sectionIndex) { return mSearchResults.size(); }
@Override
public int getItemsType(int sectionIndex)
{
return TYPE_BOOKMARK;
}
public int getItemsType(int sectionIndex) { return TYPE_BOOKMARK; }
@Override
public void onDelete(SectionPosition pos)
{
mSearchResults.remove(pos.itemIndex);
}
public void onDelete(SectionPosition pos) { mSearchResults.remove(pos.itemIndex); }
@Override
public long getBookmarkId(SectionPosition pos)
{
return mSearchResults.get(pos.itemIndex);
}
public long getBookmarkId(SectionPosition pos) { return mSearchResults.get(pos.itemIndex); }
@Override
public long getTrackId(SectionPosition pos)
{
return 0;
throw new AssertionError("Tracks unsupported in search results.");
}
}
@ -276,34 +249,51 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
mSortedBlocks = sortedBlocks;
}
private boolean isDescriptionSection(int sectionIndex)
{
return hasDescription() && sectionIndex == 0;
}
@NonNull
private SortedBlock getSortedBlock(int sectionIndex)
{
if (isDescriptionSection(sectionIndex))
throw new IllegalArgumentException("Invalid section index for sorted block.");
int blockIndex = sectionIndex - (hasDescription() ? 1 : 0);
return mSortedBlocks.get(blockIndex);
}
@Override
public int getSectionsCount()
{
return mSortedBlocks.size();
return mSortedBlocks.size() + (hasDescription() ? 1 : 0);
}
@Override
public boolean isEditable(int sectionIndex)
{
if (isDescriptionSection(sectionIndex))
return false;
return true;
}
@Override
public boolean hasTitle(int sectionIndex)
{
return true;
}
public boolean hasTitle(int sectionIndex) { return true; }
@Nullable
public String getTitle(int sectionIndex, Resources rs)
{
return mSortedBlocks.get(sectionIndex).getName();
if (isDescriptionSection(sectionIndex))
return rs.getString(R.string.description);
return getSortedBlock(sectionIndex).getName();
}
@Override
public int getItemsCount(int sectionIndex)
{
SortedBlock block = mSortedBlocks.get(sectionIndex);
if (isDescriptionSection(sectionIndex))
return 1;
SortedBlock block = getSortedBlock(sectionIndex);
if (block.isBookmarksBlock())
return block.getBookmarkIds().size();
return block.getTrackIds().size();
@ -312,8 +302,9 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
@Override
public int getItemsType(int sectionIndex)
{
SortedBlock block = mSortedBlocks.get(sectionIndex);
if (block.isBookmarksBlock())
if (isDescriptionSection(sectionIndex))
return TYPE_DESC;
if (getSortedBlock(sectionIndex).isBookmarksBlock())
return TYPE_BOOKMARK;
return TYPE_TRACK;
}
@ -321,28 +312,32 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
@Override
public void onDelete(SectionPosition pos)
{
SortedBlock block = mSortedBlocks.get(pos.sectionIndex);
if (isDescriptionSection(pos.sectionIndex))
throw new IllegalArgumentException("Delete failed. Invalid section index.");
int blockIndex = pos.sectionIndex - (hasDescription() ? 1 : 0);
SortedBlock block = mSortedBlocks.get(blockIndex);
if (block.isBookmarksBlock())
{
block.getBookmarkIds().remove(pos.itemIndex);
if (block.getBookmarkIds().isEmpty())
mSortedBlocks.remove(pos.sectionIndex);
mSortedBlocks.remove(blockIndex);
return;
}
block.getTrackIds().remove(pos.itemIndex);
if (block.getTrackIds().isEmpty())
mSortedBlocks.remove(pos.sectionIndex);
mSortedBlocks.remove(blockIndex);
}
public long getBookmarkId(SectionPosition pos)
{
return mSortedBlocks.get(pos.sectionIndex).getBookmarkIds().get(pos.itemIndex);
return getSortedBlock(pos.sectionIndex).getBookmarkIds().get(pos.itemIndex);
}
public long getTrackId(SectionPosition pos)
{
return mSortedBlocks.get(pos.sectionIndex).getTrackIds().get(pos.itemIndex);
return getSortedBlock(pos.sectionIndex).getTrackIds().get(pos.itemIndex);
}
}
@ -380,15 +375,27 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
return new SectionPosition(SectionPosition.INVALID_POSITION, SectionPosition.INVALID_POSITION);
}
public void setSearchResults(@Nullable List<Long> searchResults)
public void setSearchResults(@Nullable long[] searchResults)
{
mSearchResults = searchResults;
if (searchResults != null)
{
mSearchResults = new ArrayList<Long>(searchResults.length);
for (long id : searchResults)
mSearchResults.add(id);
}
else
{
mSearchResults = null;
}
refreshSections();
}
public void setSortedResults(@Nullable List<SortedBlock> sortedResults)
public void setSortedResults(@Nullable SortedBlock[] sortedResults)
{
mSortedResults = sortedResults;
if (sortedResults != null)
mSortedResults = new ArrayList<>(Arrays.asList(sortedResults));
else
mSortedResults = null;
refreshSections();
}
@ -473,6 +480,14 @@ public class BookmarkListAdapter extends RecyclerView.Adapter<Holders.BaseBookma
return itemCount;
}
public void onDelete(int position)
{
SectionPosition sp = getSectionPosition(position);
mSectionsDataSource.onDelete(sp);
if (mSearchResults != null)
mSortedResults = null;
}
// FIXME: remove this heavy method and use BoomarkInfo class instead.
public Object getItem(int position)
{

View file

@ -63,19 +63,16 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<BookmarkListA
public static final String EXTRA_CATEGORY = "bookmark_category";
private BookmarksToolbarController mToolbarController;
private long mLastQueryTimestamp;
private long mLastSortTimestamp;
private long mLastQueryTimestamp = 0;
private long mLastSortTimestamp = 0;
@SuppressWarnings("NullableProblems")
@NonNull
private CategoryDataSource mCategoryDataSource;
private int mSelectedPosition;
private List<Long> mSearchResults;
private List<SortedBlock> mSortResults;
private boolean mSearchMode = false;
private boolean mSortMode = false;
private boolean mNeedUpdateSorting = true;
@SuppressWarnings("NullableProblems")
@NonNull
@ -162,8 +159,8 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<BookmarkListA
super.onResume();
Crashlytics.log("onResume");
BookmarkListAdapter adapter = getAdapter();
adapter.notifyDataSetChanged();
updateSorting();
}
@Override
@ -301,7 +298,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<BookmarkListA
@Override
public void onBookmarkSearchResultsUpdate(@Nullable long[] bookmarkIds, long timestamp)
{
if (!isAdded() || !mToolbarController.hasQuery())
if (!isAdded() || !mToolbarController.hasQuery() || mLastQueryTimestamp != timestamp)
return;
updateSearchResults(bookmarkIds);
}
@ -309,22 +306,17 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<BookmarkListA
@Override
public void onBookmarkSearchResultsEnd(@Nullable long[] bookmarkIds, long timestamp)
{
if (!isAdded() || !mToolbarController.hasQuery())
if (!isAdded() || !mToolbarController.hasQuery() || mLastQueryTimestamp != timestamp)
return;
mLastQueryTimestamp = 0;
mToolbarController.showProgress(false);
updateSearchResults(bookmarkIds);
}
private void updateSearchResults(@Nullable long[] bookmarkIds)
{
ArrayList<Long> ids = new ArrayList<Long>(bookmarkIds.length);
for (long id : bookmarkIds)
ids.add(id);
mSearchResults = ids;
BookmarkListAdapter adapter = getAdapter();
adapter.setSearchResults(mSearchResults);
adapter.setSearchResults(bookmarkIds);
adapter.notifyDataSetChanged();
}
@ -332,23 +324,23 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<BookmarkListA
{
SearchEngine.INSTANCE.cancel();
mToolbarController.showProgress(false);
mSearchResults = null;
BookmarkListAdapter adapter = getAdapter();
adapter.setSearchResults(mSearchResults);
adapter.setSearchResults(null);
adapter.notifyDataSetChanged();
updateSorting();
}
public void activateSearch()
{
mSearchMode = true;
BookmarkManager.INSTANCE.setNotificationsEnabled(true);
updateControlsStatus();
}
public void deactivateSearch()
{
mSearchMode = false;
BookmarkManager.INSTANCE.setNotificationsEnabled(false);
updateControlsStatus();
}
@ -362,11 +354,10 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<BookmarkListA
{
if (mLastSortTimestamp != timestamp)
return;
mSortResults = Arrays.asList(sortedBlocks);
mLastSortTimestamp = 0;
BookmarkListAdapter adapter = getAdapter();
adapter.setSortedResults(mSortResults);
adapter.setSortedResults(sortedBlocks);
adapter.notifyDataSetChanged();
}
@ -375,18 +366,21 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<BookmarkListA
{
if (mLastSortTimestamp != timestamp)
return;
mSortResults = null;
mLastSortTimestamp = 0;
BookmarkListAdapter adapter = getAdapter();
adapter.setSortedResults(mSortResults);
adapter.setSortedResults(null);
adapter.notifyDataSetChanged();
}
@Override
public void onPreparedFileForSharing(@NonNull BookmarkSharingResult result)
public void onSort(@BookmarkManager.SortingType int sortingType)
{
SharingHelper.INSTANCE.onPreparedFileForSharing(getActivity(), result);
mLastSortTimestamp = System.nanoTime();
long catId = getCategoryOrThrow().getId();
BookmarkManager.INSTANCE.setLastSortingType(catId, sortingType);
BookmarkManager.INSTANCE.getSortedBookmarks(catId, sortingType,
false, 0, 0, mLastSortTimestamp);
}
public void onResetSorting()
@ -400,13 +394,38 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<BookmarkListA
adapter.notifyDataSetChanged();
}
public void onSort(@BookmarkManager.SortingType int sortingType)
public void updateSorting()
{
mLastSortTimestamp = System.nanoTime();
if (!mNeedUpdateSorting)
return;
mNeedUpdateSorting = false;
// Do nothing in case of sorting has already started and we are waiting for results.
if (mLastSortTimestamp != 0)
return;
long catId = getCategoryOrThrow().getId();
BookmarkManager.INSTANCE.setLastSortingType(catId, sortingType);
BookmarkManager.INSTANCE.getSortedBookmarks(catId, sortingType,
false, 0, 0, mLastSortTimestamp);
if (!BookmarkManager.INSTANCE.hasLastSortingType(catId))
return;
@BookmarkManager.SortingType int currentType =
BookmarkManager.INSTANCE.getLastSortingType(catId);
@BookmarkManager.SortingType int[] types =
BookmarkManager.INSTANCE.getAvailableSortingTypes(catId, false);
for (int i = 0; i < types.length; ++i)
{
if (types[i] == currentType)
{
onSort(currentType);
break;
}
}
}
@Override
public void onPreparedFileForSharing(@NonNull BookmarkSharingResult result)
{
SharingHelper.INSTANCE.onPreparedFileForSharing(getActivity(), result);
}
@Override
@ -457,8 +476,11 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment<BookmarkListA
break;
case R.id.delete:
adapter.onDelete(mSelectedPosition);
BookmarkManager.INSTANCE.deleteBookmark(item.getBookmarkId());
adapter.notifyDataSetChanged();
if (mSearchMode)
mNeedUpdateSorting = true;
break;
}
return false;

View file

@ -3,6 +3,7 @@ package com.mapswithme.maps.bookmarks.data;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -19,8 +20,8 @@ public class SortedBlock
@NonNull Long[] trackIds)
{
mName = name;
mBookmarkIds = Arrays.asList(bookmarkIds);
mTrackIds = Arrays.asList(trackIds);
mBookmarkIds = new ArrayList<>(Arrays.asList(bookmarkIds));
mTrackIds = new ArrayList<>(Arrays.asList(trackIds));
}
public boolean isBookmarksBlock() { return !mBookmarkIds.isEmpty(); }

View file

@ -65,24 +65,16 @@ public enum SearchEngine implements NativeSearchListener,
public void onBookmarkSearchResultsUpdate(@Nullable long[] bookmarkIds, long timestamp)
{
UiThread.run(
() ->
{
for (NativeBookmarkSearchListener listener : mBookmarkListeners)
listener.onBookmarkSearchResultsUpdate(bookmarkIds, timestamp);
mBookmarkListeners.finishIterate();
});
for (NativeBookmarkSearchListener listener : mBookmarkListeners)
listener.onBookmarkSearchResultsUpdate(bookmarkIds, timestamp);
mBookmarkListeners.finishIterate();
}
public void onBookmarkSearchResultsEnd(@Nullable long[] bookmarkIds, long timestamp)
{
UiThread.run(
() ->
{
for (NativeBookmarkSearchListener listener : mBookmarkListeners)
listener.onBookmarkSearchResultsEnd(bookmarkIds, timestamp);
mBookmarkListeners.finishIterate();
});
for (NativeBookmarkSearchListener listener : mBookmarkListeners)
listener.onBookmarkSearchResultsEnd(bookmarkIds, timestamp);
mBookmarkListeners.finishIterate();
}
@Override