mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
* #3468 Switch from RvRenderer to AdapterDelegates - replace SearchDepictionsRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace UploadCategoryDepictionsRenderer * #3468 Switch from RvRenderer to AdapterDelegates - update BaseAdapter to be easier to use * #3468 Switch from RvRenderer to AdapterDelegates - replace SearchImagesRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace SearchCategoriesRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace NotificationRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace UploadDepictsRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace PlaceRenderer * #3468 fix constant import * #3468 Switch from RvRenderer to AdapterDelegates - resolve id conflict
This commit is contained in:
parent
82d662c8ef
commit
b063d6bdfd
61 changed files with 851 additions and 1609 deletions
|
|
@ -11,7 +11,7 @@ apply from: 'quality.gradle'
|
||||||
|
|
||||||
def isRunningOnTravisAndIsNotPRBuild = System.getenv("CI") == "true" && file('../play.p12').exists()
|
def isRunningOnTravisAndIsNotPRBuild = System.getenv("CI") == "true" && file('../play.p12').exists()
|
||||||
|
|
||||||
if(isRunningOnTravisAndIsNotPRBuild) {
|
if (isRunningOnTravisAndIsNotPRBuild) {
|
||||||
apply plugin: 'com.github.triplet.play'
|
apply plugin: 'com.github.triplet.play'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,7 +35,6 @@ dependencies {
|
||||||
// UI
|
// UI
|
||||||
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
|
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
|
||||||
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
|
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
|
||||||
implementation 'com.github.pedrovgs:renderers:3.3.3'
|
|
||||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:8.6.2'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:8.6.2'
|
||||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v8:0.11.0'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v8:0.11.0'
|
||||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.4.0'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.4.0'
|
||||||
|
|
@ -43,8 +42,9 @@ dependencies {
|
||||||
implementation 'com.dinuscxj:circleprogressbar:1.1.1'
|
implementation 'com.dinuscxj:circleprogressbar:1.1.1'
|
||||||
implementation 'com.karumi:dexter:5.0.0'
|
implementation 'com.karumi:dexter:5.0.0'
|
||||||
implementation "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION"
|
implementation "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION"
|
||||||
|
|
||||||
kapt "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION"
|
kapt "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION"
|
||||||
|
implementation "com.hannesdorfmann:adapterdelegates4-kotlin-dsl-layoutcontainer:$ADAPTER_DELEGATES_VERSION"
|
||||||
|
implementation "com.hannesdorfmann:adapterdelegates4-pagination:$ADAPTER_DELEGATES_VERSION"
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
implementation 'ch.acra:acra-dialog:5.3.0'
|
implementation 'ch.acra:acra-dialog:5.3.0'
|
||||||
|
|
@ -104,6 +104,7 @@ dependencies {
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||||
implementation "androidx.exifinterface:exifinterface:1.0.0"
|
implementation "androidx.exifinterface:exifinterface:1.0.0"
|
||||||
implementation "androidx.core:core-ktx:$CORE_KTX_VERSION"
|
implementation "androidx.core:core-ktx:$CORE_KTX_VERSION"
|
||||||
|
implementation "androidx.multidex:multidex:2.0.1"
|
||||||
|
|
||||||
//swipe_layout
|
//swipe_layout
|
||||||
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
|
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
|
||||||
|
|
@ -112,7 +113,8 @@ dependencies {
|
||||||
implementation "androidx.room:room-runtime:$ROOM_VERSION"
|
implementation "androidx.room:room-runtime:$ROOM_VERSION"
|
||||||
implementation "androidx.room:room-ktx:$ROOM_VERSION"
|
implementation "androidx.room:room-ktx:$ROOM_VERSION"
|
||||||
implementation "androidx.room:room-rxjava2:$ROOM_VERSION"
|
implementation "androidx.room:room-rxjava2:$ROOM_VERSION"
|
||||||
kapt "androidx.room:room-compiler:$ROOM_VERSION" // For Kotlin use kapt instead of annotationProcessor
|
kapt "androidx.room:room-compiler:$ROOM_VERSION"
|
||||||
|
// For Kotlin use kapt instead of annotationProcessor
|
||||||
implementation 'com.squareup.retrofit2:retrofit:2.8.1'
|
implementation 'com.squareup.retrofit2:retrofit:2.8.1'
|
||||||
testImplementation "androidx.arch.core:core-testing:2.1.0"
|
testImplementation "androidx.arch.core:core-testing:2.1.0"
|
||||||
|
|
||||||
|
|
@ -145,7 +147,7 @@ android {
|
||||||
testOptions {
|
testOptions {
|
||||||
execution 'ANDROIDX_TEST_ORCHESTRATOR'
|
execution 'ANDROIDX_TEST_ORCHESTRATOR'
|
||||||
}
|
}
|
||||||
|
multiDexEnabled true
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,7 +174,7 @@ android {
|
||||||
test.resources.srcDirs += 'src/main/resoures'
|
test.resources.srcDirs += 'src/main/resoures'
|
||||||
}
|
}
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
release
|
release
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,7 +183,7 @@ android {
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||||
testProguardFile 'test-proguard-rules.txt'
|
testProguardFile 'test-proguard-rules.txt'
|
||||||
if(isRunningOnTravisAndIsNotPRBuild) {
|
if (isRunningOnTravisAndIsNotPRBuild) {
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +212,7 @@ android {
|
||||||
productFlavors {
|
productFlavors {
|
||||||
prod {
|
prod {
|
||||||
|
|
||||||
applicationId 'fr.free.nrw.commons'
|
applicationId 'fr.free.nrw.commons'
|
||||||
|
|
||||||
buildConfigField "String", "WIKIMEDIA_API_POTD", "\"https://commons.wikimedia.org/w/api.php?action=featuredfeed&feed=potd&feedformat=rss&language=en\""
|
buildConfigField "String", "WIKIMEDIA_API_POTD", "\"https://commons.wikimedia.org/w/api.php?action=featuredfeed&feed=potd&feedformat=rss&language=en\""
|
||||||
buildConfigField "String", "WIKIMEDIA_API_HOST", "\"https://commons.wikimedia.org/w/api.php\""
|
buildConfigField "String", "WIKIMEDIA_API_HOST", "\"https://commons.wikimedia.org/w/api.php\""
|
||||||
|
|
@ -291,7 +293,7 @@ android {
|
||||||
buildToolsVersion buildToolsVersion
|
buildToolsVersion buildToolsVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isRunningOnTravisAndIsNotPRBuild) {
|
if (isRunningOnTravisAndIsNotPRBuild) {
|
||||||
play {
|
play {
|
||||||
track = "alpha"
|
track = "alpha"
|
||||||
userFraction = 1
|
userFraction = 1
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import static org.acra.ReportField.STACK_TRACE;
|
||||||
import static org.acra.ReportField.USER_COMMENT;
|
import static org.acra.ReportField.USER_COMMENT;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Application;
|
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
@ -25,7 +24,6 @@ import com.facebook.imagepipeline.core.ImagePipelineConfig;
|
||||||
import com.mapbox.mapboxsdk.Mapbox;
|
import com.mapbox.mapboxsdk.Mapbox;
|
||||||
import com.squareup.leakcanary.LeakCanary;
|
import com.squareup.leakcanary.LeakCanary;
|
||||||
import com.squareup.leakcanary.RefWatcher;
|
import com.squareup.leakcanary.RefWatcher;
|
||||||
|
|
||||||
import fr.free.nrw.commons.auth.SessionManager;
|
import fr.free.nrw.commons.auth.SessionManager;
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
||||||
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao;
|
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao;
|
||||||
|
|
|
||||||
|
|
@ -8,26 +8,21 @@ import android.view.ViewGroup;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import dagger.android.support.DaggerFragment;
|
import dagger.android.support.DaggerFragment;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.contributions.ContributionController;
|
import fr.free.nrw.commons.contributions.ContributionController;
|
||||||
import fr.free.nrw.commons.nearby.NearbyAdapterFactory;
|
|
||||||
import fr.free.nrw.commons.nearby.Place;
|
import fr.free.nrw.commons.nearby.Place;
|
||||||
|
import fr.free.nrw.commons.nearby.fragments.CommonPlaceClickActions;
|
||||||
|
import fr.free.nrw.commons.nearby.fragments.PlaceAdapter;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import kotlin.Unit;
|
||||||
|
|
||||||
public class BookmarkLocationsFragment extends DaggerFragment {
|
public class BookmarkLocationsFragment extends DaggerFragment {
|
||||||
|
|
||||||
|
|
@ -37,8 +32,10 @@ public class BookmarkLocationsFragment extends DaggerFragment {
|
||||||
@BindView(R.id.parentLayout) RelativeLayout parentLayout;
|
@BindView(R.id.parentLayout) RelativeLayout parentLayout;
|
||||||
|
|
||||||
@Inject BookmarkLocationsController controller;
|
@Inject BookmarkLocationsController controller;
|
||||||
private NearbyAdapterFactory adapterFactory;
|
|
||||||
@Inject ContributionController contributionController;
|
@Inject ContributionController contributionController;
|
||||||
|
@Inject BookmarkLocationsDao bookmarkLocationDao;
|
||||||
|
@Inject CommonPlaceClickActions commonPlaceClickActions;
|
||||||
|
private PlaceAdapter adapter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an instance of the fragment with the right bundle parameters
|
* Create an instance of the fragment with the right bundle parameters
|
||||||
|
|
@ -56,7 +53,6 @@ public class BookmarkLocationsFragment extends DaggerFragment {
|
||||||
) {
|
) {
|
||||||
View v = inflater.inflate(R.layout.fragment_bookmarks_locations, container, false);
|
View v = inflater.inflate(R.layout.fragment_bookmarks_locations, container, false);
|
||||||
ButterKnife.bind(this, v);
|
ButterKnife.bind(this, v);
|
||||||
adapterFactory = new NearbyAdapterFactory(this, contributionController);
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,7 +61,15 @@ public class BookmarkLocationsFragment extends DaggerFragment {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
progressBar.setVisibility(View.VISIBLE);
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
recyclerView.setAdapter(adapterFactory.create(new ArrayList<>(), this::initList));
|
adapter = new PlaceAdapter(bookmarkLocationDao,
|
||||||
|
place -> Unit.INSTANCE,
|
||||||
|
(place, isBookmarked) -> {
|
||||||
|
adapter.remove(place);
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
},
|
||||||
|
commonPlaceClickActions
|
||||||
|
);
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -79,7 +83,7 @@ public class BookmarkLocationsFragment extends DaggerFragment {
|
||||||
*/
|
*/
|
||||||
private void initList() {
|
private void initList() {
|
||||||
List<Place> places = controller.loadFavoritesLocations();
|
List<Place> places = controller.loadFavoritesLocations();
|
||||||
adapterFactory.updateAdapterData(places, (RVRendererAdapter<Place>) recyclerView.getAdapter());
|
adapter.setItems(places);
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.GONE);
|
||||||
if (places.size() <= 0) {
|
if (places.size() <= 0) {
|
||||||
statusTextView.setText(R.string.bookmark_empty);
|
statusTextView.setText(R.string.bookmark_empty);
|
||||||
|
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
package fr.free.nrw.commons.category;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.CheckedTextView;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.Renderer;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the Categories view
|
|
||||||
*/
|
|
||||||
public class CategoriesRenderer extends Renderer<CategoryItem> {
|
|
||||||
@BindView(R.id.tvName) CheckedTextView checkedView;
|
|
||||||
private final CategoryClickedListener listener;
|
|
||||||
|
|
||||||
CategoriesRenderer(CategoryClickedListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View inflate(LayoutInflater layoutInflater, ViewGroup viewGroup) {
|
|
||||||
return layoutInflater.inflate(R.layout.layout_categories_item, viewGroup, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUpView(View view) {
|
|
||||||
ButterKnife.bind(this, view);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void hookListeners(View view) {
|
|
||||||
view.setOnClickListener(v -> {
|
|
||||||
CategoryItem item = getContent();
|
|
||||||
item.setSelected(!item.isSelected());
|
|
||||||
checkedView.setChecked(item.isSelected());
|
|
||||||
if (listener != null) {
|
|
||||||
listener.categoryClicked(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render() {
|
|
||||||
CategoryItem item = getContent();
|
|
||||||
Timber.e("Rendering: %s", item);
|
|
||||||
checkedView.setChecked(item.isSelected());
|
|
||||||
checkedView.setText(item.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,6 +5,7 @@ import org.wikipedia.dataclient.mwapi.MwQueryResponse
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
const val CATEGORY_PREFIX = "Category:"
|
||||||
/**
|
/**
|
||||||
* Category Client to handle custom calls to Commons MediaWiki APIs
|
* Category Client to handle custom calls to Commons MediaWiki APIs
|
||||||
*/
|
*/
|
||||||
|
|
@ -72,7 +73,7 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
||||||
return responseObservable
|
return responseObservable
|
||||||
.map { it.query()?.pages() ?: emptyList() }
|
.map { it.query()?.pages() ?: emptyList() }
|
||||||
.map {
|
.map {
|
||||||
it.map { page -> page.title().replace("Category:", "") }
|
it.map { page -> page.title().replace(CATEGORY_PREFIX, "") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package fr.free.nrw.commons.category;
|
||||||
|
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
|
import static fr.free.nrw.commons.category.CategoryClientKt.CATEGORY_PREFIX;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
|
@ -17,17 +18,16 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||||
import fr.free.nrw.commons.explore.categories.SearchCategoriesAdapterFactory;
|
import fr.free.nrw.commons.explore.categories.SearchCategoriesAdapter;
|
||||||
import fr.free.nrw.commons.utils.NetworkUtils;
|
import fr.free.nrw.commons.utils.NetworkUtils;
|
||||||
import fr.free.nrw.commons.utils.ViewUtil;
|
import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import kotlin.Unit;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -46,16 +46,9 @@ public class SubCategoryListFragment extends CommonsDaggerSupportFragment {
|
||||||
private String categoryName = null;
|
private String categoryName = null;
|
||||||
@Inject CategoryClient categoryClient;
|
@Inject CategoryClient categoryClient;
|
||||||
|
|
||||||
private RVRendererAdapter<String> categoriesAdapter;
|
private SearchCategoriesAdapter categoriesAdapter;
|
||||||
private boolean isParentCategory = true;
|
private boolean isParentCategory = true;
|
||||||
|
|
||||||
private final SearchCategoriesAdapterFactory adapterFactory = new SearchCategoriesAdapterFactory(item -> {
|
|
||||||
// Open SubCategory Details page
|
|
||||||
Intent intent = new Intent(getContext(), CategoryDetailsActivity.class);
|
|
||||||
intent.putExtra("categoryName", item);
|
|
||||||
getContext().startActivity(intent);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
|
||||||
|
|
@ -70,8 +63,12 @@ public class SubCategoryListFragment extends CommonsDaggerSupportFragment {
|
||||||
else{
|
else{
|
||||||
categoriesRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
categoriesRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
||||||
}
|
}
|
||||||
ArrayList<String> items = new ArrayList<>();
|
categoriesAdapter = new SearchCategoriesAdapter(item->{
|
||||||
categoriesAdapter = adapterFactory.create(items);
|
Intent intent = new Intent(getContext(), CategoryDetailsActivity.class);
|
||||||
|
intent.putExtra("categoryName", item);
|
||||||
|
getContext().startActivity(intent);
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
categoriesRecyclerView.setAdapter(categoriesAdapter);
|
categoriesRecyclerView.setAdapter(categoriesAdapter);
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
@ -88,12 +85,14 @@ public class SubCategoryListFragment extends CommonsDaggerSupportFragment {
|
||||||
}
|
}
|
||||||
progressBar.setVisibility(View.VISIBLE);
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
if (isParentCategory) {
|
if (isParentCategory) {
|
||||||
compositeDisposable.add(categoryClient.getParentCategoryList("Category:"+categoryName)
|
compositeDisposable.add(categoryClient.getParentCategoryList(
|
||||||
|
CATEGORY_PREFIX +categoryName)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(this::handleSuccess, this::handleError));
|
.subscribe(this::handleSuccess, this::handleError));
|
||||||
} else {
|
} else {
|
||||||
compositeDisposable.add(categoryClient.getSubCategoryList("Category:"+categoryName)
|
compositeDisposable.add(categoryClient.getSubCategoryList(
|
||||||
|
CATEGORY_PREFIX +categoryName)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(this::handleSuccess, this::handleError));
|
.subscribe(this::handleSuccess, this::handleError));
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ public class DepictedImagesPresenter implements DepictedImagesContract.UserActio
|
||||||
* Ex: Q9394
|
* Ex: Q9394
|
||||||
*/
|
*/
|
||||||
private List<Media> queryList = new ArrayList<>();
|
private List<Media> queryList = new ArrayList<>();
|
||||||
|
private String entityId;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public DepictedImagesPresenter(@Named("default_preferences") JsonKvStore depictionKvStore, DepictsClient depictsClient, MediaClient mediaClient, @Named(IO_THREAD) Scheduler ioScheduler,
|
public DepictedImagesPresenter(@Named("default_preferences") JsonKvStore depictionKvStore, DepictsClient depictsClient, MediaClient mediaClient, @Named(IO_THREAD) Scheduler ioScheduler,
|
||||||
|
|
@ -67,6 +68,7 @@ public class DepictedImagesPresenter implements DepictedImagesContract.UserActio
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
@Override
|
@Override
|
||||||
public void initList(String entityId) {
|
public void initList(String entityId) {
|
||||||
|
this.entityId = entityId;
|
||||||
view.setLoadingStatus(true);
|
view.setLoadingStatus(true);
|
||||||
view.progressBarVisible(true);
|
view.progressBarVisible(true);
|
||||||
view.setIsLastPage(false);
|
view.setIsLastPage(false);
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,10 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import dagger.android.support.DaggerFragment;
|
import dagger.android.support.DaggerFragment;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity;
|
import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity;
|
||||||
import fr.free.nrw.commons.explore.depictions.SearchDepictionsAdapterFactory;
|
import fr.free.nrw.commons.explore.depictions.DepictionAdapter;
|
||||||
import fr.free.nrw.commons.explore.depictions.SearchDepictionsRenderer;
|
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
||||||
import fr.free.nrw.commons.utils.NetworkUtils;
|
import fr.free.nrw.commons.utils.NetworkUtils;
|
||||||
import fr.free.nrw.commons.utils.ViewUtil;
|
import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
|
|
@ -30,6 +28,7 @@ import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import kotlin.Unit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment for parent classes and child classes of Depicted items in Explore
|
* Fragment for parent classes and child classes of Depicted items in Explore
|
||||||
|
|
@ -48,7 +47,7 @@ public class SubDepictionListFragment extends DaggerFragment implements SubDepic
|
||||||
* Keeps a record of whether current instance of the fragment if of SubClass or ParentClass
|
* Keeps a record of whether current instance of the fragment if of SubClass or ParentClass
|
||||||
*/
|
*/
|
||||||
private boolean isParentClass = false;
|
private boolean isParentClass = false;
|
||||||
private RVRendererAdapter<DepictedItem> depictionsAdapter;
|
private DepictionAdapter depictionsAdapter;
|
||||||
RecyclerView.LayoutManager layoutManager;
|
RecyclerView.LayoutManager layoutManager;
|
||||||
/**
|
/**
|
||||||
* Stores entityId for the depiction
|
* Stores entityId for the depiction
|
||||||
|
|
@ -61,20 +60,6 @@ public class SubDepictionListFragment extends DaggerFragment implements SubDepic
|
||||||
|
|
||||||
@Inject SubDepictionListPresenter presenter;
|
@Inject SubDepictionListPresenter presenter;
|
||||||
|
|
||||||
private final SearchDepictionsAdapterFactory adapterFactory = new SearchDepictionsAdapterFactory(new SearchDepictionsRenderer.DepictCallback() {
|
|
||||||
@Override
|
|
||||||
public void depictsClicked(DepictedItem item) {
|
|
||||||
// Open SubDepiction Details page
|
|
||||||
getActivity().finish();
|
|
||||||
WikidataItemDetailsActivity.startYourself(getContext(), item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initViews() {
|
private void initViews() {
|
||||||
if (getArguments() != null) {
|
if (getArguments() != null) {
|
||||||
depictsName = getArguments().getString("wikidataItemName");
|
depictsName = getArguments().getString("wikidataItemName");
|
||||||
|
|
@ -115,7 +100,12 @@ public class SubDepictionListFragment extends DaggerFragment implements SubDepic
|
||||||
}
|
}
|
||||||
initViews();
|
initViews();
|
||||||
depictionsRecyclerView.setLayoutManager(layoutManager);
|
depictionsRecyclerView.setLayoutManager(layoutManager);
|
||||||
depictionsAdapter = adapterFactory.create();
|
depictionsAdapter = new DepictionAdapter(depictedItem -> {
|
||||||
|
// Open SubDepiction Details page
|
||||||
|
getActivity().finish();
|
||||||
|
WikidataItemDetailsActivity.startYourself(getContext(), depictedItem);
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
depictionsRecyclerView.setAdapter(depictionsAdapter);
|
depictionsRecyclerView.setAdapter(depictionsAdapter);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
@ -130,14 +120,7 @@ public class SubDepictionListFragment extends DaggerFragment implements SubDepic
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.GONE);
|
||||||
depictionNotFound.setVisibility(GONE);
|
depictionNotFound.setVisibility(GONE);
|
||||||
bottomProgressBar.setVisibility(GONE);
|
bottomProgressBar.setVisibility(GONE);
|
||||||
int itemCount=layoutManager.getItemCount();
|
|
||||||
depictionsAdapter.addAll(mediaList);
|
depictionsAdapter.addAll(mediaList);
|
||||||
depictionsRecyclerView.getRecycledViewPool().clear();
|
|
||||||
if(itemCount!=0) {
|
|
||||||
depictionsAdapter.notifyItemRangeInserted(itemCount, mediaList.size()-1);
|
|
||||||
}else{
|
|
||||||
depictionsAdapter.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ data class Binding(
|
||||||
val itemLabel: SparqInfo,
|
val itemLabel: SparqInfo,
|
||||||
val itemDescription: SparqInfo? = null
|
val itemDescription: SparqInfo? = null
|
||||||
) {
|
) {
|
||||||
val id: String by lazy { item.value.substringAfterLast("/") }
|
val id: String
|
||||||
|
get() = item.value.substringAfterLast("/")
|
||||||
}
|
}
|
||||||
|
|
||||||
data class SparqInfo(val type: String, val value: String)
|
data class SparqInfo(val type: String, val value: String)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package fr.free.nrw.commons.di
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsFragment
|
||||||
|
|
||||||
|
@Module
|
||||||
|
class BookmarkLocationsFragmentModule {
|
||||||
|
@Provides
|
||||||
|
fun BookmarkLocationsFragment.providesActivity(): Activity = activity!!
|
||||||
|
}
|
||||||
|
|
@ -10,11 +10,9 @@ import dagger.android.AndroidInjector;
|
||||||
import dagger.android.support.AndroidSupportInjectionModule;
|
import dagger.android.support.AndroidSupportInjectionModule;
|
||||||
import fr.free.nrw.commons.CommonsApplication;
|
import fr.free.nrw.commons.CommonsApplication;
|
||||||
import fr.free.nrw.commons.auth.LoginActivity;
|
import fr.free.nrw.commons.auth.LoginActivity;
|
||||||
import fr.free.nrw.commons.contributions.ContributionViewHolder;
|
|
||||||
import fr.free.nrw.commons.contributions.ContributionsModule;
|
import fr.free.nrw.commons.contributions.ContributionsModule;
|
||||||
import fr.free.nrw.commons.depictions.DepictionModule;
|
import fr.free.nrw.commons.depictions.DepictionModule;
|
||||||
import fr.free.nrw.commons.explore.SearchModule;
|
import fr.free.nrw.commons.explore.SearchModule;
|
||||||
import fr.free.nrw.commons.nearby.PlaceRenderer;
|
|
||||||
import fr.free.nrw.commons.review.ReviewController;
|
import fr.free.nrw.commons.review.ReviewController;
|
||||||
import fr.free.nrw.commons.settings.SettingsFragment;
|
import fr.free.nrw.commons.settings.SettingsFragment;
|
||||||
import fr.free.nrw.commons.upload.FileProcessor;
|
import fr.free.nrw.commons.upload.FileProcessor;
|
||||||
|
|
@ -49,8 +47,6 @@ public interface CommonsApplicationComponent extends AndroidInjector<Application
|
||||||
@Override
|
@Override
|
||||||
void inject(ApplicationlessInjection instance);
|
void inject(ApplicationlessInjection instance);
|
||||||
|
|
||||||
void inject(PlaceRenderer placeRenderer);
|
|
||||||
|
|
||||||
void inject(FileProcessor fileProcessor);
|
void inject(FileProcessor fileProcessor);
|
||||||
|
|
||||||
void inject(PicOfDayAppWidget picOfDayAppWidget);
|
void inject(PicOfDayAppWidget picOfDayAppWidget);
|
||||||
|
|
|
||||||
|
|
@ -72,13 +72,13 @@ public abstract class FragmentBuilderModule {
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract ContributionsFragment bindContributionsFragment();
|
abstract ContributionsFragment bindContributionsFragment();
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector(modules = NearbyParentFragmentModule.class)
|
||||||
abstract NearbyParentFragment bindNearbyParentFragment();
|
abstract NearbyParentFragment bindNearbyParentFragment();
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract BookmarkPicturesFragment bindBookmarkPictureListFragment();
|
abstract BookmarkPicturesFragment bindBookmarkPictureListFragment();
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector(modules = BookmarkLocationsFragmentModule.class)
|
||||||
abstract BookmarkLocationsFragment bindBookmarkLocationListFragment();
|
abstract BookmarkLocationsFragment bindBookmarkLocationListFragment();
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package fr.free.nrw.commons.di
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import fr.free.nrw.commons.nearby.fragments.NearbyParentFragment
|
||||||
|
|
||||||
|
@Module
|
||||||
|
class NearbyParentFragmentModule{
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun NearbyParentFragment.providesActivity(): Activity = activity!!
|
||||||
|
}
|
||||||
|
|
@ -5,23 +5,16 @@ import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.SearchView;
|
import android.widget.SearchView;
|
||||||
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
import com.google.android.material.tabs.TabLayout;
|
import com.google.android.material.tabs.TabLayout;
|
||||||
import com.jakewharton.rxbinding2.view.RxView;
|
import com.jakewharton.rxbinding2.view.RxView;
|
||||||
import com.jakewharton.rxbinding2.widget.RxSearchView;
|
import com.jakewharton.rxbinding2.widget.RxSearchView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import fr.free.nrw.commons.Media;
|
import fr.free.nrw.commons.Media;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.category.CategoryImagesCallback;
|
import fr.free.nrw.commons.category.CategoryImagesCallback;
|
||||||
|
|
@ -34,6 +27,10 @@ import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
||||||
import fr.free.nrw.commons.utils.FragmentUtils;
|
import fr.free.nrw.commons.utils.FragmentUtils;
|
||||||
import fr.free.nrw.commons.utils.ViewUtil;
|
import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents search screen of this app
|
* Represents search screen of this app
|
||||||
|
|
@ -111,35 +108,35 @@ public class SearchActivity extends NavigationBaseActivity
|
||||||
.takeUntil(RxView.detaches(searchView))
|
.takeUntil(RxView.detaches(searchView))
|
||||||
.debounce(500, TimeUnit.MILLISECONDS)
|
.debounce(500, TimeUnit.MILLISECONDS)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe( query -> {
|
.subscribe(query -> {
|
||||||
this.query = query.toString();
|
this.query = query.toString();
|
||||||
//update image list
|
//update image list
|
||||||
if (!TextUtils.isEmpty(query)) {
|
if (!TextUtils.isEmpty(query)) {
|
||||||
viewPager.setVisibility(View.VISIBLE);
|
viewPager.setVisibility(View.VISIBLE);
|
||||||
tabLayout.setVisibility(View.VISIBLE);
|
tabLayout.setVisibility(View.VISIBLE);
|
||||||
searchHistoryContainer.setVisibility(View.GONE);
|
searchHistoryContainer.setVisibility(View.GONE);
|
||||||
|
|
||||||
if (FragmentUtils.isFragmentUIActive(searchDepictionsFragment)) {
|
if (FragmentUtils.isFragmentUIActive(searchDepictionsFragment)) {
|
||||||
searchDepictionsFragment.updateDepictionList(query.toString());
|
searchDepictionsFragment.updateDepictionList(query.toString());
|
||||||
}
|
|
||||||
|
|
||||||
if (FragmentUtils.isFragmentUIActive(searchImageFragment)) {
|
|
||||||
searchImageFragment.updateImageList(query.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FragmentUtils.isFragmentUIActive(searchCategoryFragment)) {
|
|
||||||
searchCategoryFragment.updateCategoryList(query.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}else {
|
|
||||||
//Open RecentSearchesFragment
|
|
||||||
recentSearchesFragment.updateRecentSearches();
|
|
||||||
viewPager.setVisibility(View.GONE);
|
|
||||||
tabLayout.setVisibility(View.GONE);
|
|
||||||
setSearchHistoryFragment();
|
|
||||||
searchHistoryContainer.setVisibility(View.VISIBLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FragmentUtils.isFragmentUIActive(searchImageFragment)) {
|
||||||
|
searchImageFragment.updateImageList(query.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FragmentUtils.isFragmentUIActive(searchCategoryFragment)) {
|
||||||
|
searchCategoryFragment.updateCategoryList(query.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//Open RecentSearchesFragment
|
||||||
|
recentSearchesFragment.updateRecentSearches();
|
||||||
|
viewPager.setVisibility(View.GONE);
|
||||||
|
tabLayout.setVisibility(View.GONE);
|
||||||
|
setSearchHistoryFragment();
|
||||||
|
searchHistoryContainer.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
}, Timber::e
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package fr.free.nrw.commons.explore.categories
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.upload.categories.BaseDelegateAdapter
|
||||||
|
|
||||||
|
|
||||||
|
class SearchCategoriesAdapter(onCateoryClicked: (String) -> Unit) : BaseDelegateAdapter<String>(
|
||||||
|
searchCategoryDelegate(onCateoryClicked),
|
||||||
|
areItemsTheSame = { oldItem, newItem -> oldItem == newItem }
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package fr.free.nrw.commons.explore.categories
|
||||||
|
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer
|
||||||
|
import fr.free.nrw.commons.R
|
||||||
|
import fr.free.nrw.commons.category.CATEGORY_PREFIX
|
||||||
|
import kotlinx.android.synthetic.main.item_recent_searches.*
|
||||||
|
|
||||||
|
|
||||||
|
fun searchCategoryDelegate(onCategoryClicked: (String) -> Unit) =
|
||||||
|
adapterDelegateLayoutContainer<String, String>(R.layout.item_recent_searches) {
|
||||||
|
containerView.setOnClickListener { onCategoryClicked(item) }
|
||||||
|
bind {
|
||||||
|
textView1.text = item.substringAfter(CATEGORY_PREFIX)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
package fr.free.nrw.commons.explore.categories;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.ListAdapteeCollection;
|
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import com.pedrogomez.renderers.RendererBuilder;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class helps in creating adapter for categoriesRecyclerView in SearchCategoryFragment,
|
|
||||||
* implementing onClicks on categoriesRecyclerView Items
|
|
||||||
**/
|
|
||||||
public class SearchCategoriesAdapterFactory {
|
|
||||||
private final SearchCategoriesRenderer.CategoryClickedListener listener;
|
|
||||||
|
|
||||||
public SearchCategoriesAdapterFactory(SearchCategoriesRenderer.CategoryClickedListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method creates a recyclerViewAdapter for Categories.
|
|
||||||
* @param searchImageItemList List of category name to be displayed
|
|
||||||
* @return categoriesAdapter
|
|
||||||
**/
|
|
||||||
public RVRendererAdapter<String> create(List<String> searchImageItemList) {
|
|
||||||
RendererBuilder<String> builder = new RendererBuilder<String>().bind(String.class, new SearchCategoriesRenderer(listener));
|
|
||||||
ListAdapteeCollection<String> collection = new ListAdapteeCollection<>(
|
|
||||||
searchImageItemList != null ? searchImageItemList : Collections.<String>emptyList());
|
|
||||||
return new RVRendererAdapter<>(builder, collection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
package fr.free.nrw.commons.explore.categories;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.Renderer;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* presentation logic of individual category in search is handled here
|
|
||||||
**/
|
|
||||||
class SearchCategoriesRenderer extends Renderer<String> {
|
|
||||||
@BindView(R.id.textView1) TextView tvCategoryName;
|
|
||||||
|
|
||||||
private final CategoryClickedListener listener;
|
|
||||||
|
|
||||||
SearchCategoriesRenderer(CategoryClickedListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View inflate(LayoutInflater layoutInflater, ViewGroup viewGroup) {
|
|
||||||
return layoutInflater.inflate(R.layout.item_recent_searches, viewGroup, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUpView(View view) {
|
|
||||||
ButterKnife.bind(this, view);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void hookListeners(View view) {
|
|
||||||
view.setOnClickListener(v -> {
|
|
||||||
String item = getContent();
|
|
||||||
if (listener != null) {
|
|
||||||
listener.categoryClicked(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render() {
|
|
||||||
String item = getContent();
|
|
||||||
tvCategoryName.setText(item.replaceFirst("^Category:", ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface CategoryClickedListener {
|
|
||||||
void categoryClicked(String item);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -16,7 +16,6 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.category.CategoryClient;
|
import fr.free.nrw.commons.category.CategoryClient;
|
||||||
import fr.free.nrw.commons.category.CategoryDetailsActivity;
|
import fr.free.nrw.commons.category.CategoryDetailsActivity;
|
||||||
|
|
@ -33,6 +32,7 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
import kotlin.Unit;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,16 +59,9 @@ public class SearchCategoryFragment extends CommonsDaggerSupportFragment {
|
||||||
@Named("default_preferences")
|
@Named("default_preferences")
|
||||||
JsonKvStore basicKvStore;
|
JsonKvStore basicKvStore;
|
||||||
|
|
||||||
private RVRendererAdapter<String> categoriesAdapter;
|
private SearchCategoriesAdapter categoriesAdapter;
|
||||||
private List<String> queryList = new ArrayList<>();
|
private List<String> queryList = new ArrayList<>();
|
||||||
|
|
||||||
private final SearchCategoriesAdapterFactory adapterFactory = new SearchCategoriesAdapterFactory(item -> {
|
|
||||||
// Called on Click of a individual category Item
|
|
||||||
// Open Category Details activity
|
|
||||||
CategoryDetailsActivity.startYourself(getContext(), item);
|
|
||||||
saveQuery(query);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method saves Search Query in the Recent Searches Database.
|
* This method saves Search Query in the Recent Searches Database.
|
||||||
* @param query
|
* @param query
|
||||||
|
|
@ -98,8 +91,11 @@ public class SearchCategoryFragment extends CommonsDaggerSupportFragment {
|
||||||
else{
|
else{
|
||||||
categoriesRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
categoriesRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
||||||
}
|
}
|
||||||
ArrayList<String> items = new ArrayList<>();
|
categoriesAdapter = new SearchCategoriesAdapter(item -> {
|
||||||
categoriesAdapter = adapterFactory.create(items);
|
CategoryDetailsActivity.startYourself(getContext(), item);
|
||||||
|
saveQuery(query);
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
categoriesRecyclerView.setAdapter(categoriesAdapter);
|
categoriesRecyclerView.setAdapter(categoriesAdapter);
|
||||||
categoriesRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
categoriesRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -141,7 +137,9 @@ public class SearchCategoryFragment extends CommonsDaggerSupportFragment {
|
||||||
* Adds 25 more results to existing search results
|
* Adds 25 more results to existing search results
|
||||||
*/
|
*/
|
||||||
public void addCategoriesToList(String query) {
|
public void addCategoriesToList(String query) {
|
||||||
if(isLoadingCategories) return;
|
if(isLoadingCategories) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
isLoadingCategories=true;
|
isLoadingCategories=true;
|
||||||
this.query = query;
|
this.query = query;
|
||||||
bottomProgressBar.setVisibility(View.VISIBLE);
|
bottomProgressBar.setVisibility(View.VISIBLE);
|
||||||
|
|
@ -161,7 +159,6 @@ public class SearchCategoryFragment extends CommonsDaggerSupportFragment {
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.GONE);
|
||||||
bottomProgressBar.setVisibility(GONE);
|
bottomProgressBar.setVisibility(GONE);
|
||||||
categoriesAdapter.addAll(mediaList);
|
categoriesAdapter.addAll(mediaList);
|
||||||
categoriesAdapter.notifyDataSetChanged();
|
|
||||||
isLoadingCategories=false;
|
isLoadingCategories=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,7 +178,6 @@ public class SearchCategoryFragment extends CommonsDaggerSupportFragment {
|
||||||
bottomProgressBar.setVisibility(View.GONE);
|
bottomProgressBar.setVisibility(View.GONE);
|
||||||
progressBar.setVisibility(GONE);
|
progressBar.setVisibility(GONE);
|
||||||
categoriesAdapter.addAll(mediaList);
|
categoriesAdapter.addAll(mediaList);
|
||||||
categoriesAdapter.notifyDataSetChanged();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package fr.free.nrw.commons.explore.depictions
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.upload.categories.BaseDelegateAdapter
|
||||||
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
|
|
||||||
|
|
||||||
|
class DepictionAdapter(clickListener: (DepictedItem) -> Unit) : BaseDelegateAdapter<DepictedItem>(
|
||||||
|
depictionDelegate(clickListener),
|
||||||
|
areItemsTheSame = { oldItem, newItem -> oldItem.id == newItem.id }
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package fr.free.nrw.commons.explore.depictions
|
||||||
|
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer
|
||||||
|
import fr.free.nrw.commons.R
|
||||||
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
|
import kotlinx.android.synthetic.main.item_depictions.*
|
||||||
|
|
||||||
|
|
||||||
|
fun depictionDelegate(onDepictionClicked: (DepictedItem) -> Unit) =
|
||||||
|
adapterDelegateLayoutContainer<DepictedItem, DepictedItem>(R.layout.item_depictions) {
|
||||||
|
containerView.setOnClickListener { onDepictionClicked(item) }
|
||||||
|
bind {
|
||||||
|
depicts_label.text = item.name
|
||||||
|
description.text = item.description
|
||||||
|
if (item.imageUrl?.isNotBlank() == true) {
|
||||||
|
depicts_image.setImageURI(item.imageUrl)
|
||||||
|
} else {
|
||||||
|
depicts_image.setActualImageResource(R.drawable.ic_wikidata_logo_24dp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,6 @@ package fr.free.nrw.commons.explore.depictions
|
||||||
import fr.free.nrw.commons.BuildConfig
|
import fr.free.nrw.commons.BuildConfig
|
||||||
import fr.free.nrw.commons.Media
|
import fr.free.nrw.commons.Media
|
||||||
import fr.free.nrw.commons.depictions.models.DepictionResponse
|
import fr.free.nrw.commons.depictions.models.DepictionResponse
|
||||||
import fr.free.nrw.commons.depictions.subClass.models.Binding
|
|
||||||
import fr.free.nrw.commons.depictions.subClass.models.SparqlResponse
|
import fr.free.nrw.commons.depictions.subClass.models.SparqlResponse
|
||||||
import fr.free.nrw.commons.media.MediaInterface
|
import fr.free.nrw.commons.media.MediaInterface
|
||||||
import fr.free.nrw.commons.upload.depicts.DepictsInterface
|
import fr.free.nrw.commons.upload.depicts.DepictsInterface
|
||||||
|
|
@ -20,8 +19,9 @@ import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
const val LARGE_IMAGE_SIZE="640px"
|
const val LARGE_IMAGE_SIZE = "640px"
|
||||||
const val THUMB_IMAGE_SIZE="70px"
|
const val THUMB_IMAGE_SIZE = "70px"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Depicts Client to handle custom calls to Commons Wikibase APIs
|
* Depicts Client to handle custom calls to Commons Wikibase APIs
|
||||||
*/
|
*/
|
||||||
|
|
@ -79,7 +79,11 @@ class DepictsClient @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toDepictions(sparqlResponse: Observable<SparqlResponse>): Observable<List<DepictedItem>> {
|
fun toDepictions(sparqlResponse: Observable<SparqlResponse>): Observable<List<DepictedItem>> {
|
||||||
return sparqlResponse.map { it.results.bindings.joinToString("|", transform = Binding::id) }
|
return sparqlResponse.map {
|
||||||
|
it.results.bindings.joinToString("|") { binding ->
|
||||||
|
binding.id
|
||||||
|
}
|
||||||
|
}
|
||||||
.flatMap { getEntities(it).toObservable() }
|
.flatMap { getEntities(it).toObservable() }
|
||||||
.map { it.entities().values.map(::DepictedItem) }
|
.map { it.entities().values.map(::DepictedItem) }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
package fr.free.nrw.commons.explore.depictions;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.ListAdapteeCollection;
|
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import com.pedrogomez.renderers.RendererBuilder;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapter factory for Items in Explore
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class SearchDepictionsAdapterFactory {
|
|
||||||
private final SearchDepictionsRenderer.DepictCallback listener;
|
|
||||||
|
|
||||||
public SearchDepictionsAdapterFactory(SearchDepictionsRenderer.DepictCallback listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RVRendererAdapter<DepictedItem> create() {
|
|
||||||
List<DepictedItem> searchImageItemList = new ArrayList<>();
|
|
||||||
RendererBuilder<DepictedItem> builder = new RendererBuilder<DepictedItem>().bind(DepictedItem.class, new SearchDepictionsRenderer(listener));
|
|
||||||
ListAdapteeCollection<DepictedItem> collection = new ListAdapteeCollection<>(
|
|
||||||
searchImageItemList != null ? searchImageItemList : Collections.<DepictedItem>emptyList());
|
|
||||||
return new RVRendererAdapter<>(builder, collection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,6 +2,7 @@ package fr.free.nrw.commons.explore.depictions;
|
||||||
|
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
|
import static fr.free.nrw.commons.explore.depictions.DepictionAdapterDelegatesKt.depictionDelegate;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
|
@ -12,12 +13,13 @@ import android.view.ViewGroup;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.DiffUtil.ItemCallback;
|
||||||
import androidx.recyclerview.widget.GridLayoutManager;
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity;
|
import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity;
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||||
|
|
@ -28,6 +30,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import kotlin.Unit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display depictions in search fragment
|
* Display depictions in search fragment
|
||||||
|
|
@ -42,24 +45,17 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
|
||||||
TextView depictionNotFound;
|
TextView depictionNotFound;
|
||||||
@BindView(R.id.bottomProgressBar)
|
@BindView(R.id.bottomProgressBar)
|
||||||
ProgressBar bottomProgressBar;
|
ProgressBar bottomProgressBar;
|
||||||
RecyclerView.LayoutManager layoutManager;
|
private RecyclerView.LayoutManager layoutManager;
|
||||||
private boolean isLoading = true;
|
private boolean isLoading = true;
|
||||||
private int PAGE_SIZE = 25;
|
private final int PAGE_SIZE = 25;
|
||||||
@Inject
|
@Inject
|
||||||
SearchDepictionsFragmentPresenter presenter;
|
SearchDepictionsFragmentPresenter presenter;
|
||||||
private final SearchDepictionsAdapterFactory adapterFactory = new SearchDepictionsAdapterFactory(new SearchDepictionsRenderer.DepictCallback() {
|
private DepictionAdapter depictionsAdapter;
|
||||||
@Override
|
|
||||||
public void depictsClicked(DepictedItem item) {
|
|
||||||
WikidataItemDetailsActivity.startYourself(getContext(), item);
|
|
||||||
presenter.saveQuery();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
private RVRendererAdapter<DepictedItem> depictionsAdapter;
|
|
||||||
private boolean isLastPage;
|
private boolean isLastPage;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
|
||||||
View rootView = inflater.inflate(R.layout.fragment_browse_image, container, false);
|
final View rootView = inflater.inflate(R.layout.fragment_browse_image, container, false);
|
||||||
ButterKnife.bind(this, rootView);
|
ButterKnife.bind(this, rootView);
|
||||||
if (getActivity().getResources().getConfiguration().orientation
|
if (getActivity().getResources().getConfiguration().orientation
|
||||||
== Configuration.ORIENTATION_PORTRAIT) {
|
== Configuration.ORIENTATION_PORTRAIT) {
|
||||||
|
|
@ -68,20 +64,25 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
|
||||||
layoutManager = new GridLayoutManager(getContext(), 2);
|
layoutManager = new GridLayoutManager(getContext(), 2);
|
||||||
}
|
}
|
||||||
depictionsRecyclerView.setLayoutManager(layoutManager);
|
depictionsRecyclerView.setLayoutManager(layoutManager);
|
||||||
depictionsAdapter = adapterFactory.create();
|
depictionsAdapter = new DepictionAdapter(
|
||||||
|
depictedItem -> {
|
||||||
|
WikidataItemDetailsActivity.startYourself(getContext(), depictedItem);
|
||||||
|
presenter.saveQuery();
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
depictionsRecyclerView.setAdapter(depictionsAdapter);
|
depictionsRecyclerView.setAdapter(depictionsAdapter);
|
||||||
depictionsRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
depictionsRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
|
public void onScrollStateChanged(final RecyclerView recyclerView, final int newState) {
|
||||||
super.onScrollStateChanged(recyclerView, newState);
|
super.onScrollStateChanged(recyclerView, newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
|
||||||
super.onScrolled(recyclerView, dx, dy);
|
super.onScrolled(recyclerView, dx, dy);
|
||||||
|
|
||||||
int visibleItemCount = layoutManager.getChildCount();
|
final int visibleItemCount = layoutManager.getChildCount();
|
||||||
int totalItemCount = layoutManager.getItemCount();
|
final int totalItemCount = layoutManager.getItemCount();
|
||||||
int firstVisibleItemPosition=0;
|
int firstVisibleItemPosition=0;
|
||||||
if(layoutManager instanceof GridLayoutManager){
|
if(layoutManager instanceof GridLayoutManager){
|
||||||
firstVisibleItemPosition=((GridLayoutManager) layoutManager).findFirstVisibleItemPosition();
|
firstVisibleItemPosition=((GridLayoutManager) layoutManager).findFirstVisibleItemPosition();
|
||||||
|
|
@ -108,12 +109,12 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
|
||||||
/**
|
/**
|
||||||
* Fetch PAGE_SIZE number of items
|
* Fetch PAGE_SIZE number of items
|
||||||
*/
|
*/
|
||||||
private void loadMoreItems(boolean reInitialise) {
|
private void loadMoreItems(final boolean reInitialise) {
|
||||||
presenter.updateDepictionList(presenter.getQuery(),PAGE_SIZE, reInitialise);
|
presenter.updateDepictionList(presenter.getQuery(),PAGE_SIZE, reInitialise);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(final Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
presenter.onAttachView(this);
|
presenter.onAttachView(this);
|
||||||
}
|
}
|
||||||
|
|
@ -124,7 +125,7 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
|
||||||
*
|
*
|
||||||
* @param query string searched in the Explore Activity
|
* @param query string searched in the Explore Activity
|
||||||
*/
|
*/
|
||||||
public void updateDepictionList(String query) {
|
public void updateDepictionList(final String query) {
|
||||||
presenter.initializeQuery(query);
|
presenter.initializeQuery(query);
|
||||||
if (!NetworkUtils.isInternetConnectionEstablished(getContext())) {
|
if (!NetworkUtils.isInternetConnectionEstablished(getContext())) {
|
||||||
handleNoInternet();
|
handleNoInternet();
|
||||||
|
|
@ -142,22 +143,10 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
|
||||||
progressBar.setVisibility(GONE);
|
progressBar.setVisibility(GONE);
|
||||||
bottomProgressBar.setVisibility(GONE);
|
bottomProgressBar.setVisibility(GONE);
|
||||||
depictionNotFound.setVisibility(VISIBLE);
|
depictionNotFound.setVisibility(VISIBLE);
|
||||||
String no_depiction = getString(R.string.depictions_not_found);
|
final String no_depiction = getString(R.string.depictions_not_found);
|
||||||
depictionNotFound.setText(String.format(Locale.getDefault(), no_depiction, presenter.getQuery()));
|
depictionNotFound.setText(String.format(Locale.getDefault(), no_depiction, presenter.getQuery()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
depictionsAdapter.clear();
|
|
||||||
depictionsRecyclerView.cancelPendingInputEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the UI updates for no internet scenario
|
* Handles the UI updates for no internet scenario
|
||||||
*/
|
*/
|
||||||
|
|
@ -172,24 +161,18 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
|
||||||
* like hiding empty labels, hiding progressbar and notifying the apdapter that list of items has been fetched from the API
|
* like hiding empty labels, hiding progressbar and notifying the apdapter that list of items has been fetched from the API
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<DepictedItem> mediaList) {
|
public void onSuccess(final List<DepictedItem> mediaList) {
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(GONE);
|
||||||
depictionNotFound.setVisibility(GONE);
|
depictionNotFound.setVisibility(GONE);
|
||||||
bottomProgressBar.setVisibility(GONE);
|
bottomProgressBar.setVisibility(GONE);
|
||||||
int itemCount = layoutManager.getItemCount();
|
|
||||||
depictionsAdapter.addAll(mediaList);
|
depictionsAdapter.addAll(mediaList);
|
||||||
if(itemCount!=0) {
|
|
||||||
depictionsAdapter.notifyItemRangeInserted(itemCount, mediaList.size()-1);
|
|
||||||
}else{
|
|
||||||
depictionsAdapter.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadingDepictions(boolean isLoading) {
|
public void loadingDepictions(final boolean isLoading) {
|
||||||
depictionNotFound.setVisibility(GONE);
|
depictionNotFound.setVisibility(GONE);
|
||||||
bottomProgressBar.setVisibility(View.VISIBLE);
|
bottomProgressBar.setVisibility(VISIBLE);
|
||||||
progressBar.setVisibility(GONE);
|
progressBar.setVisibility(GONE);
|
||||||
this.isLoading = isLoading;
|
this.isLoading = isLoading;
|
||||||
}
|
}
|
||||||
|
|
@ -204,18 +187,13 @@ public class SearchDepictionsFragment extends CommonsDaggerSupportFragment imple
|
||||||
ViewUtil.showShortSnackbar(depictionsRecyclerView, R.string.error_loading_depictions);
|
ViewUtil.showShortSnackbar(depictionsRecyclerView, R.string.error_loading_depictions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public RVRendererAdapter<DepictedItem> getAdapter() {
|
|
||||||
return depictionsAdapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inform the view that there are no more items to be loaded for this search query
|
* Inform the view that there are no more items to be loaded for this search query
|
||||||
* or reset the isLastPage for the current query
|
* or reset the isLastPage for the current query
|
||||||
* @param isLastPage
|
* @param isLastPage
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setIsLastPage(boolean isLastPage) {
|
public void setIsLastPage(final boolean isLastPage) {
|
||||||
this.isLastPage=isLastPage;
|
this.isLastPage=isLastPage;
|
||||||
progressBar.setVisibility(GONE);
|
progressBar.setVisibility(GONE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
package fr.free.nrw.commons.explore.depictions;
|
package fr.free.nrw.commons.explore.depictions;
|
||||||
|
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.BasePresenter;
|
import fr.free.nrw.commons.BasePresenter;
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The contract with with SearchDepictionsFragment and its presenter would talk to each other
|
* The contract with with SearchDepictionsFragment and its presenter would talk to each other
|
||||||
|
|
@ -44,11 +41,6 @@ public interface SearchDepictionsFragmentContract {
|
||||||
*/
|
*/
|
||||||
void showSnackbar();
|
void showSnackbar();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return adapter
|
|
||||||
*/
|
|
||||||
RVRendererAdapter<DepictedItem> getAdapter();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inform the view that there are no more items to be loaded for this search query
|
* Inform the view that there are no more items to be loaded for this search query
|
||||||
* or reset the isLastPage for the current query
|
* or reset the isLastPage for the current query
|
||||||
|
|
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
package fr.free.nrw.commons.explore.depictions;
|
|
||||||
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import com.facebook.common.executors.CallerThreadExecutor;
|
|
||||||
import com.facebook.common.references.CloseableReference;
|
|
||||||
import com.facebook.datasource.DataSource;
|
|
||||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
|
||||||
import com.facebook.imagepipeline.core.ImagePipeline;
|
|
||||||
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
|
|
||||||
import com.facebook.imagepipeline.image.CloseableImage;
|
|
||||||
import com.facebook.imagepipeline.request.ImageRequest;
|
|
||||||
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
|
||||||
import com.pedrogomez.renderers.Renderer;
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renderer for DepictedItem
|
|
||||||
*/
|
|
||||||
public class SearchDepictionsRenderer extends Renderer<DepictedItem> {
|
|
||||||
|
|
||||||
@BindView(R.id.depicts_label)
|
|
||||||
TextView tvDepictionLabel;
|
|
||||||
|
|
||||||
@BindView(R.id.description)
|
|
||||||
TextView tvDepictionDesc;
|
|
||||||
|
|
||||||
@BindView(R.id.depicts_image)
|
|
||||||
ImageView imageView;
|
|
||||||
|
|
||||||
private DepictCallback listener;
|
|
||||||
|
|
||||||
public SearchDepictionsRenderer(DepictCallback listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUpView(View rootView) {
|
|
||||||
ButterKnife.bind(this, rootView);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void hookListeners(View rootView) {
|
|
||||||
rootView.setOnClickListener(v -> {
|
|
||||||
DepictedItem item = getContent();
|
|
||||||
if (listener != null) {
|
|
||||||
listener.depictsClicked(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View inflate(LayoutInflater inflater, ViewGroup parent) {
|
|
||||||
return inflater.inflate(R.layout.item_depictions, parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render value to all the items in the search depictions list
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void render() {
|
|
||||||
DepictedItem item = getContent();
|
|
||||||
tvDepictionLabel.setText(item.getName());
|
|
||||||
tvDepictionDesc.setText(item.getDescription());
|
|
||||||
imageView.setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_wikidata_logo_24dp));
|
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(item.getImageUrl())) {
|
|
||||||
ImageRequest imageRequest = ImageRequestBuilder
|
|
||||||
.newBuilderWithSource(Uri.parse(item.getImageUrl()))
|
|
||||||
.setAutoRotateEnabled(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ImagePipeline imagePipeline = Fresco.getImagePipeline();
|
|
||||||
final DataSource<CloseableReference<CloseableImage>>
|
|
||||||
dataSource = imagePipeline.fetchDecodedImage(imageRequest, getContext());
|
|
||||||
|
|
||||||
dataSource.subscribe(new BaseBitmapDataSubscriber() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNewResultImpl(@Nullable Bitmap bitmap) {
|
|
||||||
if (dataSource.isFinished() && bitmap != null) {
|
|
||||||
//imageView.setImageBitmap(Bitmap.createBitmap(bitmap));
|
|
||||||
imageView.post(() -> imageView.setImageBitmap(Bitmap.createBitmap(bitmap)));
|
|
||||||
dataSource.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailureImpl(DataSource dataSource) {
|
|
||||||
if (dataSource != null) {
|
|
||||||
dataSource.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, CallerThreadExecutor.getInstance());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface DepictCallback {
|
|
||||||
void depictsClicked(DepictedItem item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -17,7 +17,6 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import fr.free.nrw.commons.Media;
|
import fr.free.nrw.commons.Media;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||||
|
|
@ -33,9 +32,9 @@ import io.reactivex.schedulers.Schedulers;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
import kotlin.Unit;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -66,16 +65,9 @@ public class SearchImageFragment extends CommonsDaggerSupportFragment {
|
||||||
*/
|
*/
|
||||||
private int mediaSize = 0;
|
private int mediaSize = 0;
|
||||||
|
|
||||||
private RVRendererAdapter<Media> imagesAdapter;
|
private SearchImagesAdapter imagesAdapter;
|
||||||
private List<Media> queryList = new ArrayList<>();
|
private List<Media> queryList = new ArrayList<>();
|
||||||
|
|
||||||
private final SearchImagesAdapterFactory adapterFactory = new SearchImagesAdapterFactory(item -> {
|
|
||||||
// Called on Click of a individual media Item
|
|
||||||
int index = queryList.indexOf(item);
|
|
||||||
((SearchActivity)getContext()).onSearchImageClicked(index);
|
|
||||||
saveQuery(query);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method saves Search Query in the Recent Searches Database.
|
* This method saves Search Query in the Recent Searches Database.
|
||||||
* @param query
|
* @param query
|
||||||
|
|
@ -106,8 +98,11 @@ public class SearchImageFragment extends CommonsDaggerSupportFragment {
|
||||||
else{
|
else{
|
||||||
imagesRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
imagesRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
||||||
}
|
}
|
||||||
ArrayList<Media> items = new ArrayList<>();
|
imagesAdapter =new SearchImagesAdapter(media -> {
|
||||||
imagesAdapter = adapterFactory.create(items);
|
((SearchActivity)getContext()).onSearchImageClicked(imagesAdapter.getItems().indexOf(media));
|
||||||
|
saveQuery(query);
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
imagesRecyclerView.setAdapter(imagesAdapter);
|
imagesRecyclerView.setAdapter(imagesAdapter);
|
||||||
imagesRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
imagesRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -173,7 +168,6 @@ public class SearchImageFragment extends CommonsDaggerSupportFragment {
|
||||||
if (mediaList.size() != 0 && !queryList.get(queryList.size() - 1).getFilename().equals(mediaList.get(mediaList.size() - 1).getFilename())) {
|
if (mediaList.size() != 0 && !queryList.get(queryList.size() - 1).getFilename().equals(mediaList.get(mediaList.size() - 1).getFilename())) {
|
||||||
queryList.addAll(mediaList);
|
queryList.addAll(mediaList);
|
||||||
imagesAdapter.addAll(mediaList);
|
imagesAdapter.addAll(mediaList);
|
||||||
imagesAdapter.notifyDataSetChanged();
|
|
||||||
((SearchActivity) getContext()).viewPagerNotifyDataSetChanged();
|
((SearchActivity) getContext()).viewPagerNotifyDataSetChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -222,8 +216,7 @@ public class SearchImageFragment extends CommonsDaggerSupportFragment {
|
||||||
|
|
||||||
private void handleLabelforImage(String s, int position) {
|
private void handleLabelforImage(String s, int position) {
|
||||||
if (!s.trim().equals(getString(R.string.detail_caption_empty))) {
|
if (!s.trim().equals(getString(R.string.detail_caption_empty))) {
|
||||||
imagesAdapter.getItem(position).setThumbnailTitle(s);
|
imagesAdapter.updateThumbnail(position, s);
|
||||||
imagesAdapter.notifyDataSetChanged();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -281,13 +274,11 @@ public class SearchImageFragment extends CommonsDaggerSupportFragment {
|
||||||
* @param i position of Media in the recyclerview adapter.
|
* @param i position of Media in the recyclerview adapter.
|
||||||
*/
|
*/
|
||||||
public Media getImageAtPosition(int i) {
|
public Media getImageAtPosition(int i) {
|
||||||
if (imagesAdapter.getItem(i).getFilename() == null) {
|
if (imagesAdapter.getItemAt(i).getFilename() == null) {
|
||||||
// not yet ready to return data
|
// not yet ready to return data
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
return imagesAdapter.getItemAt(i);
|
||||||
return imagesAdapter.getItem(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void onDestroyView() {
|
@Override public void onDestroyView() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package fr.free.nrw.commons.explore.images
|
||||||
|
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.ListDelegationAdapter
|
||||||
|
import fr.free.nrw.commons.Media
|
||||||
|
|
||||||
|
class SearchImagesAdapter(onImageClicked: (Media) -> Unit) : ListDelegationAdapter<List<Media>>(
|
||||||
|
searchImagesAdapter(onImageClicked)
|
||||||
|
) {
|
||||||
|
fun getItemAt(position: Int) = items[position]
|
||||||
|
|
||||||
|
init {
|
||||||
|
items = emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
items = emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addAll(mediaList: List<Media>) {
|
||||||
|
items = items + mediaList
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateThumbnail(position: Int, thumbnailTitle: String) {
|
||||||
|
items[position].thumbnailTitle = thumbnailTitle
|
||||||
|
notifyItemChanged(position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package fr.free.nrw.commons.explore.images
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer
|
||||||
|
import fr.free.nrw.commons.Media
|
||||||
|
import fr.free.nrw.commons.R
|
||||||
|
import kotlinx.android.synthetic.main.layout_category_images.*
|
||||||
|
|
||||||
|
|
||||||
|
fun searchImagesAdapter(onImageClicked: (Media) -> Unit) =
|
||||||
|
adapterDelegateLayoutContainer<Media, Media>(R.layout.layout_category_images) {
|
||||||
|
categoryImageView.setOnClickListener { onImageClicked(item) }
|
||||||
|
bind {
|
||||||
|
categoryImageTitle.text = item.thumbnailTitle
|
||||||
|
categoryImageView.setImageURI(item.thumbUrl)
|
||||||
|
if (item.creator?.isNotEmpty() == true) {
|
||||||
|
categoryImageAuthor.visibility = View.VISIBLE
|
||||||
|
categoryImageAuthor.text = getString(R.string.image_uploaded_by, item.creator)
|
||||||
|
} else {
|
||||||
|
categoryImageAuthor.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
package fr.free.nrw.commons.explore.images;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.ListAdapteeCollection;
|
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import com.pedrogomez.renderers.RendererBuilder;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.Media;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class helps in creating adapter for imagesRecyclerView in SearchImagesFragment,
|
|
||||||
* implementing onClicks on imagesRecyclerView Items
|
|
||||||
**/
|
|
||||||
class SearchImagesAdapterFactory {
|
|
||||||
private final SearchImagesRenderer.ImageClickedListener listener;
|
|
||||||
|
|
||||||
SearchImagesAdapterFactory(SearchImagesRenderer.ImageClickedListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method creates a recyclerViewAdapter for Media.
|
|
||||||
* @param searchImageItemList List of Media objects to be displayed
|
|
||||||
* @return imagesAdapter
|
|
||||||
**/
|
|
||||||
public RVRendererAdapter<Media> create(List<Media> searchImageItemList) {
|
|
||||||
RendererBuilder<Media> builder = new RendererBuilder<Media>()
|
|
||||||
.bind(Media.class, new SearchImagesRenderer(listener));
|
|
||||||
ListAdapteeCollection<Media> collection = new ListAdapteeCollection<>(
|
|
||||||
searchImageItemList != null ? searchImageItemList : Collections.<Media>emptyList());
|
|
||||||
return new RVRendererAdapter<>(builder, collection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
package fr.free.nrw.commons.explore.images;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.facebook.drawee.view.SimpleDraweeView;
|
|
||||||
import com.pedrogomez.renderers.Renderer;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import fr.free.nrw.commons.Media;
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* presentation logic of individual image in search is handled here
|
|
||||||
**/
|
|
||||||
class SearchImagesRenderer extends Renderer<Media> {
|
|
||||||
@BindView(R.id.categoryImageTitle) TextView tvImageName;
|
|
||||||
@BindView(R.id.categoryImageAuthor) TextView categoryImageAuthor;
|
|
||||||
@BindView(R.id.categoryImageView) SimpleDraweeView browseImage;
|
|
||||||
|
|
||||||
private final ImageClickedListener listener;
|
|
||||||
|
|
||||||
SearchImagesRenderer(ImageClickedListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View inflate(LayoutInflater layoutInflater, ViewGroup viewGroup) {
|
|
||||||
return layoutInflater.inflate(R.layout.layout_category_images, viewGroup, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUpView(View view) {
|
|
||||||
ButterKnife.bind(this, view);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void hookListeners(View view) {
|
|
||||||
view.setOnClickListener(v -> {
|
|
||||||
Media item = getContent();
|
|
||||||
if (listener != null) {
|
|
||||||
listener.imageClicked(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render() {
|
|
||||||
Media item = getContent();
|
|
||||||
tvImageName.setText(item.getThumbnailTitle());
|
|
||||||
browseImage.setImageURI(item.getThumbUrl());
|
|
||||||
setAuthorView(item, categoryImageAuthor);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ImageClickedListener {
|
|
||||||
void imageClicked(Media item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* formats author name as "Uploaded by: authorName" and sets it in textview
|
|
||||||
*/
|
|
||||||
private void setAuthorView(Media item, TextView author) {
|
|
||||||
if (item.getCreator() != null && !item.getCreator().equals("")) {
|
|
||||||
author.setVisibility(View.VISIBLE);
|
|
||||||
String uploadedByTemplate = getContext().getString(R.string.image_uploaded_by);
|
|
||||||
author.setText(String.format(uploadedByTemplate, item.getCreator()));
|
|
||||||
} else {
|
|
||||||
author.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,6 +2,7 @@ package fr.free.nrw.commons.media;
|
||||||
|
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
|
import static fr.free.nrw.commons.category.CategoryClientKt.CATEGORY_PREFIX;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
|
@ -49,7 +50,6 @@ import fr.free.nrw.commons.delete.ReasonBuilder;
|
||||||
import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity;
|
import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity;
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||||
import fr.free.nrw.commons.ui.widget.HtmlTextView;
|
import fr.free.nrw.commons.ui.widget.HtmlTextView;
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
|
||||||
import fr.free.nrw.commons.utils.ViewUtilWrapper;
|
import fr.free.nrw.commons.utils.ViewUtilWrapper;
|
||||||
import io.reactivex.Single;
|
import io.reactivex.Single;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
|
@ -619,7 +619,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
if (categoriesLoaded && categoriesPresent) {
|
if (categoriesLoaded && categoriesPresent) {
|
||||||
textView.setOnClickListener(view -> {
|
textView.setOnClickListener(view -> {
|
||||||
// Open Category Details page
|
// Open Category Details page
|
||||||
String selectedCategoryTitle = "Category:" + catName;
|
String selectedCategoryTitle = CATEGORY_PREFIX + catName;
|
||||||
Intent intent = new Intent(getContext(), CategoryDetailsActivity.class);
|
Intent intent = new Intent(getContext(), CategoryDetailsActivity.class);
|
||||||
intent.putExtra("categoryName", selectedCategoryTitle);
|
intent.putExtra("categoryName", selectedCategoryTitle);
|
||||||
getContext().startActivity(intent);
|
getContext().startActivity(intent);
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,23 @@
|
||||||
package fr.free.nrw.commons.mwapi;
|
package fr.free.nrw.commons.mwapi;
|
||||||
|
|
||||||
|
import static fr.free.nrw.commons.category.CategoryClientKt.CATEGORY_PREFIX;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import io.reactivex.Single;
|
||||||
import org.wikipedia.dataclient.mwapi.MwQueryPage;
|
|
||||||
import org.wikipedia.dataclient.mwapi.MwQueryResponse;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import io.reactivex.Single;
|
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
import okhttp3.ResponseBody;
|
import okhttp3.ResponseBody;
|
||||||
|
import org.wikipedia.dataclient.mwapi.MwQueryPage;
|
||||||
|
import org.wikipedia.dataclient.mwapi.MwQueryResponse;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -60,7 +58,7 @@ public class CategoryApi {
|
||||||
for (MwQueryPage page : apiResponse.query().pages()) {
|
for (MwQueryPage page : apiResponse.query().pages()) {
|
||||||
if (page.categories() != null) {
|
if (page.categories() != null) {
|
||||||
for (MwQueryPage.Category category : page.categories()) {
|
for (MwQueryPage.Category category : page.categories()) {
|
||||||
categories.add(category.title().replace("Category:", ""));
|
categories.add(category.title().replace(CATEGORY_PREFIX, ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
package fr.free.nrw.commons.nearby;
|
|
||||||
|
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.ListAdapteeCollection;
|
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import com.pedrogomez.renderers.RendererBuilder;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.contributions.ContributionController;
|
|
||||||
|
|
||||||
public class NearbyAdapterFactory {
|
|
||||||
|
|
||||||
private Fragment fragment;
|
|
||||||
private 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, onBookmarkClick));
|
|
||||||
ListAdapteeCollection<Place> collection = new ListAdapteeCollection<>(
|
|
||||||
placeList != null ? placeList : Collections.emptyList());
|
|
||||||
return new RVRendererAdapter<>(builder, collection);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateAdapterData(List<Place> newPlaceList, RVRendererAdapter<Place> rendererAdapter) {
|
|
||||||
rendererAdapter.notifyDataSetChanged();
|
|
||||||
rendererAdapter.diffUpdate(newPlaceList);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear(RVRendererAdapter<Place> rendererAdapter){
|
|
||||||
rendererAdapter.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(Place place, RVRendererAdapter<Place> rendererAdapter){
|
|
||||||
rendererAdapter.add(place);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(RVRendererAdapter<Place> rendererAdapter){
|
|
||||||
rendererAdapter.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
package fr.free.nrw.commons.nearby
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.view.View.*
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.transition.TransitionManager
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.dsl.AdapterDelegateLayoutContainerViewHolder
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer
|
||||||
|
import fr.free.nrw.commons.R
|
||||||
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao
|
||||||
|
import kotlinx.android.synthetic.main.item_place.*
|
||||||
|
import kotlinx.android.synthetic.main.nearby_row_button.*
|
||||||
|
|
||||||
|
|
||||||
|
fun placeAdapterDelegate(
|
||||||
|
bookmarkLocationDao: BookmarkLocationsDao,
|
||||||
|
onItemClick: ((Place) -> Unit)? = null,
|
||||||
|
onCameraClicked: (Place) -> Unit,
|
||||||
|
onGalleryClicked: (Place) -> Unit,
|
||||||
|
onBookmarkClicked: (Place, Boolean) -> Unit,
|
||||||
|
onOverflowIconClicked: (Place, View) -> Unit,
|
||||||
|
onDirectionsClicked: (Place) -> Unit
|
||||||
|
) =
|
||||||
|
adapterDelegateLayoutContainer<Place, Place>(R.layout.item_place) {
|
||||||
|
containerView.setOnClickListener { _: View? ->
|
||||||
|
showOrHideAndScrollToIfLast()
|
||||||
|
onItemClick?.invoke(item)
|
||||||
|
}
|
||||||
|
containerView.setOnFocusChangeListener { view1: View?, hasFocus: Boolean ->
|
||||||
|
if (!hasFocus && buttonLayout.isShown) {
|
||||||
|
buttonLayout.visibility = GONE
|
||||||
|
} else if (hasFocus && !buttonLayout.isShown) {
|
||||||
|
showOrHideAndScrollToIfLast()
|
||||||
|
onItemClick?.invoke(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cameraButton.setOnClickListener { onCameraClicked(item) }
|
||||||
|
galleryButton.setOnClickListener { onGalleryClicked(item) }
|
||||||
|
bookmarkButtonImage.setOnClickListener {
|
||||||
|
val isBookmarked = bookmarkLocationDao.updateBookmarkLocation(item)
|
||||||
|
bookmarkButtonImage.setImageResource(if (isBookmarked) R.drawable.ic_round_star_filled_24px else R.drawable.ic_round_star_border_24px)
|
||||||
|
onBookmarkClicked(item, isBookmarked)
|
||||||
|
}
|
||||||
|
iconOverflow.setOnClickListener { onOverflowIconClicked(item, it) }
|
||||||
|
directionsButton.setOnClickListener { onDirectionsClicked(item) }
|
||||||
|
bind {
|
||||||
|
tvName.text = item.name
|
||||||
|
val descriptionText: String = item.longDescription
|
||||||
|
if (descriptionText == "?") {
|
||||||
|
tvDesc.setText(R.string.no_description_found)
|
||||||
|
tvDesc.visibility = INVISIBLE
|
||||||
|
} else {
|
||||||
|
tvDesc.text = descriptionText
|
||||||
|
}
|
||||||
|
distance.text = item.distance
|
||||||
|
icon.setImageResource(item.label.icon)
|
||||||
|
iconOverflow.visibility =
|
||||||
|
if (item.hasCommonsLink() || item.hasWikidataLink()) VISIBLE
|
||||||
|
else GONE
|
||||||
|
|
||||||
|
bookmarkButtonImage.setImageResource(
|
||||||
|
if (bookmarkLocationDao.findBookmarkLocation(item))
|
||||||
|
R.drawable.ic_round_star_filled_24px
|
||||||
|
else
|
||||||
|
R.drawable.ic_round_star_border_24px
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun AdapterDelegateLayoutContainerViewHolder<Place>.showOrHideAndScrollToIfLast() {
|
||||||
|
TransitionManager.beginDelayedTransition(buttonLayout)
|
||||||
|
if (buttonLayout.isShown) {
|
||||||
|
buttonLayout.visibility = GONE
|
||||||
|
} else {
|
||||||
|
buttonLayout.visibility = VISIBLE
|
||||||
|
val recyclerView = containerView.parent as RecyclerView
|
||||||
|
val lastPosition = recyclerView.adapter!!.itemCount - 1
|
||||||
|
if (recyclerView.getChildLayoutPosition(containerView) == lastPosition) {
|
||||||
|
(recyclerView.layoutManager as LinearLayoutManager?)
|
||||||
|
?.scrollToPositionWithOffset(lastPosition, buttonLayout.height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,289 +0,0 @@
|
||||||
package fr.free.nrw.commons.nearby;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import androidx.appcompat.widget.PopupMenu;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import androidx.transition.TransitionManager;
|
|
||||||
|
|
||||||
import com.facebook.drawee.view.SimpleDraweeView;
|
|
||||||
import com.pedrogomez.renderers.Renderer;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
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 fr.free.nrw.commons.kvstore.JsonKvStore;
|
|
||||||
import fr.free.nrw.commons.nearby.fragments.NearbyParentFragment;
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
import static fr.free.nrw.commons.theme.NavigationBaseActivity.startActivityWithFlags;
|
|
||||||
import static fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT;
|
|
||||||
|
|
||||||
public class PlaceRenderer extends Renderer<Place> {
|
|
||||||
|
|
||||||
@BindView(R.id.tvName) TextView tvName;
|
|
||||||
@BindView(R.id.tvDesc) TextView tvDesc;
|
|
||||||
@BindView(R.id.distance) TextView distance;
|
|
||||||
@BindView(R.id.icon) SimpleDraweeView icon;
|
|
||||||
@BindView(R.id.buttonLayout) LinearLayout buttonLayout;
|
|
||||||
@BindView(R.id.cameraButton) LinearLayout cameraButton;
|
|
||||||
|
|
||||||
@BindView(R.id.galleryButton) LinearLayout galleryButton;
|
|
||||||
@BindView(R.id.directionsButton) LinearLayout directionsButton;
|
|
||||||
@BindView(R.id.iconOverflow) LinearLayout iconOverflow;
|
|
||||||
@BindView(R.id.cameraButtonText) TextView cameraButtonText;
|
|
||||||
@BindView(R.id.galleryButtonText) TextView galleryButtonText;
|
|
||||||
@BindView(R.id.bookmarkButtonImage) ImageView bookmarkButtonImage;
|
|
||||||
|
|
||||||
@BindView(R.id.directionsButtonText) TextView directionsButtonText;
|
|
||||||
@BindView(R.id.iconOverflowText) TextView iconOverflowText;
|
|
||||||
|
|
||||||
private View view;
|
|
||||||
private static ArrayList<LinearLayout> openedItems;
|
|
||||||
private Place place;
|
|
||||||
|
|
||||||
private Fragment fragment;
|
|
||||||
private ContributionController controller;
|
|
||||||
private OnBookmarkClick onBookmarkClick;
|
|
||||||
|
|
||||||
@Inject BookmarkLocationsDao bookmarkLocationDao;
|
|
||||||
@Inject
|
|
||||||
@Named("default_preferences")
|
|
||||||
JsonKvStore applicationKvStore;
|
|
||||||
|
|
||||||
public PlaceRenderer(){
|
|
||||||
openedItems = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlaceRenderer(
|
|
||||||
Fragment fragment,
|
|
||||||
ContributionController controller,
|
|
||||||
OnBookmarkClick onBookmarkClick
|
|
||||||
) {
|
|
||||||
this.fragment = fragment;
|
|
||||||
this.controller = controller;
|
|
||||||
openedItems = new ArrayList<>();
|
|
||||||
this.onBookmarkClick = onBookmarkClick;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View inflate(LayoutInflater layoutInflater, ViewGroup viewGroup) {
|
|
||||||
view = layoutInflater.inflate(R.layout.item_place, viewGroup, false);
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUpView(View view) {
|
|
||||||
ButterKnife.bind(this, view);
|
|
||||||
closeLayout(buttonLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void hookListeners(View view) {
|
|
||||||
|
|
||||||
final View.OnClickListener listener = view12 -> {
|
|
||||||
Timber.d("Renderer clicked");
|
|
||||||
TransitionManager.beginDelayedTransition(buttonLayout);
|
|
||||||
|
|
||||||
if (buttonLayout.isShown()) {
|
|
||||||
closeLayout(buttonLayout);
|
|
||||||
} else {
|
|
||||||
openLayout(buttonLayout);
|
|
||||||
RecyclerView recyclerView = (RecyclerView) view.getParent();
|
|
||||||
int lastPosition = recyclerView.getAdapter().getItemCount() - 1;
|
|
||||||
if (recyclerView.getChildLayoutPosition(view) == lastPosition) {
|
|
||||||
((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(lastPosition, buttonLayout.getHeight());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (onBookmarkClick == null) {
|
|
||||||
((NearbyParentFragment) fragment).centerMapToPlace(place);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
view.setOnClickListener(listener);
|
|
||||||
|
|
||||||
view.requestFocus();
|
|
||||||
view.setOnFocusChangeListener((view1, hasFocus) -> {
|
|
||||||
if (!hasFocus && buttonLayout.isShown()) {
|
|
||||||
closeLayout(buttonLayout);
|
|
||||||
} else if (hasFocus && !buttonLayout.isShown()) {
|
|
||||||
listener.onClick(view1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cameraButton.setOnClickListener(view2 -> {
|
|
||||||
if (applicationKvStore.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);
|
|
||||||
applicationKvStore.putBoolean("login_skipped", false);
|
|
||||||
fragment.getActivity().finish();
|
|
||||||
})
|
|
||||||
.show();
|
|
||||||
} else {
|
|
||||||
Timber.d("Camera button tapped. Image title: " + place.getName() + "Image desc: " + place.getLongDescription());
|
|
||||||
storeSharedPrefs();
|
|
||||||
controller.initiateCameraPick(fragment.getActivity());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
galleryButton.setOnClickListener(view3 -> {
|
|
||||||
if (applicationKvStore.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);
|
|
||||||
applicationKvStore.putBoolean("login_skipped", false);
|
|
||||||
fragment.getActivity().finish();
|
|
||||||
})
|
|
||||||
.show();
|
|
||||||
}else {
|
|
||||||
Timber.d("Gallery button tapped. Image title: " + place.getName() + "Image desc: " + place.getLongDescription());
|
|
||||||
storeSharedPrefs();
|
|
||||||
controller.initiateGalleryPick(fragment.getActivity(), false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
bookmarkButtonImage.setOnClickListener(view4 -> {
|
|
||||||
if (applicationKvStore.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);
|
|
||||||
applicationKvStore.putBoolean("login_skipped", false);
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
((NearbyParentFragment) (fragment)).updateMarker(isBookmarked, place, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void storeSharedPrefs() {
|
|
||||||
Timber.d("Store place object %s", place.toString());
|
|
||||||
applicationKvStore.putJson(PLACE_OBJECT, place);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void closeLayout(LinearLayout buttonLayout){
|
|
||||||
buttonLayout.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void openLayout(LinearLayout buttonLayout){
|
|
||||||
buttonLayout.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render() {
|
|
||||||
ApplicationlessInjection.getInstance(getContext().getApplicationContext())
|
|
||||||
.getCommonsApplicationComponent().inject(this);
|
|
||||||
place = getContent();
|
|
||||||
tvName.setText(place.name);
|
|
||||||
String descriptionText = place.getLongDescription();
|
|
||||||
if (descriptionText.equals("?")) {
|
|
||||||
descriptionText = getContext().getString(R.string.no_description_found);
|
|
||||||
tvDesc.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
tvDesc.setText(descriptionText);
|
|
||||||
distance.setText(place.distance);
|
|
||||||
|
|
||||||
|
|
||||||
icon.setImageResource(place.getLabel().getIcon());
|
|
||||||
|
|
||||||
directionsButton.setOnClickListener(view -> Utils.handleGeoCoordinates(getContext(), this.place.getLocation()));
|
|
||||||
|
|
||||||
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() {
|
|
||||||
PopupMenu popupMenu = new PopupMenu(view.getContext(), iconOverflow);
|
|
||||||
popupMenu.inflate(R.menu.nearby_info_dialog_options);
|
|
||||||
|
|
||||||
MenuItem commonsArticle = popupMenu.getMenu()
|
|
||||||
.findItem(R.id.nearby_info_menu_commons_article);
|
|
||||||
MenuItem wikiDataArticle = popupMenu.getMenu()
|
|
||||||
.findItem(R.id.nearby_info_menu_wikidata_article);
|
|
||||||
MenuItem wikipediaArticle = popupMenu.getMenu()
|
|
||||||
.findItem(R.id.nearby_info_menu_wikipedia_article);
|
|
||||||
|
|
||||||
commonsArticle.setEnabled(place.hasCommonsLink());
|
|
||||||
wikiDataArticle.setEnabled(place.hasWikidataLink());
|
|
||||||
wikipediaArticle.setEnabled(place.hasWikipediaLink());
|
|
||||||
|
|
||||||
popupMenu.setOnMenuItemClickListener(item -> {
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case R.id.nearby_info_menu_commons_article:
|
|
||||||
openWebView(place.siteLinks.getCommonsLink());
|
|
||||||
return true;
|
|
||||||
case R.id.nearby_info_menu_wikidata_article:
|
|
||||||
openWebView(place.siteLinks.getWikidataLink());
|
|
||||||
return true;
|
|
||||||
case R.id.nearby_info_menu_wikipedia_article:
|
|
||||||
openWebView(place.siteLinks.getWikipediaLink());
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
popupMenu.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void openWebView(Uri link) {
|
|
||||||
Utils.handleWebUrl(getContext(), link);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean showMenu() {
|
|
||||||
return place.hasCommonsLink() || place.hasWikidataLink();
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnBookmarkClick {
|
|
||||||
void onClick();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
package fr.free.nrw.commons.nearby.fragments
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.appcompat.widget.PopupMenu
|
||||||
|
import fr.free.nrw.commons.R
|
||||||
|
import fr.free.nrw.commons.Utils
|
||||||
|
import fr.free.nrw.commons.auth.LoginActivity
|
||||||
|
import fr.free.nrw.commons.contributions.ContributionController
|
||||||
|
import fr.free.nrw.commons.kvstore.JsonKvStore
|
||||||
|
import fr.free.nrw.commons.nearby.Place
|
||||||
|
import fr.free.nrw.commons.theme.NavigationBaseActivity
|
||||||
|
import fr.free.nrw.commons.wikidata.WikidataConstants
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Named
|
||||||
|
|
||||||
|
|
||||||
|
class CommonPlaceClickActions @Inject constructor(
|
||||||
|
@Named("default_preferences") private val applicationKvStore: JsonKvStore,
|
||||||
|
private val activity: Activity,
|
||||||
|
private val contributionController: ContributionController
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun onCameraClicked(): (Place) -> Unit = {
|
||||||
|
if (applicationKvStore.getBoolean("login_skipped", false)) {
|
||||||
|
showLoginDialog()
|
||||||
|
} else {
|
||||||
|
Timber.d("Camera button tapped. Image title: ${it.getName()}Image desc: ${it.longDescription}")
|
||||||
|
storeSharedPrefs(it)
|
||||||
|
contributionController.initiateCameraPick(activity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onGalleryClicked(): (Place) -> Unit = {
|
||||||
|
if (applicationKvStore.getBoolean("login_skipped", false)) {
|
||||||
|
showLoginDialog()
|
||||||
|
} else {
|
||||||
|
Timber.d("Gallery button tapped. Image title: ${it.getName()}Image desc: ${it.getLongDescription()}")
|
||||||
|
storeSharedPrefs(it)
|
||||||
|
contributionController.initiateGalleryPick(activity, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onOverflowClicked(): (Place, View) -> Unit = { place, view ->
|
||||||
|
PopupMenu(view.context, view).apply {
|
||||||
|
inflate(R.menu.nearby_info_dialog_options)
|
||||||
|
enableBy(R.id.nearby_info_menu_commons_article, place.hasCommonsLink())
|
||||||
|
enableBy(R.id.nearby_info_menu_wikidata_article, place.hasWikidataLink())
|
||||||
|
enableBy(R.id.nearby_info_menu_wikipedia_article, place.hasWikipediaLink())
|
||||||
|
setOnMenuItemClickListener { item: MenuItem ->
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.nearby_info_menu_commons_article -> openWebView(place.siteLinks.commonsLink)
|
||||||
|
R.id.nearby_info_menu_wikidata_article -> openWebView(place.siteLinks.wikidataLink)
|
||||||
|
R.id.nearby_info_menu_wikipedia_article -> openWebView(place.siteLinks.wikipediaLink)
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onDirectionsClicked(): (Place) -> Unit = {
|
||||||
|
Utils.handleGeoCoordinates(activity, it.getLocation())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun storeSharedPrefs(selectedPlace: Place) {
|
||||||
|
Timber.d("Store place object %s", selectedPlace.toString())
|
||||||
|
applicationKvStore.putJson(WikidataConstants.PLACE_OBJECT, selectedPlace)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openWebView(link: Uri): Boolean {
|
||||||
|
Utils.handleWebUrl(activity, link)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PopupMenu.enableBy(menuId: Int, hasLink: Boolean) {
|
||||||
|
menu.findItem(menuId).isEnabled = hasLink
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showLoginDialog() {
|
||||||
|
AlertDialog.Builder(activity)
|
||||||
|
.setMessage(R.string.login_alert_message)
|
||||||
|
.setPositiveButton(R.string.login) { dialog, which ->
|
||||||
|
NavigationBaseActivity.startActivityWithFlags(
|
||||||
|
activity,
|
||||||
|
LoginActivity::class.java,
|
||||||
|
Intent.FLAG_ACTIVITY_CLEAR_TOP,
|
||||||
|
Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||||
|
)
|
||||||
|
applicationKvStore.putBoolean("login_skipped", false)
|
||||||
|
activity.finish()
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,6 @@ import static fr.free.nrw.commons.utils.LengthUtils.formatDistanceBetween;
|
||||||
import static fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT;
|
import static fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
|
@ -39,6 +38,8 @@ import android.widget.Toast;
|
||||||
import androidx.annotation.DrawableRes;
|
import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
@ -68,7 +69,6 @@ import com.mapbox.mapboxsdk.maps.Style;
|
||||||
import com.mapbox.mapboxsdk.maps.UiSettings;
|
import com.mapbox.mapboxsdk.maps.UiSettings;
|
||||||
import com.mapbox.pluginscalebar.ScaleBarOptions;
|
import com.mapbox.pluginscalebar.ScaleBarOptions;
|
||||||
import com.mapbox.pluginscalebar.ScaleBarPlugin;
|
import com.mapbox.pluginscalebar.ScaleBarPlugin;
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import fr.free.nrw.commons.CommonsApplication;
|
import fr.free.nrw.commons.CommonsApplication;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.Utils;
|
import fr.free.nrw.commons.Utils;
|
||||||
|
|
@ -76,6 +76,7 @@ import fr.free.nrw.commons.auth.LoginActivity;
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
||||||
import fr.free.nrw.commons.contributions.ContributionController;
|
import fr.free.nrw.commons.contributions.ContributionController;
|
||||||
import fr.free.nrw.commons.contributions.MainActivity;
|
import fr.free.nrw.commons.contributions.MainActivity;
|
||||||
|
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||||
|
|
@ -83,7 +84,6 @@ import fr.free.nrw.commons.location.LocationUpdateListener;
|
||||||
import fr.free.nrw.commons.nearby.CheckBoxTriStates;
|
import fr.free.nrw.commons.nearby.CheckBoxTriStates;
|
||||||
import fr.free.nrw.commons.nearby.Label;
|
import fr.free.nrw.commons.nearby.Label;
|
||||||
import fr.free.nrw.commons.nearby.MarkerPlaceGroup;
|
import fr.free.nrw.commons.nearby.MarkerPlaceGroup;
|
||||||
import fr.free.nrw.commons.nearby.NearbyAdapterFactory;
|
|
||||||
import fr.free.nrw.commons.nearby.NearbyBaseMarker;
|
import fr.free.nrw.commons.nearby.NearbyBaseMarker;
|
||||||
import fr.free.nrw.commons.nearby.NearbyController;
|
import fr.free.nrw.commons.nearby.NearbyController;
|
||||||
import fr.free.nrw.commons.nearby.NearbyFilterSearchRecyclerViewAdapter;
|
import fr.free.nrw.commons.nearby.NearbyFilterSearchRecyclerViewAdapter;
|
||||||
|
|
@ -105,12 +105,14 @@ import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
import fr.free.nrw.commons.wikidata.WikidataEditListener;
|
import fr.free.nrw.commons.wikidata.WikidataEditListener;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
import kotlin.Unit;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -163,6 +165,8 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SystemThemeUtils systemThemeUtils;
|
SystemThemeUtils systemThemeUtils;
|
||||||
|
@Inject
|
||||||
|
CommonPlaceClickActions commonPlaceClickActions;
|
||||||
|
|
||||||
private NearbyFilterSearchRecyclerViewAdapter nearbyFilterSearchRecyclerViewAdapter;
|
private NearbyFilterSearchRecyclerViewAdapter nearbyFilterSearchRecyclerViewAdapter;
|
||||||
|
|
||||||
|
|
@ -176,7 +180,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
private static final float ZOOM_LEVEL = 14f;
|
private static final float ZOOM_LEVEL = 14f;
|
||||||
private final String NETWORK_INTENT_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
|
private final String NETWORK_INTENT_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
|
||||||
private BroadcastReceiver broadcastReceiver;
|
private BroadcastReceiver broadcastReceiver;
|
||||||
private boolean isNetworkErrorOccurred = false;
|
private boolean isNetworkErrorOccurred;
|
||||||
private Snackbar snackbar;
|
private Snackbar snackbar;
|
||||||
private View view;
|
private View view;
|
||||||
private NearbyParentFragmentPresenter presenter;
|
private NearbyParentFragmentPresenter presenter;
|
||||||
|
|
@ -188,25 +192,22 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
private final double CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT = 0.005;
|
private final double CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT = 0.005;
|
||||||
private final double CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE = 0.004;
|
private final double CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE = 0.004;
|
||||||
|
|
||||||
private boolean isMapBoxReady=false;
|
private boolean isMapBoxReady;
|
||||||
private MapboxMap mapBox;
|
private MapboxMap mapBox;
|
||||||
IntentFilter intentFilter = new IntentFilter(NETWORK_INTENT_ACTION);
|
IntentFilter intentFilter = new IntentFilter(NETWORK_INTENT_ACTION);
|
||||||
private Marker currentLocationMarker;
|
private Marker currentLocationMarker;
|
||||||
private Polygon currentLocationPolygon;
|
private Polygon currentLocationPolygon;
|
||||||
private Place lastPlaceToCenter;
|
private Place lastPlaceToCenter;
|
||||||
private fr.free.nrw.commons.location.LatLng lastKnownLocation;
|
private fr.free.nrw.commons.location.LatLng lastKnownLocation;
|
||||||
private fr.free.nrw.commons.location.LatLng currentLocation=null;
|
|
||||||
private NearbyController.NearbyPlacesInfo nearbyPlacesInfo;
|
|
||||||
private NearbyAdapterFactory adapterFactory;
|
|
||||||
private boolean isVisibleToUser;
|
private boolean isVisibleToUser;
|
||||||
private MapboxMap.OnCameraMoveListener cameraMoveListener;
|
private MapboxMap.OnCameraMoveListener cameraMoveListener;
|
||||||
private fr.free.nrw.commons.location.LatLng lastFocusLocation;
|
private fr.free.nrw.commons.location.LatLng lastFocusLocation;
|
||||||
private LatLngBounds latLngBounds;
|
private LatLngBounds latLngBounds;
|
||||||
|
private PlaceAdapter adapter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
final Bundle savedInstanceState) {
|
||||||
view = inflater.inflate(R.layout.fragment_nearby_parent, container, false);
|
view = inflater.inflate(R.layout.fragment_nearby_parent, container, false);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
initNetworkBroadCastReceiver();
|
initNetworkBroadCastReceiver();
|
||||||
|
|
@ -217,7 +218,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
isDarkTheme = systemThemeUtils.isDeviceInNightMode();
|
isDarkTheme = systemThemeUtils.isDeviceInNightMode();
|
||||||
cameraMoveListener= () -> presenter.onCameraMove(mapBox.getCameraPosition().target);
|
cameraMoveListener= () -> presenter.onCameraMove(mapBox.getCameraPosition().target);
|
||||||
|
|
@ -227,28 +228,28 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
initThemePreferences();
|
initThemePreferences();
|
||||||
mapView.onCreate(savedInstanceState);
|
mapView.onCreate(savedInstanceState);
|
||||||
mapView.getMapAsync(mapBoxMap -> {
|
mapView.getMapAsync(mapBoxMap -> {
|
||||||
this.mapBox=mapBoxMap;
|
mapBox =mapBoxMap;
|
||||||
initViews();
|
initViews();
|
||||||
presenter.setActionListeners(applicationKvStore);
|
presenter.setActionListeners(applicationKvStore);
|
||||||
initNearbyFilter();
|
initNearbyFilter();
|
||||||
mapBoxMap.setStyle(isDarkTheme?Style.DARK:Style.OUTDOORS, style -> {
|
mapBoxMap.setStyle(isDarkTheme?Style.DARK:Style.OUTDOORS, style -> {
|
||||||
UiSettings uiSettings = mapBoxMap.getUiSettings();
|
final UiSettings uiSettings = mapBoxMap.getUiSettings();
|
||||||
uiSettings.setCompassGravity(Gravity.BOTTOM | Gravity.LEFT);
|
uiSettings.setCompassGravity(Gravity.BOTTOM | Gravity.LEFT);
|
||||||
uiSettings.setCompassMargins(12, 0, 0, 24);
|
uiSettings.setCompassMargins(12, 0, 0, 24);
|
||||||
uiSettings.setLogoEnabled(true);
|
uiSettings.setLogoEnabled(true);
|
||||||
uiSettings.setAttributionEnabled(true);
|
uiSettings.setAttributionEnabled(true);
|
||||||
uiSettings.setRotateGesturesEnabled(false);
|
uiSettings.setRotateGesturesEnabled(false);
|
||||||
NearbyParentFragment.this.isMapBoxReady=true;
|
isMapBoxReady =true;
|
||||||
performMapReadyActions();
|
performMapReadyActions();
|
||||||
CameraPosition cameraPosition = new CameraPosition.Builder()
|
final CameraPosition cameraPosition = new CameraPosition.Builder()
|
||||||
.target(new LatLng(51.50550, -0.07520))
|
.target(new LatLng(51.50550, -0.07520))
|
||||||
.zoom(ZOOM_LEVEL)
|
.zoom(ZOOM_LEVEL)
|
||||||
.build();
|
.build();
|
||||||
mapBoxMap.setCameraPosition(cameraPosition);
|
mapBoxMap.setCameraPosition(cameraPosition);
|
||||||
|
|
||||||
ScaleBarPlugin scaleBarPlugin = new ScaleBarPlugin(mapView, mapBoxMap);
|
final ScaleBarPlugin scaleBarPlugin = new ScaleBarPlugin(mapView, mapBoxMap);
|
||||||
int color = isDarkTheme ? R.color.bottom_bar_light : R.color.bottom_bar_dark;
|
final int color = isDarkTheme ? R.color.bottom_bar_light : R.color.bottom_bar_dark;
|
||||||
ScaleBarOptions scaleBarOptions = new ScaleBarOptions(getContext())
|
final ScaleBarOptions scaleBarOptions = new ScaleBarOptions(getContext())
|
||||||
.setTextColor(color)
|
.setTextColor(color)
|
||||||
.setTextSize(R.dimen.description_text_size)
|
.setTextSize(R.dimen.description_text_size)
|
||||||
.setBarHeight(R.dimen.tiny_gap)
|
.setBarHeight(R.dimen.tiny_gap)
|
||||||
|
|
@ -280,8 +281,18 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
|
|
||||||
private void initRvNearbyList() {
|
private void initRvNearbyList() {
|
||||||
rvNearbyList.setLayoutManager(new LinearLayoutManager(getContext()));
|
rvNearbyList.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
adapterFactory = new NearbyAdapterFactory(this, controller);
|
adapter = new PlaceAdapter(bookmarkLocationDao,
|
||||||
rvNearbyList.setAdapter(adapterFactory.create(null));
|
place -> {
|
||||||
|
centerMapToPlace(place);
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
},
|
||||||
|
(place, isBookmarked) -> {
|
||||||
|
updateMarker(isBookmarked, place, null);
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
},
|
||||||
|
commonPlaceClickActions
|
||||||
|
);
|
||||||
|
rvNearbyList.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCheckBoxCallback() {
|
private void addCheckBoxCallback() {
|
||||||
|
|
@ -291,13 +302,13 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
private void performMapReadyActions() {
|
private void performMapReadyActions() {
|
||||||
if (isVisible() && isVisibleToUser && isMapBoxReady) {
|
if (isVisible() && isVisibleToUser && isMapBoxReady) {
|
||||||
checkPermissionsAndPerformAction(() -> {
|
checkPermissionsAndPerformAction(() -> {
|
||||||
this.lastKnownLocation = locationManager.getLastLocation();
|
lastKnownLocation = locationManager.getLastLocation();
|
||||||
fr.free.nrw.commons.location.LatLng target=lastFocusLocation;
|
fr.free.nrw.commons.location.LatLng target=lastFocusLocation;
|
||||||
if(null==lastFocusLocation){
|
if(null==lastFocusLocation){
|
||||||
target=lastKnownLocation;
|
target=lastKnownLocation;
|
||||||
}
|
}
|
||||||
if (lastKnownLocation != null) {
|
if (lastKnownLocation != null) {
|
||||||
CameraPosition position = new CameraPosition.Builder()
|
final CameraPosition position = new CameraPosition.Builder()
|
||||||
.target(LocationUtils.commonsLatLngToMapBoxLatLng(target)) // Sets the new camera position
|
.target(LocationUtils.commonsLatLngToMapBoxLatLng(target)) // Sets the new camera position
|
||||||
.zoom(ZOOM_LEVEL) // Same zoom level
|
.zoom(ZOOM_LEVEL) // Same zoom level
|
||||||
.build();
|
.build();
|
||||||
|
|
@ -324,8 +335,9 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerNetworkReceiver() {
|
private void registerNetworkReceiver() {
|
||||||
if (getActivity() != null)
|
if (getActivity() != null) {
|
||||||
getActivity().registerReceiver(broadcastReceiver, intentFilter);
|
getActivity().registerReceiver(broadcastReceiver, intentFilter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -348,7 +360,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
if (null != mapBox) {
|
if (null != mapBox) {
|
||||||
mapBox.removeOnCameraMoveListener(cameraMoveListener);
|
mapBox.removeOnCameraMoveListener(cameraMoveListener);
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
}catch (final Exception e){
|
||||||
Timber.e(e);
|
Timber.e(e);
|
||||||
//Broadcast receivers should always be unregistered inside catch, you never know if they were already registered or not
|
//Broadcast receivers should always be unregistered inside catch, you never know if they were already registered or not
|
||||||
}
|
}
|
||||||
|
|
@ -361,7 +373,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(final Bundle outState) {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
mapView.onSaveInstanceState(outState);
|
mapView.onSaveInstanceState(outState);
|
||||||
}
|
}
|
||||||
|
|
@ -414,7 +426,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
|
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
|
||||||
DividerItemDecoration.VERTICAL));
|
DividerItemDecoration.VERTICAL));
|
||||||
|
|
||||||
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
|
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
|
||||||
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||||
recyclerView.setLayoutManager(linearLayoutManager);
|
recyclerView.setLayoutManager(linearLayoutManager);
|
||||||
|
|
||||||
|
|
@ -426,7 +438,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void filterByMarkerType(ArrayList<Label> selectedLabels, int i, boolean b, boolean b1) {
|
public void filterByMarkerType(final ArrayList<Label> selectedLabels, final int i, final boolean b, final boolean b1) {
|
||||||
presenter.filterByMarkerType(selectedLabels,i,b,b1);
|
presenter.filterByMarkerType(selectedLabels,i,b,b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -456,7 +468,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCheckBoxState(int state) {
|
public void setCheckBoxState(final int state) {
|
||||||
checkBoxTriStates.setState(state);
|
checkBoxTriStates.setState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -511,12 +523,12 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
bottomSheetDetailsBehavior.setBottomSheetCallback(new BottomSheetBehavior
|
bottomSheetDetailsBehavior.setBottomSheetCallback(new BottomSheetBehavior
|
||||||
.BottomSheetCallback() {
|
.BottomSheetCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onStateChanged(@NonNull View bottomSheet, int newState) {
|
public void onStateChanged(@NonNull final View bottomSheet, final int newState) {
|
||||||
prepareViewsForSheetPosition(newState);
|
prepareViewsForSheetPosition(newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
|
public void onSlide(@NonNull final View bottomSheet, final float slideOffset) {
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -536,14 +548,14 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
bottomSheetListBehavior.setBottomSheetCallback(new BottomSheetBehavior
|
bottomSheetListBehavior.setBottomSheetCallback(new BottomSheetBehavior
|
||||||
.BottomSheetCallback() {
|
.BottomSheetCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onStateChanged(@NonNull View bottomSheet, int newState) {
|
public void onStateChanged(@NonNull final View bottomSheet, final int newState) {
|
||||||
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
|
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||||
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
|
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
|
public void onSlide(@NonNull final View bottomSheet, final float slideOffset) {
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -597,21 +609,21 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
* Centers the map in nearby fragment to a given place
|
* Centers the map in nearby fragment to a given place
|
||||||
* @param place is new center of the map
|
* @param place is new center of the map
|
||||||
*/
|
*/
|
||||||
public void centerMapToPlace(Place place) {
|
public void centerMapToPlace(final Place place) {
|
||||||
Timber.d("Map is centered to place");
|
Timber.d("Map is centered to place");
|
||||||
double cameraShift;
|
final double cameraShift;
|
||||||
if(null!=place){
|
if(null!=place){
|
||||||
lastPlaceToCenter=place;
|
lastPlaceToCenter=place;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null != lastPlaceToCenter) {
|
if (null != lastPlaceToCenter) {
|
||||||
Configuration configuration = getActivity().getResources().getConfiguration();
|
final Configuration configuration = getActivity().getResources().getConfiguration();
|
||||||
if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||||
cameraShift = CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT;
|
cameraShift = CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT;
|
||||||
} else {
|
} else {
|
||||||
cameraShift = CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE;
|
cameraShift = CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE;
|
||||||
}
|
}
|
||||||
CameraPosition position = new CameraPosition.Builder()
|
final CameraPosition position = new CameraPosition.Builder()
|
||||||
.target(LocationUtils.commonsLatLngToMapBoxLatLng(
|
.target(LocationUtils.commonsLatLngToMapBoxLatLng(
|
||||||
new fr.free.nrw.commons.location.LatLng(lastPlaceToCenter.location.getLatitude() - cameraShift,
|
new fr.free.nrw.commons.location.LatLng(lastPlaceToCenter.location.getLatitude() - cameraShift,
|
||||||
lastPlaceToCenter.getLocation().getLongitude(),
|
lastPlaceToCenter.getLocation().getLongitude(),
|
||||||
|
|
@ -623,22 +635,17 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateListFragment(List<Place> placeList) {
|
public void updateListFragment(final List<Place> placeList) {
|
||||||
adapterFactory.updateAdapterData(placeList, (RVRendererAdapter<Place>) rvNearbyList.getAdapter());
|
adapter.setItems(placeList);
|
||||||
noResultsView.setVisibility(placeList.size() <= 0 ? View.VISIBLE : View.GONE);
|
noResultsView.setVisibility(placeList.isEmpty() ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearNearbyList() {
|
public void clearNearbyList() {
|
||||||
adapterFactory.clear((RVRendererAdapter<Place>) rvNearbyList.getAdapter());
|
adapter.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateNearbyList() {
|
public void addPlaceToNearbyList(final Place place) {
|
||||||
adapterFactory.update((RVRendererAdapter<Place>) rvNearbyList.getAdapter());
|
adapter.add(place);
|
||||||
noResultsView.setVisibility(rvNearbyList.getAdapter().getItemCount() <= 0 ? View.VISIBLE : View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPlaceToNearbyList(Place place) {
|
|
||||||
adapterFactory.add(place, (RVRendererAdapter<Place>) rvNearbyList.getAdapter());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -678,7 +685,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
private void initNetworkBroadCastReceiver() {
|
private void initNetworkBroadCastReceiver() {
|
||||||
broadcastReceiver = new BroadcastReceiver() {
|
broadcastReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
if (getActivity() != null) {
|
if (getActivity() != null) {
|
||||||
if (NetworkUtils.isInternetConnectionEstablished(getActivity())) {
|
if (NetworkUtils.isInternetConnectionEstablished(getActivity())) {
|
||||||
if (isNetworkErrorOccurred) {
|
if (isNetworkErrorOccurred) {
|
||||||
|
|
@ -719,10 +726,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void populatePlaces(fr.free.nrw.commons.location.LatLng curlatLng) {
|
public void populatePlaces(final fr.free.nrw.commons.location.LatLng curlatLng) {
|
||||||
if (lastKnownLocation == null) {
|
|
||||||
lastKnownLocation = currentLocation;
|
|
||||||
}
|
|
||||||
if (curlatLng.equals(lastFocusLocation)|| lastFocusLocation==null) { // Means we are checking around current location
|
if (curlatLng.equals(lastFocusLocation)|| lastFocusLocation==null) { // Means we are checking around current location
|
||||||
populatePlacesForCurrentLocation(lastKnownLocation, curlatLng);
|
populatePlacesForCurrentLocation(lastKnownLocation, curlatLng);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -730,8 +734,8 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populatePlacesForCurrentLocation(fr.free.nrw.commons.location.LatLng curlatLng,
|
private void populatePlacesForCurrentLocation(final fr.free.nrw.commons.location.LatLng curlatLng,
|
||||||
fr.free.nrw.commons.location.LatLng searchLatLng) {
|
final fr.free.nrw.commons.location.LatLng searchLatLng) {
|
||||||
compositeDisposable.add(Observable.fromCallable(() -> nearbyController
|
compositeDisposable.add(Observable.fromCallable(() -> nearbyController
|
||||||
.loadAttractionsFromLocation(curlatLng, searchLatLng, false, true))
|
.loadAttractionsFromLocation(curlatLng, searchLatLng, false, true))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
|
|
@ -749,8 +753,8 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populatePlacesForAnotherLocation(fr.free.nrw.commons.location.LatLng curlatLng,
|
private void populatePlacesForAnotherLocation(final fr.free.nrw.commons.location.LatLng curlatLng,
|
||||||
fr.free.nrw.commons.location.LatLng searchLatLng) {
|
final fr.free.nrw.commons.location.LatLng searchLatLng) {
|
||||||
compositeDisposable.add(Observable.fromCallable(() -> nearbyController
|
compositeDisposable.add(Observable.fromCallable(() -> nearbyController
|
||||||
.loadAttractionsFromLocation(curlatLng, searchLatLng, false, false))
|
.loadAttractionsFromLocation(curlatLng, searchLatLng, false, false))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
|
|
@ -772,8 +776,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
* location where you are.
|
* location where you are.
|
||||||
* @param nearbyPlacesInfo This variable has place list information and distances.
|
* @param nearbyPlacesInfo This variable has place list information and distances.
|
||||||
*/
|
*/
|
||||||
private void updateMapMarkers(NearbyController.NearbyPlacesInfo nearbyPlacesInfo,boolean shouldUpdateSelectedMarker) {
|
private void updateMapMarkers(final NearbyController.NearbyPlacesInfo nearbyPlacesInfo, final boolean shouldUpdateSelectedMarker) {
|
||||||
this.nearbyPlacesInfo=nearbyPlacesInfo;
|
|
||||||
presenter.updateMapMarkers(nearbyPlacesInfo, selectedMarker,shouldUpdateSelectedMarker);
|
presenter.updateMapMarkers(nearbyPlacesInfo, selectedMarker,shouldUpdateSelectedMarker);
|
||||||
setFilterState();
|
setFilterState();
|
||||||
}
|
}
|
||||||
|
|
@ -804,7 +807,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSearchThisAreaButtonVisibility(boolean isVisible) {
|
public void setSearchThisAreaButtonVisibility(final boolean isVisible) {
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
searchThisAreaButton.setVisibility(View.VISIBLE);
|
searchThisAreaButton.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -814,11 +817,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSearchThisAreaButtonVisible() {
|
public boolean isSearchThisAreaButtonVisible() {
|
||||||
if (searchThisAreaButton.getVisibility() == View.VISIBLE) {
|
return searchThisAreaButton.getVisibility() == View.VISIBLE;
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -836,7 +835,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setProgressBarVisibility(boolean isVisible) {
|
public void setProgressBarVisibility(final boolean isVisible) {
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
progressBar.setVisibility(View.VISIBLE);
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -850,7 +849,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkPermissionsAndPerformAction(Runnable runnable) {
|
public void checkPermissionsAndPerformAction(final Runnable runnable) {
|
||||||
Timber.d("Checking permission and perfoming action");
|
Timber.d("Checking permission and perfoming action");
|
||||||
PermissionUtils.checkPermissionsAndPerformAction(getActivity(),
|
PermissionUtils.checkPermissionsAndPerformAction(getActivity(),
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
Manifest.permission.ACCESS_FINE_LOCATION,
|
||||||
|
|
@ -885,7 +884,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
* Expands camera and gallery FABs, turn forward plus FAB
|
* Expands camera and gallery FABs, turn forward plus FAB
|
||||||
* @param isFABsExpanded true if they are already expanded
|
* @param isFABsExpanded true if they are already expanded
|
||||||
*/
|
*/
|
||||||
private void expandFABs(boolean isFABsExpanded){
|
private void expandFABs(final boolean isFABsExpanded){
|
||||||
if (!isFABsExpanded) {
|
if (!isFABsExpanded) {
|
||||||
showFABs();
|
showFABs();
|
||||||
fabPlus.startAnimation(rotate_forward);
|
fabPlus.startAnimation(rotate_forward);
|
||||||
|
|
@ -913,7 +912,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
* Collapses camera and gallery FABs, turn back plus FAB
|
* Collapses camera and gallery FABs, turn back plus FAB
|
||||||
* @param isFABsExpanded
|
* @param isFABsExpanded
|
||||||
*/
|
*/
|
||||||
private void collapseFABs(boolean isFABsExpanded){
|
private void collapseFABs(final boolean isFABsExpanded){
|
||||||
if (isFABsExpanded) {
|
if (isFABsExpanded) {
|
||||||
fabPlus.startAnimation(rotate_backward);
|
fabPlus.startAnimation(rotate_backward);
|
||||||
fabCamera.startAnimation(fab_close);
|
fabCamera.startAnimation(fab_close);
|
||||||
|
|
@ -940,19 +939,19 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleLocationUpdate(fr.free.nrw.commons.location.LatLng latLng, LocationServiceManager.LocationChangeType locationChangeType){
|
private void handleLocationUpdate(final fr.free.nrw.commons.location.LatLng latLng, final LocationServiceManager.LocationChangeType locationChangeType){
|
||||||
this.lastKnownLocation = latLng;
|
lastKnownLocation = latLng;
|
||||||
NearbyController.currentLocation = lastKnownLocation;
|
NearbyController.currentLocation = lastKnownLocation;
|
||||||
presenter.updateMapAndList(locationChangeType);
|
presenter.updateMapAndList(locationChangeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isUserBrowsing() {
|
private boolean isUserBrowsing() {
|
||||||
boolean isUserBrowsing = lastKnownLocation!=null && !presenter.areLocationsClose(getCameraTarget(), lastKnownLocation);
|
final boolean isUserBrowsing = lastKnownLocation!=null && !presenter.areLocationsClose(getCameraTarget(), lastKnownLocation);
|
||||||
return isUserBrowsing;
|
return isUserBrowsing;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLocationChangedSignificantly(fr.free.nrw.commons.location.LatLng latLng) {
|
public void onLocationChangedSignificantly(final fr.free.nrw.commons.location.LatLng latLng) {
|
||||||
Timber.d("Location significantly changed");
|
Timber.d("Location significantly changed");
|
||||||
if (isMapBoxReady && latLng != null &&!isUserBrowsing()) {
|
if (isMapBoxReady && latLng != null &&!isUserBrowsing()) {
|
||||||
handleLocationUpdate(latLng,LOCATION_SIGNIFICANTLY_CHANGED);
|
handleLocationUpdate(latLng,LOCATION_SIGNIFICANTLY_CHANGED);
|
||||||
|
|
@ -960,7 +959,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLocationChangedSlightly(fr.free.nrw.commons.location.LatLng latLng) {
|
public void onLocationChangedSlightly(final fr.free.nrw.commons.location.LatLng latLng) {
|
||||||
Timber.d("Location slightly changed");
|
Timber.d("Location slightly changed");
|
||||||
if (isMapBoxReady && latLng != null &&!isUserBrowsing()) {//If the map has never ever shown the current location, lets do it know
|
if (isMapBoxReady && latLng != null &&!isUserBrowsing()) {//If the map has never ever shown the current location, lets do it know
|
||||||
handleLocationUpdate(latLng,LOCATION_SLIGHTLY_CHANGED);
|
handleLocationUpdate(latLng,LOCATION_SLIGHTLY_CHANGED);
|
||||||
|
|
@ -968,7 +967,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLocationChangedMedium(fr.free.nrw.commons.location.LatLng latLng) {
|
public void onLocationChangedMedium(final fr.free.nrw.commons.location.LatLng latLng) {
|
||||||
Timber.d("Location changed medium");
|
Timber.d("Location changed medium");
|
||||||
if (isMapBoxReady && latLng != null && !isUserBrowsing()) {//If the map has never ever shown the current location, lets do it know
|
if (isMapBoxReady && latLng != null && !isUserBrowsing()) {//If the map has never ever shown the current location, lets do it know
|
||||||
handleLocationUpdate(latLng, LOCATION_SIGNIFICANTLY_CHANGED);
|
handleLocationUpdate(latLng, LOCATION_SIGNIFICANTLY_CHANGED);
|
||||||
|
|
@ -986,7 +985,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
@Override
|
@Override
|
||||||
public void onLogoutComplete() {
|
public void onLogoutComplete() {
|
||||||
Timber.d("Logout complete callback received.");
|
Timber.d("Logout complete callback received.");
|
||||||
Intent nearbyIntent = new Intent( getActivity(), LoginActivity.class);
|
final Intent nearbyIntent = new Intent( getActivity(), LoginActivity.class);
|
||||||
nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
startActivity(nearbyIntent);
|
startActivity(nearbyIntent);
|
||||||
|
|
@ -995,12 +994,12 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFABPlusAction(View.OnClickListener onClickListener) {
|
public void setFABPlusAction(final View.OnClickListener onClickListener) {
|
||||||
fabPlus.setOnClickListener(onClickListener);
|
fabPlus.setOnClickListener(onClickListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFABRecenterAction(View.OnClickListener onClickListener) {
|
public void setFABRecenterAction(final View.OnClickListener onClickListener) {
|
||||||
fabRecenter.setOnClickListener(onClickListener);
|
fabRecenter.setOnClickListener(onClickListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1026,27 +1025,27 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
* @param curLatLng current location
|
* @param curLatLng current location
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addCurrentLocationMarker(fr.free.nrw.commons.location.LatLng curLatLng) {
|
public void addCurrentLocationMarker(final fr.free.nrw.commons.location.LatLng curLatLng) {
|
||||||
if (null != curLatLng) {
|
if (null != curLatLng) {
|
||||||
ExecutorUtils.get().submit(() -> {
|
ExecutorUtils.get().submit(() -> {
|
||||||
mapView.post(() -> removeCurrentLocationMarker());
|
mapView.post(() -> removeCurrentLocationMarker());
|
||||||
Timber.d("Adds current location marker");
|
Timber.d("Adds current location marker");
|
||||||
|
|
||||||
Icon icon = IconFactory.getInstance(getContext())
|
final Icon icon = IconFactory.getInstance(getContext())
|
||||||
.fromResource(R.drawable.current_location_marker);
|
.fromResource(R.drawable.current_location_marker);
|
||||||
|
|
||||||
MarkerOptions currentLocationMarkerOptions = new MarkerOptions()
|
final MarkerOptions currentLocationMarkerOptions = new MarkerOptions()
|
||||||
.position(new LatLng(curLatLng.getLatitude(),
|
.position(new LatLng(curLatLng.getLatitude(),
|
||||||
curLatLng.getLongitude()));
|
curLatLng.getLongitude()));
|
||||||
currentLocationMarkerOptions.setIcon(icon); // Set custom icon
|
currentLocationMarkerOptions.setIcon(icon); // Set custom icon
|
||||||
mapView.post(() -> currentLocationMarker = mapBox.addMarker(currentLocationMarkerOptions));
|
mapView.post(() -> currentLocationMarker = mapBox.addMarker(currentLocationMarkerOptions));
|
||||||
|
|
||||||
|
|
||||||
List<LatLng> circle = UiUtils
|
final List<LatLng> circle = UiUtils
|
||||||
.createCircleArray(curLatLng.getLatitude(), curLatLng.getLongitude(),
|
.createCircleArray(curLatLng.getLatitude(), curLatLng.getLongitude(),
|
||||||
curLatLng.getAccuracy() * 2, 100);
|
curLatLng.getAccuracy() * 2, 100);
|
||||||
|
|
||||||
PolygonOptions currentLocationPolygonOptions = new PolygonOptions()
|
final PolygonOptions currentLocationPolygonOptions = new PolygonOptions()
|
||||||
.addAll(circle)
|
.addAll(circle)
|
||||||
.strokeColor(getResources().getColor(R.color.current_marker_stroke))
|
.strokeColor(getResources().getColor(R.color.current_marker_stroke))
|
||||||
.fillColor(getResources().getColor(R.color.current_marker_fill));
|
.fillColor(getResources().getColor(R.color.current_marker_fill));
|
||||||
|
|
@ -1071,9 +1070,9 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
* @param curLatLng current location of user
|
* @param curLatLng current location of user
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updateMapToTrackPosition(fr.free.nrw.commons.location.LatLng curLatLng) {
|
public void updateMapToTrackPosition(final fr.free.nrw.commons.location.LatLng curLatLng) {
|
||||||
Timber.d("Updates map camera to track user position");
|
Timber.d("Updates map camera to track user position");
|
||||||
CameraPosition cameraPosition = new CameraPosition.Builder().target
|
final CameraPosition cameraPosition = new CameraPosition.Builder().target
|
||||||
(LocationUtils.commonsLatLngToMapBoxLatLng(curLatLng)).build();
|
(LocationUtils.commonsLatLngToMapBoxLatLng(curLatLng)).build();
|
||||||
if(null!=mapBox) {
|
if(null!=mapBox) {
|
||||||
mapBox.setCameraPosition(cameraPosition);
|
mapBox.setCameraPosition(cameraPosition);
|
||||||
|
|
@ -1083,7 +1082,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateMapMarkers(List<NearbyBaseMarker> nearbyBaseMarkers, Marker selectedMarker) {
|
public void updateMapMarkers(final List<NearbyBaseMarker> nearbyBaseMarkers, final Marker selectedMarker) {
|
||||||
if(mapBox!=null && isMapBoxReady){
|
if(mapBox!=null && isMapBoxReady){
|
||||||
mapBox.clear();
|
mapBox.clear();
|
||||||
addNearbyMarkersToMapBoxMap(nearbyBaseMarkers, selectedMarker);
|
addNearbyMarkersToMapBoxMap(nearbyBaseMarkers, selectedMarker);
|
||||||
|
|
@ -1096,7 +1095,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
@Override
|
@Override
|
||||||
public void filterOutAllMarkers() {
|
public void filterOutAllMarkers() {
|
||||||
hideAllMarkers();
|
hideAllMarkers();
|
||||||
updateNearbyList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1104,10 +1102,9 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void displayAllMarkers() {
|
public void displayAllMarkers() {
|
||||||
for (MarkerPlaceGroup markerPlaceGroup : NearbyController.markerLabelList) {
|
for (final MarkerPlaceGroup markerPlaceGroup : NearbyController.markerLabelList) {
|
||||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||||
}
|
}
|
||||||
updateNearbyList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1119,17 +1116,17 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
* @param filterForAllNoneType true if we filter places with all none button
|
* @param filterForAllNoneType true if we filter places with all none button
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void filterMarkersByLabels(List<Label> selectedLabels,
|
public void filterMarkersByLabels(final List<Label> selectedLabels,
|
||||||
boolean displayExists,
|
final boolean displayExists,
|
||||||
boolean displayNeedsPhoto,
|
final boolean displayNeedsPhoto,
|
||||||
boolean filterForPlaceState,
|
final boolean filterForPlaceState,
|
||||||
boolean filterForAllNoneType) {
|
final boolean filterForAllNoneType) {
|
||||||
|
|
||||||
// Remove the previous markers before updating them
|
// Remove the previous markers before updating them
|
||||||
hideAllMarkers();
|
hideAllMarkers();
|
||||||
|
|
||||||
for (MarkerPlaceGroup markerPlaceGroup : NearbyController.markerLabelList) {
|
for (final MarkerPlaceGroup markerPlaceGroup : NearbyController.markerLabelList) {
|
||||||
Place place = markerPlaceGroup.getPlace();
|
final Place place = markerPlaceGroup.getPlace();
|
||||||
|
|
||||||
// When label filter is engaged
|
// When label filter is engaged
|
||||||
// then compare it against place's label
|
// then compare it against place's label
|
||||||
|
|
@ -1159,7 +1156,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
updateMarker(markerPlaceGroup.getIsBookmarked(), place, NearbyController.currentLocation);
|
updateMarker(markerPlaceGroup.getIsBookmarked(), place, NearbyController.currentLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateNearbyList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -1173,7 +1169,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
* @param place
|
* @param place
|
||||||
* @param curLatLng current location
|
* @param curLatLng current location
|
||||||
*/
|
*/
|
||||||
public void updateMarker(boolean isBookmarked, Place place, @Nullable fr.free.nrw.commons.location.LatLng curLatLng) {
|
public void updateMarker(final boolean isBookmarked, final Place place, @Nullable final fr.free.nrw.commons.location.LatLng curLatLng) {
|
||||||
addPlaceToNearbyList(place);
|
addPlaceToNearbyList(place);
|
||||||
|
|
||||||
VectorDrawableCompat vectorDrawable = VectorDrawableCompat.create(
|
VectorDrawableCompat vectorDrawable = VectorDrawableCompat.create(
|
||||||
|
|
@ -1182,13 +1178,13 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
for (Marker marker : mapBox.getMarkers()) {
|
for (Marker marker : mapBox.getMarkers()) {
|
||||||
if (marker.getTitle() != null && marker.getTitle().equals(place.getName())) {
|
if (marker.getTitle() != null && marker.getTitle().equals(place.getName())) {
|
||||||
|
|
||||||
Bitmap icon = UiUtils.getBitmap(vectorDrawable);
|
final Bitmap icon = UiUtils.getBitmap(vectorDrawable);
|
||||||
if (curLatLng != null) {
|
if (curLatLng != null) {
|
||||||
String distance = formatDistanceBetween(curLatLng, place.location);
|
final String distance = formatDistanceBetween(curLatLng, place.location);
|
||||||
place.setDistance(distance);
|
place.setDistance(distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
NearbyBaseMarker nearbyBaseMarker = new NearbyBaseMarker();
|
final NearbyBaseMarker nearbyBaseMarker = new NearbyBaseMarker();
|
||||||
nearbyBaseMarker.title(place.name);
|
nearbyBaseMarker.title(place.name);
|
||||||
nearbyBaseMarker.position(
|
nearbyBaseMarker.position(
|
||||||
new com.mapbox.mapboxsdk.geometry.LatLng(
|
new com.mapbox.mapboxsdk.geometry.LatLng(
|
||||||
|
|
@ -1224,11 +1220,11 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
* since grey icon may lead the users to believe that it is disabled or prohibited contribution
|
* since grey icon may lead the users to believe that it is disabled or prohibited contribution
|
||||||
*/
|
*/
|
||||||
private void hideAllMarkers() {
|
private void hideAllMarkers() {
|
||||||
VectorDrawableCompat vectorDrawable;
|
final VectorDrawableCompat vectorDrawable;
|
||||||
vectorDrawable = VectorDrawableCompat.create(
|
vectorDrawable = VectorDrawableCompat.create(
|
||||||
getContext().getResources(), R.drawable.ic_custom_greyed_out_marker, getContext().getTheme());
|
getContext().getResources(), R.drawable.ic_custom_greyed_out_marker, getContext().getTheme());
|
||||||
Bitmap icon = UiUtils.getBitmap(vectorDrawable);
|
final Bitmap icon = UiUtils.getBitmap(vectorDrawable);
|
||||||
for (Marker marker : mapBox.getMarkers()) {
|
for (final Marker marker : mapBox.getMarkers()) {
|
||||||
if (!marker.equals(currentLocationMarker)) {
|
if (!marker.equals(currentLocationMarker)) {
|
||||||
marker.setIcon(IconFactory.getInstance(getContext()).fromBitmap(icon));
|
marker.setIcon(IconFactory.getInstance(getContext()).fromBitmap(icon));
|
||||||
}
|
}
|
||||||
|
|
@ -1237,7 +1233,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
clearNearbyList();
|
clearNearbyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addNearbyMarkersToMapBoxMap(List<NearbyBaseMarker> nearbyBaseMarkers, Marker selectedMarker) {
|
private void addNearbyMarkersToMapBoxMap(final List<NearbyBaseMarker> nearbyBaseMarkers, final Marker selectedMarker) {
|
||||||
if (isMapBoxReady && mapBox != null) {
|
if (isMapBoxReady && mapBox != null) {
|
||||||
mapBox.addMarkers(nearbyBaseMarkers);
|
mapBox.addMarkers(nearbyBaseMarkers);
|
||||||
setMapMarkerActions(selectedMarker);
|
setMapMarkerActions(selectedMarker);
|
||||||
|
|
@ -1245,7 +1241,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMapMarkerActions(Marker selectedMarker) {
|
private void setMapMarkerActions(final Marker selectedMarker) {
|
||||||
if (mapBox != null) {
|
if (mapBox != null) {
|
||||||
mapBox.setOnInfoWindowCloseListener(marker -> {
|
mapBox.setOnInfoWindowCloseListener(marker -> {
|
||||||
if (marker == selectedMarker) {
|
if (marker == selectedMarker) {
|
||||||
|
|
@ -1263,7 +1259,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recenterMap(fr.free.nrw.commons.location.LatLng curLatLng) {
|
public void recenterMap(final fr.free.nrw.commons.location.LatLng curLatLng) {
|
||||||
if (curLatLng == null) {
|
if (curLatLng == null) {
|
||||||
if (!(locationManager.isNetworkProviderEnabled() || locationManager.isGPSProviderEnabled())) {
|
if (!(locationManager.isNetworkProviderEnabled() || locationManager.isGPSProviderEnabled())) {
|
||||||
showLocationOffDialog();
|
showLocationOffDialog();
|
||||||
|
|
@ -1271,7 +1267,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addCurrentLocationMarker(curLatLng);
|
addCurrentLocationMarker(curLatLng);
|
||||||
CameraPosition position;
|
final CameraPosition position;
|
||||||
|
|
||||||
if (ViewUtil.isPortrait(getActivity())) {
|
if (ViewUtil.isPortrait(getActivity())) {
|
||||||
position = new CameraPosition.Builder()
|
position = new CameraPosition.Builder()
|
||||||
|
|
@ -1309,8 +1305,8 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
@Override
|
@Override
|
||||||
public void openLocationSettings() {
|
public void openLocationSettings() {
|
||||||
// This method opens the location settings of the device along with a followup toast.
|
// This method opens the location settings of the device along with a followup toast.
|
||||||
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
final Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||||
PackageManager packageManager = getActivity().getPackageManager();
|
final PackageManager packageManager = getActivity().getPackageManager();
|
||||||
|
|
||||||
if (intent.resolveActivity(packageManager)!= null) {
|
if (intent.resolveActivity(packageManager)!= null) {
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
|
@ -1331,10 +1327,10 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void displayBottomSheetWithInfo(Marker marker) {
|
public void displayBottomSheetWithInfo(final Marker marker) {
|
||||||
this.selectedMarker = marker;
|
selectedMarker = marker;
|
||||||
NearbyMarker nearbyMarker = (NearbyMarker) marker;
|
final NearbyMarker nearbyMarker = (NearbyMarker) marker;
|
||||||
Place place = nearbyMarker.getNearbyBaseMarker().getPlace();
|
final Place place = nearbyMarker.getNearbyBaseMarker().getPlace();
|
||||||
passInfoToSheet(place);
|
passInfoToSheet(place);
|
||||||
hideBottomSheet();
|
hideBottomSheet();
|
||||||
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
||||||
|
|
@ -1351,16 +1347,18 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
* If nearby details bottom sheet state is hidden: hide all fabs
|
* If nearby details bottom sheet state is hidden: hide all fabs
|
||||||
* @param bottomSheetState see bottom sheet states
|
* @param bottomSheetState see bottom sheet states
|
||||||
*/
|
*/
|
||||||
public void prepareViewsForSheetPosition(int bottomSheetState) {
|
public void prepareViewsForSheetPosition(final int bottomSheetState) {
|
||||||
|
|
||||||
switch (bottomSheetState) {
|
switch (bottomSheetState) {
|
||||||
case (BottomSheetBehavior.STATE_COLLAPSED):
|
case (BottomSheetBehavior.STATE_COLLAPSED):
|
||||||
collapseFABs(isFABsExpanded);
|
collapseFABs(isFABsExpanded);
|
||||||
if (!fabPlus.isShown()) showFABs();
|
if (!fabPlus.isShown()) {
|
||||||
this.getView().requestFocus();
|
showFABs();
|
||||||
|
}
|
||||||
|
getView().requestFocus();
|
||||||
break;
|
break;
|
||||||
case (BottomSheetBehavior.STATE_EXPANDED):
|
case (BottomSheetBehavior.STATE_EXPANDED):
|
||||||
this.getView().requestFocus();
|
getView().requestFocus();
|
||||||
break;
|
break;
|
||||||
case (BottomSheetBehavior.STATE_HIDDEN):
|
case (BottomSheetBehavior.STATE_HIDDEN):
|
||||||
if (null != mapBox) {
|
if (null != mapBox) {
|
||||||
|
|
@ -1370,8 +1368,8 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
transparentView.setAlpha(0);
|
transparentView.setAlpha(0);
|
||||||
collapseFABs(isFABsExpanded);
|
collapseFABs(isFABsExpanded);
|
||||||
hideFABs();
|
hideFABs();
|
||||||
if (this.getView() != null) {
|
if (getView() != null) {
|
||||||
this.getView().requestFocus();
|
getView().requestFocus();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1382,36 +1380,37 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
* (title, description, distance and links) to view on nearby marker click
|
* (title, description, distance and links) to view on nearby marker click
|
||||||
* @param place Place of clicked nearby marker
|
* @param place Place of clicked nearby marker
|
||||||
*/
|
*/
|
||||||
private void passInfoToSheet(Place place) {
|
private void passInfoToSheet(final Place place) {
|
||||||
this.selectedPlace = place;
|
selectedPlace = place;
|
||||||
updateBookmarkButtonImage(this.selectedPlace);
|
updateBookmarkButtonImage(selectedPlace);
|
||||||
|
|
||||||
bookmarkButton.setOnClickListener(view -> {
|
bookmarkButton.setOnClickListener(view -> {
|
||||||
boolean isBookmarked = bookmarkLocationDao.updateBookmarkLocation(this.selectedPlace);
|
final boolean isBookmarked = bookmarkLocationDao.updateBookmarkLocation(selectedPlace);
|
||||||
updateBookmarkButtonImage(this.selectedPlace);
|
updateBookmarkButtonImage(selectedPlace);
|
||||||
updateMarker(isBookmarked, this.selectedPlace, locationManager.getLastLocation());
|
updateMarker(isBookmarked, selectedPlace, locationManager.getLastLocation());
|
||||||
});
|
});
|
||||||
|
|
||||||
wikipediaButton.setVisibility(place.hasWikipediaLink()?View.VISIBLE:View.GONE);
|
wikipediaButton.setVisibility(place.hasWikipediaLink()?View.VISIBLE:View.GONE);
|
||||||
wikipediaButton.setOnClickListener(view -> Utils.handleWebUrl(getContext(), this.selectedPlace.siteLinks.getWikipediaLink()));
|
wikipediaButton.setOnClickListener(view -> Utils.handleWebUrl(getContext(), selectedPlace.siteLinks.getWikipediaLink()));
|
||||||
|
|
||||||
wikidataButton.setVisibility(place.hasWikidataLink()?View.VISIBLE:View.GONE);
|
wikidataButton.setVisibility(place.hasWikidataLink()?View.VISIBLE:View.GONE);
|
||||||
wikidataButton.setOnClickListener(view -> Utils.handleWebUrl(getContext(), this.selectedPlace.siteLinks.getWikidataLink()));
|
wikidataButton.setOnClickListener(view -> Utils.handleWebUrl(getContext(), selectedPlace.siteLinks.getWikidataLink()));
|
||||||
|
|
||||||
directionsButton.setOnClickListener(view -> Utils.handleGeoCoordinates(getActivity(), this.selectedPlace.getLocation()));
|
directionsButton.setOnClickListener(view -> Utils.handleGeoCoordinates(getActivity(),
|
||||||
|
selectedPlace.getLocation()));
|
||||||
|
|
||||||
commonsButton.setVisibility(this.selectedPlace.hasCommonsLink()?View.VISIBLE:View.GONE);
|
commonsButton.setVisibility(selectedPlace.hasCommonsLink()?View.VISIBLE:View.GONE);
|
||||||
commonsButton.setOnClickListener(view -> Utils.handleWebUrl(getContext(), this.selectedPlace.siteLinks.getCommonsLink()));
|
commonsButton.setOnClickListener(view -> Utils.handleWebUrl(getContext(), selectedPlace.siteLinks.getCommonsLink()));
|
||||||
|
|
||||||
icon.setImageResource(this.selectedPlace.getLabel().getIcon());
|
icon.setImageResource(selectedPlace.getLabel().getIcon());
|
||||||
|
|
||||||
title.setText(this.selectedPlace.name);
|
title.setText(selectedPlace.name);
|
||||||
distance.setText(this.selectedPlace.distance);
|
distance.setText(selectedPlace.distance);
|
||||||
description.setText(this.selectedPlace.getLongDescription());
|
description.setText(selectedPlace.getLongDescription());
|
||||||
|
|
||||||
fabCamera.setOnClickListener(view -> {
|
fabCamera.setOnClickListener(view -> {
|
||||||
if (fabCamera.isShown()) {
|
if (fabCamera.isShown()) {
|
||||||
Timber.d("Camera button tapped. Place: %s", this.selectedPlace.toString());
|
Timber.d("Camera button tapped. Place: %s", selectedPlace.toString());
|
||||||
storeSharedPrefs(selectedPlace);
|
storeSharedPrefs(selectedPlace);
|
||||||
controller.initiateCameraPick(getActivity());
|
controller.initiateCameraPick(getActivity());
|
||||||
}
|
}
|
||||||
|
|
@ -1419,20 +1418,20 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
|
|
||||||
fabGallery.setOnClickListener(view -> {
|
fabGallery.setOnClickListener(view -> {
|
||||||
if (fabGallery.isShown()) {
|
if (fabGallery.isShown()) {
|
||||||
Timber.d("Gallery button tapped. Place: %s", this.selectedPlace.toString());
|
Timber.d("Gallery button tapped. Place: %s", selectedPlace.toString());
|
||||||
storeSharedPrefs(selectedPlace);
|
storeSharedPrefs(selectedPlace);
|
||||||
controller.initiateGalleryPick(getActivity(), false);
|
controller.initiateGalleryPick(getActivity(), false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void storeSharedPrefs(Place selectedPlace) {
|
private void storeSharedPrefs(final Place selectedPlace) {
|
||||||
Timber.d("Store place object %s", selectedPlace.toString());
|
Timber.d("Store place object %s", selectedPlace.toString());
|
||||||
applicationKvStore.putJson(PLACE_OBJECT, selectedPlace);
|
applicationKvStore.putJson(PLACE_OBJECT, selectedPlace);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBookmarkButtonImage(Place place) {
|
private void updateBookmarkButtonImage(final Place place) {
|
||||||
int bookmarkIcon;
|
final int bookmarkIcon;
|
||||||
if (bookmarkLocationDao.findBookmarkLocation(place)) {
|
if (bookmarkLocationDao.findBookmarkLocation(place)) {
|
||||||
bookmarkIcon = R.drawable.ic_round_star_filled_24px;
|
bookmarkIcon = R.drawable.ic_round_star_filled_24px;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1444,7 +1443,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(final Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
wikidataEditListener.setAuthenticationStateListener(this);
|
wikidataEditListener.setAuthenticationStateListener(this);
|
||||||
}
|
}
|
||||||
|
|
@ -1462,11 +1461,11 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showErrorMessage(String message) {
|
private void showErrorMessage(final String message) {
|
||||||
ViewUtil.showLongToast(getActivity(), message);
|
ViewUtil.showLongToast(getActivity(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerUnregisterLocationListener(boolean removeLocationListener) {
|
public void registerUnregisterLocationListener(final boolean removeLocationListener) {
|
||||||
try {
|
try {
|
||||||
if (removeLocationListener) {
|
if (removeLocationListener) {
|
||||||
locationManager.unregisterLocationManager();
|
locationManager.unregisterLocationManager();
|
||||||
|
|
@ -1477,14 +1476,14 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
locationManager.registerLocationManager();
|
locationManager.registerLocationManager();
|
||||||
Timber.d("Location service manager added and registered");
|
Timber.d("Location service manager added and registered");
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
}catch (final Exception e){
|
||||||
Timber.e(e);
|
Timber.e(e);
|
||||||
//Broadcasts are tricky, should be catchedonR
|
//Broadcasts are tricky, should be catchedonR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUserVisibleHint(boolean isVisibleToUser) {
|
public void setUserVisibleHint(final boolean isVisibleToUser) {
|
||||||
super.setUserVisibleHint(isVisibleToUser);
|
super.setUserVisibleHint(isVisibleToUser);
|
||||||
this.isVisibleToUser=isVisibleToUser;
|
this.isVisibleToUser=isVisibleToUser;
|
||||||
if (isResumed() && isVisibleToUser) {
|
if (isResumed() && isVisibleToUser) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package fr.free.nrw.commons.nearby.fragments
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao
|
||||||
|
import fr.free.nrw.commons.nearby.Place
|
||||||
|
import fr.free.nrw.commons.nearby.placeAdapterDelegate
|
||||||
|
import fr.free.nrw.commons.upload.categories.BaseDelegateAdapter
|
||||||
|
|
||||||
|
class PlaceAdapter(
|
||||||
|
bookmarkLocationsDao: BookmarkLocationsDao,
|
||||||
|
onPlaceClicked: ((Place) -> Unit)? = null,
|
||||||
|
onBookmarkClicked: (Place, Boolean) -> Unit,
|
||||||
|
commonPlaceClickActions: CommonPlaceClickActions
|
||||||
|
) :
|
||||||
|
BaseDelegateAdapter<Place>(
|
||||||
|
placeAdapterDelegate(
|
||||||
|
bookmarkLocationsDao,
|
||||||
|
onPlaceClicked,
|
||||||
|
commonPlaceClickActions.onCameraClicked(),
|
||||||
|
commonPlaceClickActions.onGalleryClicked(),
|
||||||
|
onBookmarkClicked,
|
||||||
|
commonPlaceClickActions.onOverflowClicked(),
|
||||||
|
commonPlaceClickActions.onDirectionsClicked()
|
||||||
|
),
|
||||||
|
areItemsTheSame = {oldItem, newItem -> oldItem.wikiDataEntityId == newItem.wikiDataEntityId }
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package fr.free.nrw.commons.notification
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.upload.categories.BaseDelegateAdapter
|
||||||
|
|
||||||
|
internal class NotificatinAdapter(onNotificationClicked: (Notification) -> Unit) :
|
||||||
|
BaseDelegateAdapter<Notification>(
|
||||||
|
notificationDelegate(onNotificationClicked),
|
||||||
|
areItemsTheSame = { oldItem, newItem -> oldItem.notificationId == newItem.notificationId }
|
||||||
|
)
|
||||||
|
|
@ -11,16 +11,6 @@ data class Notification(var notificationType: NotificationType,
|
||||||
var link: String,
|
var link: String,
|
||||||
var iconUrl: String,
|
var iconUrl: String,
|
||||||
var notificationId: String) {
|
var notificationId: String) {
|
||||||
override fun toString(): String {
|
|
||||||
return "Notification" +
|
|
||||||
"notificationType='" + notificationType + '\'' +
|
|
||||||
", notificationText='" + notificationText + '\'' +
|
|
||||||
", date='" + date + '\'' +
|
|
||||||
", link='" + link + '\'' +
|
|
||||||
", iconUrl='" + iconUrl + '\'' +
|
|
||||||
", notificationId='" + notificationId + '\'' +
|
|
||||||
'}'
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
|
|
||||||
|
|
@ -13,23 +13,13 @@ import android.widget.ProgressBar;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.Utils;
|
import fr.free.nrw.commons.Utils;
|
||||||
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
||||||
|
|
@ -40,6 +30,11 @@ import io.reactivex.ObservableSource;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.Disposable;
|
import io.reactivex.disposables.Disposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import kotlin.Unit;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -47,7 +42,6 @@ import timber.log.Timber;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class NotificationActivity extends NavigationBaseActivity {
|
public class NotificationActivity extends NavigationBaseActivity {
|
||||||
NotificationAdapterFactory notificationAdapterFactory;
|
|
||||||
@BindView(R.id.listView)
|
@BindView(R.id.listView)
|
||||||
RecyclerView recyclerView;
|
RecyclerView recyclerView;
|
||||||
@BindView(R.id.progressBar)
|
@BindView(R.id.progressBar)
|
||||||
|
|
@ -64,7 +58,7 @@ public class NotificationActivity extends NavigationBaseActivity {
|
||||||
|
|
||||||
private static final String TAG_NOTIFICATION_WORKER_FRAGMENT = "NotificationWorkerFragment";
|
private static final String TAG_NOTIFICATION_WORKER_FRAGMENT = "NotificationWorkerFragment";
|
||||||
private NotificationWorkerFragment mNotificationWorkerFragment;
|
private NotificationWorkerFragment mNotificationWorkerFragment;
|
||||||
private RVRendererAdapter<Notification> adapter;
|
private NotificatinAdapter adapter;
|
||||||
private List<Notification> notificationList;
|
private List<Notification> notificationList;
|
||||||
MenuItem notificationMenuItem;
|
MenuItem notificationMenuItem;
|
||||||
|
|
||||||
|
|
@ -89,7 +83,7 @@ public class NotificationActivity extends NavigationBaseActivity {
|
||||||
.subscribe(result -> {
|
.subscribe(result -> {
|
||||||
if (result) {
|
if (result) {
|
||||||
notificationList.remove(notification);
|
notificationList.remove(notification);
|
||||||
setAdapter(notificationList);
|
setItems(notificationList);
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
Snackbar snackbar = Snackbar
|
Snackbar snackbar = Snackbar
|
||||||
.make(relativeLayout, getString(R.string.notification_mark_read), Snackbar.LENGTH_LONG);
|
.make(relativeLayout, getString(R.string.notification_mark_read), Snackbar.LENGTH_LONG);
|
||||||
|
|
@ -102,7 +96,7 @@ public class NotificationActivity extends NavigationBaseActivity {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
setAdapter(notificationList);
|
setItems(notificationList);
|
||||||
Toast.makeText(NotificationActivity.this, getString(R.string.some_error), Toast.LENGTH_SHORT).show();
|
Toast.makeText(NotificationActivity.this, getString(R.string.some_error), Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}, throwable -> {
|
}, throwable -> {
|
||||||
|
|
@ -126,6 +120,13 @@ public class NotificationActivity extends NavigationBaseActivity {
|
||||||
} else {
|
} else {
|
||||||
refresh(false);
|
refresh(false);
|
||||||
}
|
}
|
||||||
|
adapter = new NotificatinAdapter(item -> {
|
||||||
|
Timber.d("Notification clicked %s", item.getLink());
|
||||||
|
handleUrl(item.getLink());
|
||||||
|
removeNotification(item);
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
|
recyclerView.setAdapter(this.adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refresh(boolean archived) {
|
private void refresh(boolean archived) {
|
||||||
|
|
@ -158,7 +159,7 @@ public class NotificationActivity extends NavigationBaseActivity {
|
||||||
relativeLayout.setVisibility(View.GONE);
|
relativeLayout.setVisibility(View.GONE);
|
||||||
no_notification.setVisibility(View.VISIBLE);
|
no_notification.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
setAdapter(notificationList);
|
setItems(notificationList);
|
||||||
}
|
}
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.GONE);
|
||||||
}, throwable -> {
|
}, throwable -> {
|
||||||
|
|
@ -168,7 +169,7 @@ public class NotificationActivity extends NavigationBaseActivity {
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
notificationList = mNotificationWorkerFragment.getNotificationList();
|
notificationList = mNotificationWorkerFragment.getNotificationList();
|
||||||
setAdapter(notificationList);
|
setItems(notificationList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,7 +205,7 @@ public class NotificationActivity extends NavigationBaseActivity {
|
||||||
Utils.handleWebUrl(this, Uri.parse(url));
|
Utils.handleWebUrl(this, Uri.parse(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setAdapter(List<Notification> notificationList) {
|
private void setItems(List<Notification> notificationList) {
|
||||||
if (notificationList == null || notificationList.isEmpty()) {
|
if (notificationList == null || notificationList.isEmpty()) {
|
||||||
ViewUtil.showShortSnackbar(relativeLayout, R.string.no_notifications);
|
ViewUtil.showShortSnackbar(relativeLayout, R.string.no_notifications);
|
||||||
/*progressBar.setVisibility(View.GONE);
|
/*progressBar.setVisibility(View.GONE);
|
||||||
|
|
@ -214,32 +215,9 @@ public class NotificationActivity extends NavigationBaseActivity {
|
||||||
no_notification.setVisibility(View.VISIBLE);
|
no_notification.setVisibility(View.VISIBLE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isarchivedvisible;
|
|
||||||
if (getIntent().getStringExtra("title").equals("read")) {
|
|
||||||
isarchivedvisible = true;
|
|
||||||
} else {
|
|
||||||
isarchivedvisible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
notificationAdapterFactory = new NotificationAdapterFactory(new NotificationRenderer.NotificationClicked() {
|
|
||||||
@Override
|
|
||||||
public void notificationClicked(Notification notification) {
|
|
||||||
Timber.d("Notification clicked %s", notification.getLink());
|
|
||||||
handleUrl(notification.getLink());
|
|
||||||
removeNotification(notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void markNotificationAsRead(Notification notification) {
|
|
||||||
Timber.d("Notification to mark as read %s", notification.getNotificationId());
|
|
||||||
removeNotification(notification);
|
|
||||||
}
|
|
||||||
}, isarchivedvisible);
|
|
||||||
adapter = notificationAdapterFactory.create(notificationList);
|
|
||||||
relativeLayout.setVisibility(View.VISIBLE);
|
relativeLayout.setVisibility(View.VISIBLE);
|
||||||
no_notification.setVisibility(View.GONE);
|
no_notification.setVisibility(View.GONE);
|
||||||
recyclerView.setAdapter(adapter);
|
adapter.setItems(notificationList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void startYourself(Context context, String title) {
|
public static void startYourself(Context context, String title) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package fr.free.nrw.commons.notification
|
||||||
|
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer
|
||||||
|
import fr.free.nrw.commons.R
|
||||||
|
import kotlinx.android.synthetic.main.activity_login.title
|
||||||
|
import kotlinx.android.synthetic.main.item_notification.*
|
||||||
|
import org.wikipedia.util.StringUtil
|
||||||
|
|
||||||
|
|
||||||
|
fun notificationDelegate(onNotificationClicked: (Notification) -> Unit) =
|
||||||
|
adapterDelegateLayoutContainer<Notification, Notification>(R.layout.item_notification) {
|
||||||
|
containerView.setOnClickListener { onNotificationClicked(item) }
|
||||||
|
bind {
|
||||||
|
title.text = item.processedNotificationText
|
||||||
|
time.text = item.date
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private val Notification.processedNotificationText: CharSequence
|
||||||
|
get() = notificationText.trim()
|
||||||
|
.replace("(^\\s*)|(\\s*$)".toRegex(), "")
|
||||||
|
.let { StringUtil.fromHtml(it).toString() }
|
||||||
|
.let { if (it.length > 280) "${it.substring(0, 279)}..." else it } + " "
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
package fr.free.nrw.commons.notification;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.ListAdapteeCollection;
|
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import com.pedrogomez.renderers.RendererBuilder;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by root on 19.12.2017.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class NotificationAdapterFactory {
|
|
||||||
private NotificationRenderer.NotificationClicked listener;
|
|
||||||
private boolean isarchivedvisible = false;
|
|
||||||
|
|
||||||
NotificationAdapterFactory(@NonNull NotificationRenderer.NotificationClicked listener, boolean isarchivedvisible) {
|
|
||||||
this.listener = listener;
|
|
||||||
this.isarchivedvisible = isarchivedvisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RVRendererAdapter<Notification> create(List<Notification> notifications) {
|
|
||||||
RendererBuilder<Notification> builder = new RendererBuilder<Notification>()
|
|
||||||
.bind(Notification.class, new NotificationRenderer(listener, isarchivedvisible));
|
|
||||||
ListAdapteeCollection<Notification> collection = new ListAdapteeCollection<>(
|
|
||||||
notifications != null ? notifications : Collections.<Notification>emptyList());
|
|
||||||
return new RVRendererAdapter<>(builder, collection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
package fr.free.nrw.commons.notification;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.Renderer;
|
|
||||||
|
|
||||||
import org.wikipedia.util.StringUtil;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import butterknife.OnClick;
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by root on 19.12.2017.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class NotificationRenderer extends Renderer<Notification> {
|
|
||||||
@BindView(R.id.title)
|
|
||||||
TextView title;
|
|
||||||
@BindView(R.id.time)
|
|
||||||
TextView time;
|
|
||||||
@BindView(R.id.icon)
|
|
||||||
ImageView icon;
|
|
||||||
/*@BindView(R.id.bottom)
|
|
||||||
LinearLayout bottomLayout;*/
|
|
||||||
|
|
||||||
private NotificationClicked listener;
|
|
||||||
private boolean isarchivedvisible = false;
|
|
||||||
|
|
||||||
|
|
||||||
NotificationRenderer(NotificationClicked listener, boolean isarchivedvisible) {
|
|
||||||
this.listener = listener;
|
|
||||||
this.isarchivedvisible = isarchivedvisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.notification_view)
|
|
||||||
void onNotificationClicked() {
|
|
||||||
listener.notificationClicked(getContent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUpView(View rootView) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void hookListeners(View rootView) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View inflate(LayoutInflater layoutInflater, ViewGroup viewGroup) {
|
|
||||||
View inflatedView = layoutInflater.inflate(R.layout.item_notification, viewGroup, false);
|
|
||||||
ButterKnife.bind(this, inflatedView);
|
|
||||||
return inflatedView;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render() {
|
|
||||||
Notification notification = getContent();
|
|
||||||
setTitle(notification.getNotificationText());
|
|
||||||
time.setText(notification.getDate());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cleans up the notification text and sets it as the title
|
|
||||||
* Clean up is required to fix escaped HTML string and extra white spaces at the beginning of the notification
|
|
||||||
*
|
|
||||||
* @param notificationText
|
|
||||||
*/
|
|
||||||
private void setTitle(String notificationText) {
|
|
||||||
notificationText = notificationText.trim().replaceAll("(^\\s*)|(\\s*$)", "");
|
|
||||||
notificationText = StringUtil.fromHtml(notificationText).toString();
|
|
||||||
if (notificationText.length() > 280) {
|
|
||||||
notificationText = notificationText.substring(0, 279);
|
|
||||||
notificationText = notificationText.concat("...");
|
|
||||||
}
|
|
||||||
notificationText = notificationText.concat(" ");
|
|
||||||
title.setText(notificationText);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface NotificationClicked {
|
|
||||||
void notificationClicked(Notification notification);
|
|
||||||
void markNotificationAsRead(Notification notification);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
package fr.free.nrw.commons.upload;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.ListAdapteeCollection;
|
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import com.pedrogomez.renderers.RendererBuilder;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.category.CategoryClickedListener;
|
|
||||||
import fr.free.nrw.commons.category.CategoryItem;
|
|
||||||
|
|
||||||
public class UploadCategoriesAdapterFactory {
|
|
||||||
private final CategoryClickedListener listener;
|
|
||||||
|
|
||||||
public UploadCategoriesAdapterFactory(CategoryClickedListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RVRendererAdapter<CategoryItem> create(List<CategoryItem> placeList) {
|
|
||||||
RendererBuilder<CategoryItem> builder = new RendererBuilder<CategoryItem>()
|
|
||||||
.bind(CategoryItem.class, new UploadCategoriesRenderer(listener));
|
|
||||||
ListAdapteeCollection<CategoryItem> collection = new ListAdapteeCollection<>(
|
|
||||||
placeList != null ? placeList : Collections.emptyList());
|
|
||||||
return new RVRendererAdapter<>(builder, collection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
package fr.free.nrw.commons.upload;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.CheckBox;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.Renderer;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
import fr.free.nrw.commons.category.CategoryClickedListener;
|
|
||||||
import fr.free.nrw.commons.category.CategoryItem;
|
|
||||||
|
|
||||||
public class UploadCategoriesRenderer extends Renderer<CategoryItem> {
|
|
||||||
@BindView(R.id.tvName) CheckBox checkedView;
|
|
||||||
private final CategoryClickedListener listener;
|
|
||||||
|
|
||||||
UploadCategoriesRenderer(CategoryClickedListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View inflate(LayoutInflater layoutInflater, ViewGroup viewGroup) {
|
|
||||||
return layoutInflater.inflate(R.layout.layout_upload_categories_item, viewGroup, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUpView(View view) {
|
|
||||||
ButterKnife.bind(this, view);
|
|
||||||
Configuration config = getContext().getResources().getConfiguration();
|
|
||||||
if (config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
|
|
||||||
checkedView.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("WrongConstant")
|
|
||||||
@Override
|
|
||||||
protected void hookListeners(View view) {
|
|
||||||
view.setOnClickListener(v -> {
|
|
||||||
CategoryItem item = getContent();
|
|
||||||
item.setSelected(!item.isSelected());
|
|
||||||
checkedView.setChecked(item.isSelected());
|
|
||||||
if (listener != null) {
|
|
||||||
listener.categoryClicked(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render() {
|
|
||||||
CategoryItem item = getContent();
|
|
||||||
checkedView.setChecked(item.isSelected());
|
|
||||||
checkedView.setText(item.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
package fr.free.nrw.commons.upload;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.ListAdapteeCollection;
|
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import com.pedrogomez.renderers.RendererBuilder;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.UploadDepictsCallback;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapter Factory for DepictsClicked Listener
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class UploadDepictsAdapterFactory {
|
|
||||||
private final UploadDepictsCallback listener;
|
|
||||||
|
|
||||||
public UploadDepictsAdapterFactory(UploadDepictsCallback listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RVRendererAdapter<DepictedItem> create(List<DepictedItem> itemList) {
|
|
||||||
RendererBuilder<DepictedItem> builder = new RendererBuilder<DepictedItem>()
|
|
||||||
.bind(DepictedItem.class, new UploadDepictsRenderer(listener));
|
|
||||||
ListAdapteeCollection<DepictedItem> collection = new ListAdapteeCollection<>(
|
|
||||||
itemList != null ? itemList : Collections.emptyList());
|
|
||||||
return new RVRendererAdapter<>(builder, collection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
package fr.free.nrw.commons.upload;
|
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import com.facebook.common.util.UriUtil;
|
|
||||||
import com.facebook.drawee.view.SimpleDraweeView;
|
|
||||||
import com.pedrogomez.renderers.Renderer;
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.UploadDepictsCallback;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Depicts Renderer for setting up inflating layout,
|
|
||||||
* and setting views for the layout of each depicted Item
|
|
||||||
*/
|
|
||||||
public class UploadDepictsRenderer extends Renderer<DepictedItem> {
|
|
||||||
private final UploadDepictsCallback listener;
|
|
||||||
@BindView(R.id.depict_checkbox)
|
|
||||||
CheckBox checkedView;
|
|
||||||
@BindView(R.id.depicts_label)
|
|
||||||
TextView depictsLabel;
|
|
||||||
@BindView(R.id.description) TextView description;
|
|
||||||
@BindView(R.id.depicted_image)
|
|
||||||
SimpleDraweeView imageView;
|
|
||||||
|
|
||||||
public UploadDepictsRenderer(UploadDepictsCallback listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUpView(View rootView) {
|
|
||||||
ButterKnife.bind(this, rootView);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup OnClicklisteners on the views
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void hookListeners(View rootView) {
|
|
||||||
rootView.setOnClickListener(v -> {
|
|
||||||
DepictedItem item = getContent();
|
|
||||||
item.setSelected(!item.isSelected());
|
|
||||||
checkedView.setChecked(item.isSelected());
|
|
||||||
if (listener != null) {
|
|
||||||
listener.depictsClicked(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
checkedView.setOnClickListener(v -> {
|
|
||||||
DepictedItem item = getContent();
|
|
||||||
item.setSelected(!item.isSelected());
|
|
||||||
checkedView.setChecked(item.isSelected());
|
|
||||||
if (listener != null) {
|
|
||||||
listener.depictsClicked(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View inflate(LayoutInflater inflater, ViewGroup parent) {
|
|
||||||
return inflater.inflate(R.layout.layout_upload_depicts_item, parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* initialise views for every item in the adapter
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void render() {
|
|
||||||
DepictedItem item = getContent();
|
|
||||||
checkedView.setChecked(item.isSelected());
|
|
||||||
depictsLabel.setText(item.getName());
|
|
||||||
description.setText(item.getDescription());
|
|
||||||
final String imageUrl = item.getImageUrl();
|
|
||||||
if (TextUtils.isEmpty(imageUrl)) {
|
|
||||||
imageView.setImageURI(UriUtil.getUriForResourceId(R.drawable.ic_wikidata_logo_24dp));
|
|
||||||
} else {
|
|
||||||
imageView.setImageURI(Uri.parse(imageUrl));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package fr.free.nrw.commons.upload.categories
|
||||||
|
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.AdapterDelegate
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter
|
||||||
|
|
||||||
|
|
||||||
|
abstract class BaseDelegateAdapter<T>(
|
||||||
|
vararg delegates: AdapterDelegate<List<T>>,
|
||||||
|
areItemsTheSame: (T, T) -> Boolean,
|
||||||
|
areContentsTheSame: (T, T) -> Boolean = { old, new -> old == new }
|
||||||
|
) : AsyncListDifferDelegationAdapter<T>(
|
||||||
|
object : DiffUtil.ItemCallback<T>() {
|
||||||
|
override fun areItemsTheSame(oldItem: T, newItem: T) =
|
||||||
|
areItemsTheSame(oldItem, newItem)
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItem: T, newItem: T) =
|
||||||
|
areContentsTheSame(oldItem, newItem)
|
||||||
|
},
|
||||||
|
*delegates
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun addAll(newResults: List<T>) {
|
||||||
|
items = itemsOrEmpty + newResults
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
items = emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(item: T) {
|
||||||
|
items = itemsOrEmpty + item
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remove(item: T) {
|
||||||
|
items = itemsOrEmpty - item
|
||||||
|
}
|
||||||
|
|
||||||
|
private val itemsOrEmpty get() = items ?: emptyList<T>()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -18,23 +18,19 @@ import com.google.android.material.textfield.TextInputEditText;
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
import com.jakewharton.rxbinding2.view.RxView;
|
import com.jakewharton.rxbinding2.view.RxView;
|
||||||
import com.jakewharton.rxbinding2.widget.RxTextView;
|
import com.jakewharton.rxbinding2.widget.RxTextView;
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.category.CategoryClickedListener;
|
|
||||||
import fr.free.nrw.commons.category.CategoryItem;
|
import fr.free.nrw.commons.category.CategoryItem;
|
||||||
import fr.free.nrw.commons.upload.UploadBaseFragment;
|
import fr.free.nrw.commons.upload.UploadBaseFragment;
|
||||||
import fr.free.nrw.commons.upload.UploadCategoriesAdapterFactory;
|
|
||||||
import fr.free.nrw.commons.utils.DialogUtil;
|
import fr.free.nrw.commons.utils.DialogUtil;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.Disposable;
|
import io.reactivex.disposables.Disposable;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import kotlin.Unit;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class UploadCategoriesFragment extends UploadBaseFragment implements CategoriesContract.View,
|
public class UploadCategoriesFragment extends UploadBaseFragment implements CategoriesContract.View {
|
||||||
CategoryClickedListener {
|
|
||||||
|
|
||||||
@BindView(R.id.tv_title)
|
@BindView(R.id.tv_title)
|
||||||
TextView tvTitle;
|
TextView tvTitle;
|
||||||
|
|
@ -49,14 +45,9 @@ public class UploadCategoriesFragment extends UploadBaseFragment implements Cate
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CategoriesContract.UserActionListener presenter;
|
CategoriesContract.UserActionListener presenter;
|
||||||
private RVRendererAdapter<CategoryItem> adapter;
|
private UploadCategoryAdapter adapter;
|
||||||
private Disposable subscribe;
|
private Disposable subscribe;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
|
|
@ -93,8 +84,10 @@ public class UploadCategoriesFragment extends UploadBaseFragment implements Cate
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initRecyclerView() {
|
private void initRecyclerView() {
|
||||||
adapter = new UploadCategoriesAdapterFactory(this)
|
adapter = new UploadCategoryAdapter(categoryItem -> {
|
||||||
.create(new ArrayList<>());
|
presenter.onCategoryItemClicked(categoryItem);
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
rvCategories.setLayoutManager(new LinearLayoutManager(getContext()));
|
rvCategories.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
rvCategories.setAdapter(adapter);
|
rvCategories.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
@ -123,10 +116,11 @@ public class UploadCategoriesFragment extends UploadBaseFragment implements Cate
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCategories(List<CategoryItem> categories) {
|
public void setCategories(List<CategoryItem> categories) {
|
||||||
adapter.clear();
|
if(categories==null) {
|
||||||
if (categories != null) {
|
adapter.clear();
|
||||||
adapter.addAll(categories);
|
}
|
||||||
adapter.notifyDataSetChanged();
|
else{
|
||||||
|
adapter.setItems(categories);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,11 +151,6 @@ public class UploadCategoriesFragment extends UploadBaseFragment implements Cate
|
||||||
callback.onPreviousButtonClicked(callback.getIndexInViewFlipper(this));
|
callback.onPreviousButtonClicked(callback.getIndexInViewFlipper(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void categoryClicked(CategoryItem item) {
|
|
||||||
presenter.onCategoryItemClicked(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onBecameVisible() {
|
protected void onBecameVisible() {
|
||||||
super.onBecameVisible();
|
super.onBecameVisible();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package fr.free.nrw.commons.upload.categories
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
|
|
||||||
|
class UploadCategoryAdapter(onCategoryClicked: (CategoryItem) -> Unit) :
|
||||||
|
BaseDelegateAdapter<CategoryItem>(
|
||||||
|
uploadCategoryDelegate(onCategoryClicked),
|
||||||
|
areItemsTheSame = { oldItem, newItem -> oldItem.name == newItem.name },
|
||||||
|
areContentsTheSame = { oldItem, newItem ->
|
||||||
|
oldItem.name == newItem.name && oldItem.isSelected == newItem.isSelected
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package fr.free.nrw.commons.upload.categories
|
||||||
|
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer
|
||||||
|
import fr.free.nrw.commons.R
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
|
import kotlinx.android.synthetic.main.layout_upload_categories_item.*
|
||||||
|
|
||||||
|
fun uploadCategoryDelegate(onCategoryClicked: (CategoryItem) -> Unit) =
|
||||||
|
adapterDelegateLayoutContainer<CategoryItem, CategoryItem>(R.layout.layout_upload_categories_item) {
|
||||||
|
containerView.setOnClickListener {
|
||||||
|
item.isSelected = !item.isSelected
|
||||||
|
uploadCategoryCheckbox.isChecked = item.isSelected
|
||||||
|
onCategoryClicked(item)
|
||||||
|
}
|
||||||
|
bind {
|
||||||
|
uploadCategoryCheckbox.isChecked = item.isSelected
|
||||||
|
uploadCategoryCheckbox.text = item.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package fr.free.nrw.commons.upload.depicts;
|
package fr.free.nrw.commons.upload.depicts;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Pair;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
@ -18,27 +17,23 @@ import com.google.android.material.textfield.TextInputEditText;
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
import com.jakewharton.rxbinding2.view.RxView;
|
import com.jakewharton.rxbinding2.view.RxView;
|
||||||
import com.jakewharton.rxbinding2.widget.RxTextView;
|
import com.jakewharton.rxbinding2.widget.RxTextView;
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.upload.UploadBaseFragment;
|
import fr.free.nrw.commons.upload.UploadBaseFragment;
|
||||||
import fr.free.nrw.commons.upload.UploadDepictsAdapterFactory;
|
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.UploadDepictsCallback;
|
|
||||||
import fr.free.nrw.commons.utils.DialogUtil;
|
import fr.free.nrw.commons.utils.DialogUtil;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.Disposable;
|
import io.reactivex.disposables.Disposable;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import kotlin.Unit;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment for showing depicted items list in Upload activity after media details
|
* Fragment for showing depicted items list in Upload activity after media details
|
||||||
*/
|
*/
|
||||||
public class DepictsFragment extends UploadBaseFragment implements DepictsContract.View, UploadDepictsCallback {
|
public class DepictsFragment extends UploadBaseFragment implements DepictsContract.View {
|
||||||
|
|
||||||
@BindView(R.id.depicts_title)
|
@BindView(R.id.depicts_title)
|
||||||
TextView depictsTitle;
|
TextView depictsTitle;
|
||||||
|
|
@ -53,7 +48,7 @@ public class DepictsFragment extends UploadBaseFragment implements DepictsContra
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DepictsContract.UserActionListener presenter;
|
DepictsContract.UserActionListener presenter;
|
||||||
private RVRendererAdapter<DepictedItem> adapter;
|
private UploadDepictsAdapter adapter;
|
||||||
private Disposable subscribe;
|
private Disposable subscribe;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
@ -86,8 +81,10 @@ public class DepictsFragment extends UploadBaseFragment implements DepictsContra
|
||||||
* Initialise recyclerView and set adapter
|
* Initialise recyclerView and set adapter
|
||||||
*/
|
*/
|
||||||
private void initRecyclerView() {
|
private void initRecyclerView() {
|
||||||
adapter = new UploadDepictsAdapterFactory(this)
|
adapter = new UploadDepictsAdapter(item -> {
|
||||||
.create(new ArrayList<>());
|
presenter.onDepictItemClicked(item);
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
depictsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
depictsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
depictsRecyclerView.setAdapter(adapter);
|
depictsRecyclerView.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
@ -137,22 +134,7 @@ public class DepictsFragment extends UploadBaseFragment implements DepictsContra
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDepictsList(List<DepictedItem> depictedItemList) {
|
public void setDepictsList(List<DepictedItem> depictedItemList) {
|
||||||
adapter.clear();
|
adapter.setItems(depictedItemList);
|
||||||
if (depictedItemList != null) {
|
|
||||||
adapter.addAll(depictedItemList);
|
|
||||||
adapter.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private Pair<DepictedItem,Integer> returnItemAndPosition(@NotNull DepictedItem depictedItem) {
|
|
||||||
for (int i = 0; i < adapter.getItemCount(); i++) {
|
|
||||||
final DepictedItem item = adapter.getItem(i);
|
|
||||||
if(item.getId().equals(depictedItem.getId())){
|
|
||||||
return new Pair<>(item, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.depicts_next)
|
@OnClick(R.id.depicts_next)
|
||||||
|
|
@ -165,11 +147,6 @@ public class DepictsFragment extends UploadBaseFragment implements DepictsContra
|
||||||
callback.onPreviousButtonClicked(callback.getIndexInViewFlipper(this));
|
callback.onPreviousButtonClicked(callback.getIndexInViewFlipper(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void depictsClicked(DepictedItem item) {
|
|
||||||
presenter.onDepictItemClicked(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Text change listener for the edit text view of depicts
|
* Text change listener for the edit text view of depicts
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package fr.free.nrw.commons.upload.depicts
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.upload.categories.BaseDelegateAdapter
|
||||||
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
|
|
||||||
|
class UploadDepictsAdapter(onDepictsClicked: (DepictedItem) -> Unit) :
|
||||||
|
BaseDelegateAdapter<DepictedItem>(
|
||||||
|
uploadDepictsDelegate(onDepictsClicked),
|
||||||
|
areItemsTheSame = { oldItem, newItem -> oldItem.id == newItem.id }
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package fr.free.nrw.commons.upload.depicts
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import android.text.TextUtils
|
||||||
|
import android.view.View
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer
|
||||||
|
import fr.free.nrw.commons.R
|
||||||
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
|
import kotlinx.android.synthetic.main.layout_upload_depicts_item.*
|
||||||
|
|
||||||
|
|
||||||
|
fun uploadDepictsDelegate(onDepictClicked: (DepictedItem) -> Unit) =
|
||||||
|
adapterDelegateLayoutContainer<DepictedItem, DepictedItem>(R.layout.layout_upload_depicts_item) {
|
||||||
|
val onClickListener = { _: View? ->
|
||||||
|
item.isSelected = !item.isSelected
|
||||||
|
depict_checkbox.isChecked = item.isSelected
|
||||||
|
onDepictClicked(item)
|
||||||
|
}
|
||||||
|
containerView.setOnClickListener(onClickListener)
|
||||||
|
depict_checkbox.setOnClickListener(onClickListener)
|
||||||
|
bind {
|
||||||
|
depict_checkbox.isChecked = item.isSelected
|
||||||
|
depicts_label.text = item.name
|
||||||
|
description.text = item.description
|
||||||
|
val imageUrl = item.imageUrl
|
||||||
|
if (TextUtils.isEmpty(imageUrl)) {
|
||||||
|
depicted_image.setActualImageResource(R.drawable.ic_wikidata_logo_24dp)
|
||||||
|
} else {
|
||||||
|
depicted_image.setImageURI(Uri.parse(imageUrl))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
package fr.free.nrw.commons.upload.structure.depictions;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.CheckedTextView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.Renderer;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
|
|
||||||
public class DepictionRenderer extends Renderer<DepictedItem> {
|
|
||||||
@BindView(R.id.depict_checkbox)
|
|
||||||
CheckedTextView checkedView;
|
|
||||||
private final UploadDepictsCallback listener;
|
|
||||||
@BindView(R.id.depicts_label)
|
|
||||||
TextView depictsLabel;
|
|
||||||
@BindView(R.id.description) TextView description;
|
|
||||||
|
|
||||||
public DepictionRenderer(UploadDepictsCallback listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUpView(View rootView) {
|
|
||||||
ButterKnife.bind(this, rootView);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void hookListeners(View rootView) {
|
|
||||||
rootView.setOnClickListener( v -> {
|
|
||||||
DepictedItem item = getContent();
|
|
||||||
item.setSelected(true);
|
|
||||||
checkedView.setChecked(item.isSelected());
|
|
||||||
if (listener != null) {
|
|
||||||
listener.depictsClicked(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View inflate(LayoutInflater inflater, ViewGroup parent) {
|
|
||||||
return inflater.inflate(R.layout.layout_upload_depicts_item, parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render() {
|
|
||||||
DepictedItem item = getContent();
|
|
||||||
checkedView.setChecked(item.isSelected());
|
|
||||||
depictsLabel.setText(item.getName());
|
|
||||||
description.setText(item.getDescription());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,12 +5,12 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="@dimen/tiny_gap">
|
android:padding="@dimen/tiny_gap">
|
||||||
|
|
||||||
<ImageView
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/depicts_image"
|
android:id="@+id/depicts_image"
|
||||||
android:layout_width="70dp"
|
android:layout_width="70dp"
|
||||||
android:layout_height="70dp"
|
android:layout_height="70dp"
|
||||||
android:paddingRight="@dimen/tiny_gap"
|
android:paddingRight="@dimen/tiny_gap"
|
||||||
app:srcCompat="@drawable/ic_wikidata_logo_24dp"
|
app:placeholderImage="@drawable/ic_wikidata_logo_24dp"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"/>
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
|
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/tvName"
|
android:id="@+id/uploadCategoryCheckbox"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:checkMark="?android:attr/textCheckMark"
|
android:checkMark="?android:attr/textCheckMark"
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
<LinearLayout
|
<LinearLayout android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/buttonLayout"
|
android:id="@+id/buttonLayout"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_marginTop="@dimen/standard_gap"
|
tools:visibility="visible"
|
||||||
android:layout_below="@+id/icon"
|
android:layout_marginTop="@dimen/standard_gap"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
android:layout_below="@+id/icon"
|
||||||
>
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/cameraButton"
|
android:id="@+id/cameraButton"
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,14 @@
|
||||||
org.gradle.jvmargs=-Xmx1536M
|
org.gradle.jvmargs=-Xmx1536M
|
||||||
android.enableBuildCache=true
|
android.enableBuildCache=true
|
||||||
|
|
||||||
KOTLIN_VERSION=1.3.21
|
KOTLIN_VERSION=1.3.72
|
||||||
BUTTERKNIFE_VERSION=10.1.0
|
BUTTERKNIFE_VERSION=10.1.0
|
||||||
LEAK_CANARY_VERSION=1.6.2
|
LEAK_CANARY_VERSION=1.6.2
|
||||||
DAGGER_VERSION=2.21
|
DAGGER_VERSION=2.21
|
||||||
ROOM_VERSION=2.2.3
|
ROOM_VERSION=2.2.3
|
||||||
PREFERENCE_VERSION=1.1.0
|
PREFERENCE_VERSION=1.1.0
|
||||||
CORE_KTX_VERSION=1.2.0
|
CORE_KTX_VERSION=1.2.0
|
||||||
|
ADAPTER_DELEGATES_VERSION=4.3.0
|
||||||
MULTIDEX_VERSION=2.0.1
|
MULTIDEX_VERSION=2.0.1
|
||||||
|
|
||||||
systemProp.http.proxyPort=0
|
systemProp.http.proxyPort=0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue