Feature #1756 : Bookmark System (#1935)

* Add bookmark star images

* Add bookmark item in navigation menu

* Add Activity for bookmarks

* Implement bookmarks viewpager

* Bookmark object and bookmarkDao

* Implement Bookmark Picture Fragment and Controller

* Implement image detail bookmark menu action UI

* contentProvider + config + dao rework

* Fix Dao and Content Provider crashes

* Link bookmark controllers and dao

* Implement bookmark location fragment, controller

* Add bookmark icon to location items

* Add empty bookmark list behavior and refactoring

* bookmarkLocation dao and contentProvider

* Fix bookmarks location crashes

* Rename and refactor classes

* Implement location list refresh

* Fix picture list update
When user come back from detail picture fragment, it solve the refresh bug.

* full test coverage

* Refactor bookmarks classes

* Fix bookmarks pictures loading

* Fix bookmark locations list display

* Java Documetation

* Fix Code review quality

* Fix DB version update

* Remove forgotten todo

* Update bookmark activity base class
Change from AuthenticatedActivity to BaseNavigationActivity
This commit is contained in:
Victor-Bonin 2018-10-25 17:54:22 +02:00 committed by Josephine Lim
parent 89d2d0cfe0
commit 80a9c94653
42 changed files with 2361 additions and 12 deletions

View file

@ -12,7 +12,7 @@ import java.util.List;
import fr.free.nrw.commons.contributions.ContributionController;
class NearbyAdapterFactory {
public class NearbyAdapterFactory {
private Fragment fragment;
private ContributionController controller;
@ -21,14 +21,21 @@ class NearbyAdapterFactory {
}
NearbyAdapterFactory(Fragment fragment, ContributionController controller) {
public NearbyAdapterFactory(Fragment fragment, ContributionController controller) {
this.fragment = fragment;
this.controller = controller;
}
public RVRendererAdapter<Place> create(List<Place> placeList) {
return create(placeList, null);
}
public RVRendererAdapter<Place> create(
List<Place> placeList,
PlaceRenderer.OnBookmarkClick onBookmarkClick
) {
RendererBuilder<Place> builder = new RendererBuilder<Place>()
.bind(Place.class, new PlaceRenderer(fragment, controller));
.bind(Place.class, new PlaceRenderer(fragment, controller, onBookmarkClick));
ListAdapteeCollection<Place> collection = new ListAdapteeCollection<>(
placeList != null ? placeList : Collections.emptyList());
return new RVRendererAdapter<>(builder, collection);

View file

@ -58,6 +58,7 @@ import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.auth.LoginActivity;
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
import fr.free.nrw.commons.contributions.ContributionController;
import fr.free.nrw.commons.utils.UriDeserializer;
import fr.free.nrw.commons.utils.ViewUtil;
@ -86,6 +87,7 @@ public class NearbyMapFragment extends DaggerFragment {
private LinearLayout wikidataButton;
private LinearLayout directionsButton;
private LinearLayout commonsButton;
private LinearLayout bookmarkButton;
private FloatingActionButton fabPlus;
private FloatingActionButton fabCamera;
private FloatingActionButton fabGallery;
@ -95,6 +97,7 @@ public class NearbyMapFragment extends DaggerFragment {
private TextView title;
private TextView distance;
private ImageView icon;
private ImageView bookmarkButtonImage;
private TextView wikipediaButtonText;
private TextView wikidataButtonText;
@ -131,6 +134,8 @@ public class NearbyMapFragment extends DaggerFragment {
@Inject
@Named("direct_nearby_upload_prefs")
SharedPreferences directPrefs;
@Inject
BookmarkLocationsDao bookmarkLocationDao;
public NearbyMapFragment() {
}
@ -374,6 +379,9 @@ public class NearbyMapFragment extends DaggerFragment {
directionsButtonText = getActivity().findViewById(R.id.directionsButtonText);
commonsButtonText = getActivity().findViewById(R.id.commonsButtonText);
bookmarkButton = getActivity().findViewById(R.id.bookmarkButton);
bookmarkButtonImage = getActivity().findViewById(R.id.bookmarkButtonImage);
}
private void setListeners() {
@ -721,6 +729,20 @@ public class NearbyMapFragment extends DaggerFragment {
private void passInfoToSheet(Place place) {
this.place = place;
int bookmarkIcon;
if (bookmarkLocationDao.findBookmarkLocation(place)) {
bookmarkIcon = R.drawable.ic_round_star_filled_24px;
} else {
bookmarkIcon = R.drawable.ic_round_star_border_24px;
}
bookmarkButtonImage.setImageResource(bookmarkIcon);
bookmarkButton.setOnClickListener(view -> {
boolean isBookmarked = bookmarkLocationDao.updateBookmarkLocation(place);
int updatedIcon = isBookmarked ? R.drawable.ic_round_star_filled_24px : R.drawable.ic_round_star_border_24px;
bookmarkButtonImage.setImageResource(updatedIcon);
});
wikipediaButton.setEnabled(place.hasWikipediaLink());
wikipediaButton.setOnClickListener(view -> openWebView(place.siteLinks.getWikipediaLink()));

View file

@ -52,6 +52,8 @@ public class Place {
this.distance = distance;
}
public Uri getSecondaryImageUrl() { return this.secondaryImageUrl; }
/**
* Extracts the entity id from the wikidata link
* @return returns the entity id if wikidata link exists

View file

@ -27,6 +27,7 @@ import butterknife.ButterKnife;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.auth.LoginActivity;
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
import fr.free.nrw.commons.contributions.ContributionController;
import fr.free.nrw.commons.di.ApplicationlessInjection;
import timber.log.Timber;
@ -50,6 +51,9 @@ public class PlaceRenderer extends Renderer<Place> {
@BindView(R.id.iconOverflow) LinearLayout iconOverflow;
@BindView(R.id.cameraButtonText) TextView cameraButtonText;
@BindView(R.id.galleryButtonText) TextView galleryButtonText;
@BindView(R.id.bookmarkButton) LinearLayout bookmarkButton;
@BindView(R.id.bookmarkButtonText) TextView bookmarkButtonText;
@BindView(R.id.bookmarkButtonImage) ImageView bookmarkButtonImage;
@BindView(R.id.directionsButtonText) TextView directionsButtonText;
@BindView(R.id.iconOverflowText) TextView iconOverflowText;
@ -60,8 +64,10 @@ public class PlaceRenderer extends Renderer<Place> {
private Fragment fragment;
private ContributionController controller;
private OnBookmarkClick onBookmarkClick;
@Inject
BookmarkLocationsDao bookmarkLocationDao;
@Inject @Named("prefs") SharedPreferences prefs;
@Inject @Named("direct_nearby_upload_prefs") SharedPreferences directPrefs;
@ -69,10 +75,15 @@ public class PlaceRenderer extends Renderer<Place> {
openedItems = new ArrayList<>();
}
public PlaceRenderer(Fragment fragment, ContributionController controller) {
public PlaceRenderer(
Fragment fragment,
ContributionController controller,
OnBookmarkClick onBookmarkClick
) {
this.fragment = fragment;
this.controller = controller;
openedItems = new ArrayList<>();
this.onBookmarkClick = onBookmarkClick;
}
@Override
@ -84,6 +95,7 @@ public class PlaceRenderer extends Renderer<Place> {
@Override
protected void setUpView(View view) {
ButterKnife.bind(this, view);
closeLayout(buttonLayout);
}
@Override
@ -151,6 +163,27 @@ public class PlaceRenderer extends Renderer<Place> {
}
});
bookmarkButton.setOnClickListener(view4 -> {
if (applicationPrefs.getBoolean("login_skipped", false)) {
// prompt the user to login
new AlertDialog.Builder(getContext())
.setMessage(R.string.login_alert_message)
.setPositiveButton(R.string.login, (dialog, which) -> {
startActivityWithFlags( getContext(), LoginActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP,
Intent.FLAG_ACTIVITY_SINGLE_TOP);
prefs.edit().putBoolean("login_skipped", false).apply();
fragment.getActivity().finish();
})
.show();
} else {
boolean isBookmarked = bookmarkLocationDao.updateBookmarkLocation(place);
int icon = isBookmarked ? R.drawable.ic_round_star_filled_24px : R.drawable.ic_round_star_border_24px;
bookmarkButtonImage.setImageResource(icon);
if (onBookmarkClick != null) {
onBookmarkClick.onClick();
}
}
});
}
private void storeSharedPrefs() {
@ -197,6 +230,13 @@ public class PlaceRenderer extends Renderer<Place> {
iconOverflow.setVisibility(showMenu() ? View.VISIBLE : View.GONE);
iconOverflow.setOnClickListener(v -> popupMenuListener());
int icon;
if (bookmarkLocationDao.findBookmarkLocation(place)) {
icon = R.drawable.ic_round_star_filled_24px;
} else {
icon = R.drawable.ic_round_star_border_24px;
}
bookmarkButtonImage.setImageResource(icon);
}
private void popupMenuListener() {
@ -241,4 +281,8 @@ public class PlaceRenderer extends Renderer<Place> {
return place.hasCommonsLink() || place.hasWikidataLink();
}
public interface OnBookmarkClick {
void onClick();
}
}