mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
Merge 2.10 with master & Fixed merge conflicts (#2844)
This commit is contained in:
parent
02ad3b2dc8
commit
08a555c095
18 changed files with 172 additions and 113 deletions
|
|
@ -1,5 +1,9 @@
|
||||||
# Wikimedia Commons for Android
|
# Wikimedia Commons for Android
|
||||||
|
|
||||||
|
## v2.10.2
|
||||||
|
- Fixed remaining issues with date image taken
|
||||||
|
- Fixed database crash
|
||||||
|
|
||||||
## v2.10.1
|
## v2.10.1
|
||||||
- Fixed "stuck before category selection screen" bug
|
- Fixed "stuck before category selection screen" bug
|
||||||
- Fixed notification taps
|
- Fixed notification taps
|
||||||
|
|
|
||||||
|
|
@ -104,8 +104,8 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId 'fr.free.nrw.commons'
|
applicationId 'fr.free.nrw.commons'
|
||||||
versionCode 226
|
versionCode 243
|
||||||
versionName '2.10.1'
|
versionName '2.10.2'
|
||||||
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
|
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
|
||||||
|
|
||||||
minSdkVersion 19
|
minSdkVersion 19
|
||||||
|
|
|
||||||
|
|
@ -63,12 +63,8 @@ public class Utils {
|
||||||
return R.string.license_name_cc_by_sa_four;
|
return R.string.license_name_cc_by_sa_four;
|
||||||
case Prefs.Licenses.CC0:
|
case Prefs.Licenses.CC0:
|
||||||
return R.string.license_name_cc0;
|
return R.string.license_name_cc0;
|
||||||
case Prefs.Licenses.CC_BY: // for backward compatibility to v2.1
|
|
||||||
return R.string.license_name_cc_by_3_0;
|
|
||||||
case Prefs.Licenses.CC_BY_SA: // for backward compatibility to v2.1
|
|
||||||
return R.string.license_name_cc_by_sa_3_0;
|
|
||||||
}
|
}
|
||||||
throw new RuntimeException("Unrecognized license value: " + license);
|
throw new IllegalStateException("Unrecognized license value: " + license);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -92,7 +88,7 @@ public class Utils {
|
||||||
case Prefs.Licenses.CC0:
|
case Prefs.Licenses.CC0:
|
||||||
return "https://creativecommons.org/publicdomain/zero/1.0/";
|
return "https://creativecommons.org/publicdomain/zero/1.0/";
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unrecognized license value: " + license);
|
throw new IllegalStateException("Unrecognized license value: " + license);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,15 @@ import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import fr.free.nrw.commons.bookmarks.Bookmark;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
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 javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import fr.free.nrw.commons.bookmarks.Bookmark;
|
|
||||||
|
|
||||||
import static fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesContentProvider.BASE_URI;
|
import static fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesContentProvider.BASE_URI;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
|
|
@ -121,6 +119,10 @@ public class BookmarkPicturesDao {
|
||||||
* @return boolean : is bookmark in database ?
|
* @return boolean : is bookmark in database ?
|
||||||
*/
|
*/
|
||||||
public boolean findBookmark(Bookmark bookmark) {
|
public boolean findBookmark(Bookmark bookmark) {
|
||||||
|
if (bookmark == null) {//Avoiding NPE's
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
ContentProviderClient db = clientProvider.get();
|
ContentProviderClient db = clientProvider.get();
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -259,10 +259,6 @@ public class Contribution extends Media {
|
||||||
return "{{self|cc-by-sa-4.0}}";
|
return "{{self|cc-by-sa-4.0}}";
|
||||||
case Prefs.Licenses.CC0:
|
case Prefs.Licenses.CC0:
|
||||||
return "{{self|cc-zero}}";
|
return "{{self|cc-zero}}";
|
||||||
case Prefs.Licenses.CC_BY:
|
|
||||||
return "{{self|cc-by-3.0}}";
|
|
||||||
case Prefs.Licenses.CC_BY_SA:
|
|
||||||
return "{{self|cc-by-sa-3.0}}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new RuntimeException("Unrecognized license value: " + license);
|
throw new RuntimeException("Unrecognized license value: " + license);
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,9 @@ import android.net.Uri;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import fr.free.nrw.commons.settings.Prefs;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import fr.free.nrw.commons.settings.Prefs;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
@ -320,7 +319,7 @@ public class ContributionDao {
|
||||||
try {
|
try {
|
||||||
db.execSQL(query);
|
db.execSQL(query);
|
||||||
} catch (SQLiteException e) {
|
} catch (SQLiteException e) {
|
||||||
Timber.e(e, "Exception performing query: " + query);
|
Timber.e("Exception performing query: " + query + " message: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,26 +2,20 @@ package fr.free.nrw.commons.explore;
|
||||||
|
|
||||||
import android.database.DataSetObserver;
|
import android.database.DataSetObserver;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import com.google.android.material.tabs.TabLayout;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.fragment.app.FragmentManager;
|
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
|
||||||
import androidx.viewpager.widget.ViewPager;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
import android.text.TextUtils;
|
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 com.jakewharton.rxbinding2.view.RxView;
|
import androidx.fragment.app.Fragment;
|
||||||
import com.jakewharton.rxbinding2.widget.RxSearchView;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
import java.util.ArrayList;
|
import androidx.viewpager.widget.ViewPager;
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
import com.jakewharton.rxbinding2.view.RxView;
|
||||||
|
import com.jakewharton.rxbinding2.widget.RxSearchView;
|
||||||
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.explore.categories.SearchCategoryFragment;
|
import fr.free.nrw.commons.explore.categories.SearchCategoryFragment;
|
||||||
|
|
@ -29,8 +23,12 @@ import fr.free.nrw.commons.explore.images.SearchImageFragment;
|
||||||
import fr.free.nrw.commons.explore.recentsearches.RecentSearchesFragment;
|
import fr.free.nrw.commons.explore.recentsearches.RecentSearchesFragment;
|
||||||
import fr.free.nrw.commons.media.MediaDetailPagerFragment;
|
import fr.free.nrw.commons.media.MediaDetailPagerFragment;
|
||||||
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
||||||
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents search screen of this app
|
* Represents search screen of this app
|
||||||
|
|
@ -109,8 +107,13 @@ public class SearchActivity extends NavigationBaseActivity implements MediaDetai
|
||||||
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(searchImageFragment)) {
|
||||||
searchImageFragment.updateImageList(query.toString());
|
searchImageFragment.updateImageList(query.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FragmentUtils.isFragmentUIActive(searchCategoryFragment)) {
|
||||||
searchCategoryFragment.updateCategoryList(query.toString());
|
searchCategoryFragment.updateCategoryList(query.toString());
|
||||||
|
}
|
||||||
}else {
|
}else {
|
||||||
//Open RecentSearchesFragment
|
//Open RecentSearchesFragment
|
||||||
recentSearchesFragment.updateRecentSearches();
|
recentSearchesFragment.updateRecentSearches();
|
||||||
|
|
@ -261,4 +264,10 @@ public class SearchActivity extends NavigationBaseActivity implements MediaDetai
|
||||||
searchImageFragment.addImagesToList(query);
|
searchImageFragment.addImagesToList(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
//Dispose the disposables when the activity is destroyed
|
||||||
|
compositeDisposable.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package fr.free.nrw.commons.explore.images;
|
package fr.free.nrw.commons.explore.images;
|
||||||
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
@ -228,8 +227,15 @@ public class SearchImageFragment extends CommonsDaggerSupportFragment {
|
||||||
* Handles the UI updates for no internet scenario
|
* Handles the UI updates for no internet scenario
|
||||||
*/
|
*/
|
||||||
private void handleNoInternet() {
|
private void handleNoInternet() {
|
||||||
|
if (null
|
||||||
|
!= getView()) {//We have exposed public methods to update our ui, we will have to add null checks until we make this lifecycle aware
|
||||||
|
if (null != progressBar) {
|
||||||
progressBar.setVisibility(GONE);
|
progressBar.setVisibility(GONE);
|
||||||
|
}
|
||||||
ViewUtil.showShortSnackbar(imagesRecyclerView, R.string.no_internet);
|
ViewUtil.showShortSnackbar(imagesRecyclerView, R.string.no_internet);
|
||||||
|
} else {
|
||||||
|
Timber.d("Attempt to update fragment ui after its view was destroyed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -257,4 +263,9 @@ public class SearchImageFragment extends CommonsDaggerSupportFragment {
|
||||||
return imagesAdapter.getItem(i);
|
return imagesAdapter.getItem(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
compositeDisposable.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,12 @@ import io.reactivex.Single;
|
||||||
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.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Provider;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
|
|
@ -285,6 +291,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
detailProvider.unregisterDataSetObserver(dataObserver);
|
detailProvider.unregisterDataSetObserver(dataObserver);
|
||||||
dataObserver = null;
|
dataObserver = null;
|
||||||
}
|
}
|
||||||
|
compositeDisposable.clear();
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -414,9 +421,12 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(s -> {
|
.subscribe(s -> {
|
||||||
|
if (getActivity() != null) {
|
||||||
isDeleted = true;
|
isDeleted = true;
|
||||||
enableDeleteButton(false);
|
enableDeleteButton(false);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.seeMore)
|
@OnClick(R.id.seeMore)
|
||||||
|
|
@ -540,4 +550,5 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
nominatedForDeletion.setVisibility(GONE);
|
nominatedForDeletion.setVisibility(GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import android.app.DownloadManager;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.DataSetObserver;
|
import android.database.DataSetObserver;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
|
@ -15,14 +14,12 @@ import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.fragment.app.FragmentStatePagerAdapter;
|
import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||||
|
|
@ -44,12 +41,12 @@ import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||||
import fr.free.nrw.commons.utils.ImageUtils;
|
import fr.free.nrw.commons.utils.ImageUtils;
|
||||||
import fr.free.nrw.commons.utils.NetworkUtils;
|
import fr.free.nrw.commons.utils.NetworkUtils;
|
||||||
|
import fr.free.nrw.commons.utils.PermissionUtils;
|
||||||
import fr.free.nrw.commons.utils.ViewUtil;
|
import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||||
import static android.content.Context.DOWNLOAD_SERVICE;
|
import static android.content.Context.DOWNLOAD_SERVICE;
|
||||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
|
||||||
import static fr.free.nrw.commons.Utils.handleWebUrl;
|
import static fr.free.nrw.commons.Utils.handleWebUrl;
|
||||||
|
|
||||||
public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment implements ViewPager.OnPageChangeListener {
|
public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment implements ViewPager.OnPageChangeListener {
|
||||||
|
|
@ -227,22 +224,21 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
|
||||||
// Modern Android updates the gallery automatically. Yay!
|
// Modern Android updates the gallery automatically. Yay!
|
||||||
req.allowScanningByMediaScanner();
|
req.allowScanningByMediaScanner();
|
||||||
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
||||||
|
PermissionUtils.checkPermissionsAndPerformAction(getActivity(), WRITE_EXTERNAL_STORAGE,
|
||||||
|
() -> enqueueRequest(req), () -> Toast.makeText(getContext(),
|
||||||
|
R.string.download_failed_we_cannot_download_the_file_without_storage_permission,
|
||||||
|
Toast.LENGTH_SHORT).show(), R.string.storage_permission,
|
||||||
|
R.string.write_storage_permission_rationale);
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
|
}
|
||||||
ContextCompat.checkSelfPermission(getContext(), READ_EXTERNAL_STORAGE)
|
|
||||||
!= PERMISSION_GRANTED
|
private void enqueueRequest(DownloadManager.Request req) {
|
||||||
&& getView() != null) {
|
DownloadManager systemService =
|
||||||
Snackbar.make(getView(), R.string.read_storage_permission_rationale,
|
(DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE);
|
||||||
Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok,
|
|
||||||
view -> ActivityCompat.requestPermissions(getActivity(),
|
|
||||||
new String[]{READ_EXTERNAL_STORAGE}, 1)).show();
|
|
||||||
} else {
|
|
||||||
DownloadManager systemService = (DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE);
|
|
||||||
if (systemService != null) {
|
if (systemService != null) {
|
||||||
systemService.enqueue(req);
|
systemService.enqueue(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,10 @@ public class CustomMwApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthCookie(String authCookie) {
|
public void setAuthCookie(String authCookie) {
|
||||||
|
if (authCookie == null) {//If the authCookie is null, no need to proceed
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.authCookie = authCookie;
|
this.authCookie = authCookie;
|
||||||
this.isLoggedIn = true;
|
this.isLoggedIn = true;
|
||||||
String[] cookies = authCookie.split(";");
|
String[] cookies = authCookie.split(";");
|
||||||
|
|
|
||||||
|
|
@ -319,10 +319,13 @@ public class OkHttpJsonApiClient {
|
||||||
if (response.body() != null && response.isSuccessful()) {
|
if (response.body() != null && response.isSuccessful()) {
|
||||||
String json = response.body().string();
|
String json = response.body().string();
|
||||||
MwQueryResponse mwQueryResponse = gson.fromJson(json, MwQueryResponse.class);
|
MwQueryResponse mwQueryResponse = gson.fromJson(json, MwQueryResponse.class);
|
||||||
putContinueValues(keyword, mwQueryResponse.continuation());
|
if (null == mwQueryResponse
|
||||||
if (mwQueryResponse.query() == null) {
|
|| null == mwQueryResponse.query()
|
||||||
|
|| null == mwQueryResponse.query().pages()) {
|
||||||
return mediaList;
|
return mediaList;
|
||||||
}
|
}
|
||||||
|
putContinueValues(keyword, mwQueryResponse.continuation());
|
||||||
|
|
||||||
List<MwQueryPage> pages = mwQueryResponse.query().pages();
|
List<MwQueryPage> pages = mwQueryResponse.query().pages();
|
||||||
for (MwQueryPage page : pages) {
|
for (MwQueryPage page : pages) {
|
||||||
Media media = Media.from(page);
|
Media media = Media.from(page);
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,5 @@ public class Prefs {
|
||||||
public static final String CC_BY_SA_4 = "CC BY-SA 4.0";
|
public static final String CC_BY_SA_4 = "CC BY-SA 4.0";
|
||||||
public static final String CC_BY_4 = "CC BY 4.0";
|
public static final String CC_BY_4 = "CC BY 4.0";
|
||||||
public static final String CC0 = "CC0";
|
public static final String CC0 = "CC0";
|
||||||
|
|
||||||
// kept for backward compatibility to v2.1
|
|
||||||
@Deprecated public static final String CC_BY = "CC BY";
|
|
||||||
@Deprecated public static final String CC_BY_SA = "CC BY-SA";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,8 @@ package fr.free.nrw.commons.upload;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
|
import fr.free.nrw.commons.Utils;
|
||||||
import fr.free.nrw.commons.category.CategoriesModel;
|
import fr.free.nrw.commons.category.CategoriesModel;
|
||||||
import fr.free.nrw.commons.contributions.Contribution;
|
import fr.free.nrw.commons.contributions.Contribution;
|
||||||
import fr.free.nrw.commons.filepicker.UploadableFile;
|
import fr.free.nrw.commons.filepicker.UploadableFile;
|
||||||
|
|
@ -31,6 +21,7 @@ import java.util.List;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
import static fr.free.nrw.commons.upload.UploadModel.UploadItem;
|
import static fr.free.nrw.commons.upload.UploadModel.UploadItem;
|
||||||
|
|
@ -334,7 +325,15 @@ public class UploadPresenter {
|
||||||
* Sets the list of licences and the default license.
|
* Sets the list of licences and the default license.
|
||||||
*/
|
*/
|
||||||
private void updateLicenses() {
|
private void updateLicenses() {
|
||||||
String selectedLicense = directKvStore.getString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA_3);
|
String selectedLicense = directKvStore.getString(Prefs.DEFAULT_LICENSE,
|
||||||
|
Prefs.Licenses.CC_BY_SA_4);//CC_BY_SA_4 is the default one used by the commons web app
|
||||||
|
try {//I have to make sure that the stored default license was not one of the deprecated one's
|
||||||
|
Utils.licenseNameFor(selectedLicense);
|
||||||
|
} catch (IllegalStateException exception) {
|
||||||
|
Timber.e(exception.getMessage());
|
||||||
|
selectedLicense = Prefs.Licenses.CC_BY_SA_4;
|
||||||
|
directKvStore.putString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA_4);
|
||||||
|
}
|
||||||
view.updateLicenses(uploadModel.getLicenses(), selectedLicense);
|
view.updateLicenses(uploadModel.getLicenses(), selectedLicense);
|
||||||
view.updateLicenseSummary(selectedLicense, uploadModel.getCount());
|
view.updateLicenseSummary(selectedLicense, uploadModel.getCount());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,6 @@ public class FragmentUtils {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean isFragmentUIActive(Fragment fragment) {
|
public static boolean isFragmentUIActive(Fragment fragment) {
|
||||||
return fragment.getActivity() != null && fragment.isAdded() && !fragment.isDetached() && !fragment.isRemoving();
|
return fragment!=null && fragment.getActivity() != null && fragment.isAdded() && !fragment.isDetached() && !fragment.isRemoving();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import com.karumi.dexter.listener.PermissionDeniedResponse;
|
||||||
import com.karumi.dexter.listener.PermissionGrantedResponse;
|
import com.karumi.dexter.listener.PermissionGrantedResponse;
|
||||||
import com.karumi.dexter.listener.PermissionRequest;
|
import com.karumi.dexter.listener.PermissionRequest;
|
||||||
import com.karumi.dexter.listener.single.BasePermissionListener;
|
import com.karumi.dexter.listener.single.BasePermissionListener;
|
||||||
|
|
||||||
import fr.free.nrw.commons.CommonsApplication;
|
import fr.free.nrw.commons.CommonsApplication;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
|
|
||||||
|
|
@ -64,42 +63,68 @@ public class PermissionUtils {
|
||||||
* @param rationaleTitle rationale title to be displayed when permission was denied
|
* @param rationaleTitle rationale title to be displayed when permission was denied
|
||||||
* @param rationaleMessage rationale message to be displayed when permission was denied
|
* @param rationaleMessage rationale message to be displayed when permission was denied
|
||||||
*/
|
*/
|
||||||
public static void checkPermissionsAndPerformAction(Activity activity,
|
public static void checkPermissionsAndPerformAction(Activity activity, String permission,
|
||||||
String permission,
|
Runnable onPermissionGranted, @StringRes int rationaleTitle,
|
||||||
Runnable onPermissionGranted,
|
@StringRes int rationaleMessage) {
|
||||||
@StringRes int rationaleTitle,
|
checkPermissionsAndPerformAction(activity, permission, onPermissionGranted, null,
|
||||||
|
rationaleTitle, rationaleMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for a particular permission and runs the corresponding runnables to perform an action when the permission is granted/denied
|
||||||
|
* Also, it shows a rationale if needed
|
||||||
|
*
|
||||||
|
* Sample usage:
|
||||||
|
*
|
||||||
|
* PermissionUtils.checkPermissionsAndPerformAction(activity,
|
||||||
|
* Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||||
|
* () -> initiateCameraUpload(activity),
|
||||||
|
* () -> showMessage(),
|
||||||
|
* R.string.storage_permission_title,
|
||||||
|
* R.string.write_storage_permission_rationale);
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param activity activity requesting permissions
|
||||||
|
* @param permission the permission being requests
|
||||||
|
* @param onPermissionGranted the runnable to be executed when the permission is granted
|
||||||
|
* @param onPermissionDenied the runnable to be executed when the permission is denied(but not permanently)
|
||||||
|
* @param rationaleTitle rationale title to be displayed when permission was denied
|
||||||
|
* @param rationaleMessage rationale message to be displayed when permission was denied
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static void checkPermissionsAndPerformAction(Activity activity, String permission,
|
||||||
|
Runnable onPermissionGranted, Runnable onPermissionDenied, @StringRes int rationaleTitle,
|
||||||
@StringRes int rationaleMessage) {
|
@StringRes int rationaleMessage) {
|
||||||
Dexter.withActivity(activity)
|
Dexter.withActivity(activity)
|
||||||
.withPermission(permission)
|
.withPermission(permission)
|
||||||
.withListener(new BasePermissionListener() {
|
.withListener(new BasePermissionListener() {
|
||||||
@Override
|
@Override public void onPermissionGranted(PermissionGrantedResponse response) {
|
||||||
public void onPermissionGranted(PermissionGrantedResponse response) {
|
|
||||||
onPermissionGranted.run();
|
onPermissionGranted.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public void onPermissionDenied(PermissionDeniedResponse response) {
|
||||||
public void onPermissionDenied(PermissionDeniedResponse response) {
|
|
||||||
if (response.isPermanentlyDenied()) {
|
if (response.isPermanentlyDenied()) {
|
||||||
DialogUtil.showAlertDialog(activity,
|
DialogUtil.showAlertDialog(activity, activity.getString(rationaleTitle),
|
||||||
activity.getString(rationaleTitle),
|
|
||||||
activity.getString(rationaleMessage),
|
activity.getString(rationaleMessage),
|
||||||
activity.getString(R.string.navigation_item_settings),
|
activity.getString(R.string.navigation_item_settings), null,
|
||||||
null,
|
() -> askUserToManuallyEnablePermissionFromSettings(activity), null);
|
||||||
() -> askUserToManuallyEnablePermissionFromSettings(activity),
|
} else {
|
||||||
null);
|
if (null != onPermissionDenied) {
|
||||||
|
onPermissionDenied.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
|
public void onPermissionRationaleShouldBeShown(PermissionRequest permission,
|
||||||
DialogUtil.showAlertDialog(activity,
|
PermissionToken token) {
|
||||||
activity.getString(rationaleTitle),
|
DialogUtil.showAlertDialog(activity, activity.getString(rationaleTitle),
|
||||||
activity.getString(rationaleMessage),
|
activity.getString(rationaleMessage),
|
||||||
activity.getString(android.R.string.ok),
|
activity.getString(android.R.string.ok),
|
||||||
activity.getString(android.R.string.cancel),
|
activity.getString(android.R.string.cancel),
|
||||||
token::continuePermissionRequest,
|
token::continuePermissionRequest, token::cancelPermissionRequest);
|
||||||
token::cancelPermissionRequest);
|
|
||||||
}
|
}
|
||||||
}).check();
|
})
|
||||||
|
.check();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import android.view.Display;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
|
||||||
|
|
@ -22,7 +23,13 @@ public class ViewUtil {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecutorUtils.uiExecutor().execute(() -> Snackbar.make(view, messageResourceId, Snackbar.LENGTH_SHORT).show());
|
ExecutorUtils.uiExecutor().execute(() -> {
|
||||||
|
try {
|
||||||
|
Snackbar.make(view, messageResourceId, Snackbar.LENGTH_SHORT).show();
|
||||||
|
}catch (IllegalStateException e){
|
||||||
|
Timber.e(e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showLongToast(Context context, String text) {
|
public static void showLongToast(Context context, String text) {
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@
|
||||||
<string name="menu_refresh">Refresh</string>
|
<string name="menu_refresh">Refresh</string>
|
||||||
<string name="storage_permission_title">Requesting Storage Permission</string>
|
<string name="storage_permission_title">Requesting Storage Permission</string>
|
||||||
<string name="read_storage_permission_rationale">Required permission: Read external storage. App cannot access your gallery without this.</string>
|
<string name="read_storage_permission_rationale">Required permission: Read external storage. App cannot access your gallery without this.</string>
|
||||||
<string name="write_storage_permission_rationale">Required permission: Write external storage. App cannot access your camera without this.</string>
|
<string name="write_storage_permission_rationale">Required permission: Write external storage. App cannot access your camera/gallery without this.</string>
|
||||||
<string name="location_permission_rationale">Optional permission: Get current location for category suggestions</string>
|
<string name="location_permission_rationale">Optional permission: Get current location for category suggestions</string>
|
||||||
<string name="ok">OK</string>
|
<string name="ok">OK</string>
|
||||||
<string name="title_activity_nearby">Nearby Places</string>
|
<string name="title_activity_nearby">Nearby Places</string>
|
||||||
|
|
@ -534,4 +534,5 @@ Upload your first media by tapping on the add button.</string>
|
||||||
<string name="images_via_nearby_explanation">Images Uploaded via Nearby places are the images which are uploaded by discovering places on the map.</string>
|
<string name="images_via_nearby_explanation">Images Uploaded via Nearby places are the images which are uploaded by discovering places on the map.</string>
|
||||||
<string name="thanks_received_explanation" >This feature allows editors to send a Thank you notification to users who make useful edits – by using a small thank link on the history page or diff page.</string>
|
<string name="thanks_received_explanation" >This feature allows editors to send a Thank you notification to users who make useful edits – by using a small thank link on the history page or diff page.</string>
|
||||||
<string name="skip_image">SKIP THIS IMAGE</string>
|
<string name="skip_image">SKIP THIS IMAGE</string>
|
||||||
|
<string name="download_failed_we_cannot_download_the_file_without_storage_permission">Download Failed!!. We cannot download the file without external storage permission.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue