From a615e0784e29de6f9c175ad578f8ba4c8b99466a Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Sun, 3 Sep 2017 16:45:19 -0500 Subject: [PATCH 01/13] Cleanup the logout positive button lambda. --- .../free/nrw/commons/CommonsApplication.java | 8 +++-- .../commons/theme/NavigationBaseActivity.java | 30 +++++++++---------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java index 1fbf98a28..f3494d46f 100644 --- a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java +++ b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java @@ -13,7 +13,6 @@ import android.content.pm.PackageManager; import android.database.sqlite.SQLiteDatabase; import android.preference.PreferenceManager; import android.support.v4.util.LruCache; -import android.util.Log; import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.stetho.Stetho; @@ -35,7 +34,6 @@ import fr.free.nrw.commons.modifications.ModifierSequence; import fr.free.nrw.commons.mwapi.ApacheHttpClientMediaWikiApi; import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.nearby.NearbyPlaces; -import fr.free.nrw.commons.theme.NavigationBaseActivity; import fr.free.nrw.commons.utils.FileUtils; import timber.log.Timber; @@ -190,7 +188,7 @@ public class CommonsApplication extends Application { pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT); } - public void clearApplicationData(Context context, NavigationBaseActivity.LogoutListener logoutListener) { + public void clearApplicationData(Context context, LogoutListener logoutListener) { File cacheDirectory = context.getCacheDir(); File applicationDirectory = new File(cacheDirectory.getParent()); if (applicationDirectory.exists()) { @@ -265,4 +263,8 @@ public class CommonsApplication extends Application { Category.Table.onDelete(db); Contribution.Table.onDelete(db); } + + public interface LogoutListener { + void onLogoutComplete(); + } } diff --git a/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java b/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java index 4b4579d50..3537e4a1d 100644 --- a/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java @@ -24,15 +24,13 @@ import fr.free.nrw.commons.nearby.NearbyActivity; import fr.free.nrw.commons.settings.SettingsActivity; import timber.log.Timber; -public class NavigationBaseActivity extends BaseActivity +public abstract class NavigationBaseActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.toolbar) Toolbar toolbar; - @BindView(R.id.navigation_view) NavigationView navigationView; - @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; @@ -121,16 +119,9 @@ public class NavigationBaseActivity extends BaseActivity .setMessage(R.string.logout_verification) .setCancelable(false) .setPositiveButton(R.string.yes, (dialog, which) -> { - ((CommonsApplication) getApplicationContext()) - .clearApplicationData(NavigationBaseActivity.this, () -> { - Timber.d("Logout complete callback received."); - Intent nearbyIntent = new Intent( - NavigationBaseActivity.this, LoginActivity.class); - nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(nearbyIntent); - finish(); - }); + BaseLogoutListener logoutListener = new BaseLogoutListener(); + CommonsApplication app = (CommonsApplication) getApplication(); + app.clearApplicationData(this, logoutListener); }) .setNegativeButton(R.string.no, (dialog, which) -> dialog.cancel()) .show(); @@ -140,7 +131,16 @@ public class NavigationBaseActivity extends BaseActivity } } - public interface LogoutListener { - void onLogoutComplete(); + private class BaseLogoutListener implements CommonsApplication.LogoutListener { + @Override + public void onLogoutComplete() { + Timber.d("Logout complete callback received."); + Intent nearbyIntent = new Intent( + NavigationBaseActivity.this, LoginActivity.class); + nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(nearbyIntent); + finish(); + } } } From f74de55b607b0cd8c2abaa036e8f2de0fa9ff76c Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Sun, 3 Sep 2017 16:52:52 -0500 Subject: [PATCH 02/13] Lint warning: Lambda can be replaced with method reference. --- .../nrw/commons/auth/AuthenticatedActivity.java | 4 +--- .../commons/category/CategorizationFragment.java | 5 ++--- .../mwapi/ApacheHttpClientMediaWikiApi.java | 16 +++++++--------- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java index 0db56e66b..1fcec5389 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java @@ -28,9 +28,7 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { .subscribeOn(Schedulers.io()) .doOnError(Timber::e) .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - cookie -> onAuthCookieAcquired(cookie), - throwable -> onAuthFailure()); + .subscribe(this::onAuthCookieAcquired, throwable -> onAuthFailure()); } private void addAccount(AccountManager accountManager) { diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java b/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java index b281a6c1b..f654dca7d 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java @@ -97,6 +97,7 @@ public class CategorizationFragment extends Fragment { categoriesCache = new HashMap<>(); if (savedInstanceState != null) { items.addAll(savedInstanceState.getParcelableArrayList("currentCategories")); + //noinspection unchecked categoriesCache.putAll((HashMap>) savedInstanceState .getSerializable("categoriesCache")); } @@ -201,9 +202,7 @@ public class CategorizationFragment extends Fragment { .distinct() .observeOn(AndroidSchedulers.mainThread()) .subscribe( - s -> categoriesAdapter.add(s), - throwable -> Timber.e(throwable), - () -> { + s -> categoriesAdapter.add(s), Timber::e, () -> { categoriesAdapter.notifyDataSetChanged(); categoriesSearchInProgress.setVisibility(View.GONE); diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java index 7af42b0fe..47a91acfb 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.concurrent.Callable; import fr.free.nrw.commons.BuildConfig; import fr.free.nrw.commons.PageTitle; @@ -235,8 +236,7 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { } return categories; - }) - .flatMapObservable(list -> Observable.fromIterable(list)); + }).flatMapObservable(Observable::fromIterable); } @Override @@ -265,15 +265,14 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { } return categories; - }) - .flatMapObservable(list -> Observable.fromIterable(list)); + }).flatMapObservable(Observable::fromIterable); } @Override @NonNull public Observable searchTitles(String title, int searchCatsLimit) { - return Single.fromCallable(() -> { - ArrayList categoryNodes = null; + return Single.fromCallable((Callable>) () -> { + ArrayList categoryNodes; try { categoryNodes = api.action("query") @@ -287,7 +286,7 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { .getNodes("/api/query/search/p/@title"); } catch (IOException e) { Timber.e("Failed to obtain searchTitles", e); - return new ArrayList(); + return Collections.emptyList(); } if (categoryNodes == null) { @@ -302,8 +301,7 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { } return titleCategories; - }) - .flatMapObservable(list -> Observable.fromIterable(list)); + }).flatMapObservable(Observable::fromIterable); } @Override From d59a526f7fcaa8ed719f8602c2933d693e362b52 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Sun, 3 Sep 2017 17:00:16 -0500 Subject: [PATCH 03/13] Lint error: use of restricted API --- .../commons/media/MediaDetailFragment.java | 6 +-- .../upload/MultipleUploadListFragment.java | 42 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java index f2461fcf0..fe68203ec 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java @@ -276,13 +276,13 @@ public class MediaDetailFragment extends Fragment { categoryContainer.removeAllViews(); // @fixme add the category items for (String cat : categoryNames) { - View catLabel = buildCatLabel(cat); + View catLabel = buildCatLabel(cat, categoryContainer); categoryContainer.addView(catLabel); } } - private View buildCatLabel(final String catName) { - final View item = getLayoutInflater(null).inflate(R.layout.detail_category_item, null, false); + private View buildCatLabel(final String catName, ViewGroup categoryContainer) { + final View item = LayoutInflater.from(getContext()).inflate(R.layout.detail_category_item, categoryContainer, false); final CompatTextView textView = (CompatTextView)item.findViewById(R.id.mediaDetailCategoryItemText); textView.setText(catName); diff --git a/app/src/main/java/fr/free/nrw/commons/upload/MultipleUploadListFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/MultipleUploadListFragment.java index 629d41639..28f88e3d6 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/MultipleUploadListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/MultipleUploadListFragment.java @@ -77,8 +77,8 @@ public class MultipleUploadListFragment extends Fragment { public View getView(int i, View view, ViewGroup viewGroup) { UploadHolderView holder; - if(view == null) { - view = getLayoutInflater(null).inflate(R.layout.layout_upload_item, null); + if (view == null) { + view = LayoutInflater.from(getContext()).inflate(R.layout.layout_upload_item, viewGroup, false); holder = new UploadHolderView(); holder.image = (SimpleDraweeView) view.findViewById(R.id.uploadImage); holder.title = (TextView) view.findViewById(R.id.uploadTitle); @@ -94,17 +94,17 @@ public class MultipleUploadListFragment extends Fragment { .build()); view.setTag(holder); } else { - holder = (UploadHolderView)view.getTag(); + holder = (UploadHolderView) view.getTag(); } - Contribution up = (Contribution)this.getItem(i); + Contribution up = (Contribution) this.getItem(i); - if(holder.imageUri == null || !holder.imageUri.equals(up.getLocalUri())) { + if (holder.imageUri == null || !holder.imageUri.equals(up.getLocalUri())) { holder.image.setImageURI(up.getLocalUri().toString()); holder.imageUri = up.getLocalUri(); } - if(!imageOnlyMode) { + if (!imageOnlyMode) { holder.overlay.setVisibility(View.VISIBLE); holder.title.setText(up.getFilename()); } else { @@ -134,21 +134,21 @@ public class MultipleUploadListFragment extends Fragment { int screenHeight = screenMetrics.heightPixels; int picWidth = Math.min((int) Math.sqrt(screenWidth * screenHeight / count), screenWidth); - picWidth = Math.min((int)(192 * screenMetrics.density), Math.max((int) (120 * screenMetrics.density), picWidth / 48 * 48)); - int picHeight = Math.min(picWidth, (int)(192 * screenMetrics.density)); // Max Height is same as Contributions list + picWidth = Math.min((int) (192 * screenMetrics.density), Math.max((int) (120 * screenMetrics.density), picWidth / 48 * 48)); + int picHeight = Math.min(picWidth, (int) (192 * screenMetrics.density)); // Max Height is same as Contributions list return new Point(picWidth, picHeight); } public void notifyDatasetChanged() { - if(photosAdapter != null) { + if (photosAdapter != null) { photosAdapter.notifyDataSetChanged(); } } public void setImageOnlyMode(boolean mode) { imageOnlyMode = mode; - if(imageOnlyMode) { + if (imageOnlyMode) { baseTitle.setVisibility(View.GONE); } else { baseTitle.setVisibility(View.VISIBLE); @@ -159,13 +159,13 @@ public class MultipleUploadListFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_multiple_uploads_list, null); - photosGrid = (GridView)view.findViewById(R.id.multipleShareBackground); - baseTitle = (EditText)view.findViewById(R.id.multipleBaseTitle); + View view = inflater.inflate(R.layout.fragment_multiple_uploads_list, container, false); + photosGrid = (GridView) view.findViewById(R.id.multipleShareBackground); + baseTitle = (EditText) view.findViewById(R.id.multipleBaseTitle); photosAdapter = new PhotoDisplayAdapter(); photosGrid.setAdapter(photosAdapter); - photosGrid.setOnItemClickListener((AdapterView.OnItemClickListener)getActivity()); + photosGrid.setOnItemClickListener((AdapterView.OnItemClickListener) getActivity()); photoSize = calculatePicDimension(detailProvider.getTotalMediaCount()); photosGrid.setColumnWidth(photoSize.x); @@ -188,7 +188,7 @@ public class MultipleUploadListFragment extends Fragment { @Override public boolean onOptionsItemSelected(MenuItem item) { - switch(item.getItemId()) { + switch (item.getItemId()) { case R.id.menu_upload_multiple: multipleUploadInitiatedHandler.OnMultipleUploadInitiated(); return true; @@ -200,7 +200,7 @@ public class MultipleUploadListFragment extends Fragment { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - detailProvider = (MediaDetailPagerFragment.MediaDetailProvider)getActivity(); + detailProvider = (MediaDetailPagerFragment.MediaDetailProvider) getActivity(); multipleUploadInitiatedHandler = (OnMultipleUploadInitiatedHandler) getActivity(); setHasOptionsMenu(true); @@ -213,12 +213,12 @@ public class MultipleUploadListFragment extends Fragment { @Override public void onTextChanged(CharSequence charSequence, int i1, int i2, int i3) { - for(int i = 0; i < detailProvider.getTotalMediaCount(); i++) { + for (int i = 0; i < detailProvider.getTotalMediaCount(); i++) { Contribution up = (Contribution) detailProvider.getMediaAtPosition(i); - Boolean isDirty = (Boolean)up.getTag("isDirty"); - if(isDirty == null || !isDirty) { - if(!TextUtils.isEmpty(charSequence)) { - up.setFilename(charSequence.toString() + " - " + ((Integer)up.getTag("sequence") + 1)); + Boolean isDirty = (Boolean) up.getTag("isDirty"); + if (isDirty == null || !isDirty) { + if (!TextUtils.isEmpty(charSequence)) { + up.setFilename(charSequence.toString() + " - " + ((Integer) up.getTag("sequence") + 1)); } else { up.setFilename(""); } From 13e84a82b8db41ea6f29163c405fd71193993096 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Sun, 3 Sep 2017 17:05:37 -0500 Subject: [PATCH 04/13] Removed unused imports. --- app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java | 1 - app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java | 2 -- .../nrw/commons/contributions/ContributionsListFragment.java | 2 -- app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java | 1 - .../main/java/fr/free/nrw/commons/nearby/NearbyController.java | 1 - .../java/fr/free/nrw/commons/nearby/NearbyMapFragment.java | 3 --- .../java/fr/free/nrw/commons/settings/SettingsFragment.java | 2 -- .../java/fr/free/nrw/commons/upload/ExistingFileAsync.java | 1 - .../main/java/fr/free/nrw/commons/upload/ShareActivity.java | 1 - 9 files changed, 14 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java b/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java index 5ec80f0d3..5e8ad7386 100644 --- a/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java +++ b/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java @@ -2,7 +2,6 @@ package fr.free.nrw.commons; import android.support.annotation.Nullable; -import org.mediawiki.api.ApiResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java index aca419b9c..156741865 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java @@ -8,10 +8,8 @@ import android.os.Bundle; import android.support.v4.app.NavUtils; import android.text.Editable; import android.text.TextWatcher; -import android.view.KeyEvent; import android.view.MenuItem; import android.view.View; -import android.view.inputmethod.EditorInfo; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java index bcbb5a739..3ead40bcf 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java @@ -1,8 +1,6 @@ package fr.free.nrw.commons.contributions; -import android.Manifest; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java index 292c0a5de..310c97a8a 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java @@ -5,7 +5,6 @@ import android.support.annotation.Nullable; import java.io.IOException; import java.io.InputStream; -import java.util.List; import io.reactivex.Observable; import io.reactivex.Single; diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java index b08b99d72..58c8bb8a7 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java @@ -10,7 +10,6 @@ import com.mapbox.mapboxsdk.annotations.IconFactory; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Locale; diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java index efa88819c..d9e1aa633 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java @@ -4,7 +4,6 @@ import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; -import android.support.annotation.NonNull; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -13,7 +12,6 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import com.mapbox.mapboxsdk.Mapbox; -import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.MarkerOptions; import com.mapbox.mapboxsdk.annotations.PolygonOptions; import com.mapbox.mapboxsdk.camera.CameraPosition; @@ -22,7 +20,6 @@ import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.MapboxMapOptions; -import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; import com.mapbox.services.android.telemetry.MapboxTelemetry; import java.lang.reflect.Type; diff --git a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java index cfeda91d1..0640ea444 100644 --- a/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/settings/SettingsFragment.java @@ -1,13 +1,11 @@ package fr.free.nrw.commons.settings; import android.app.AlertDialog; -import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.ListPreference; -import android.preference.Preference; import android.preference.PreferenceFragment; import android.preference.PreferenceManager; diff --git a/app/src/main/java/fr/free/nrw/commons/upload/ExistingFileAsync.java b/app/src/main/java/fr/free/nrw/commons/upload/ExistingFileAsync.java index 09fed56ea..b76150643 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/ExistingFileAsync.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/ExistingFileAsync.java @@ -1,7 +1,6 @@ package fr.free.nrw.commons.upload; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.os.AsyncTask; import android.support.v7.app.AlertDialog; diff --git a/app/src/main/java/fr/free/nrw/commons/upload/ShareActivity.java b/app/src/main/java/fr/free/nrw/commons/upload/ShareActivity.java index 42ec3cfe6..67e96090f 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/ShareActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/ShareActivity.java @@ -27,7 +27,6 @@ import com.facebook.drawee.view.SimpleDraweeView; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; import java.util.Date; import java.util.List; From 8cbf56fa7bdee9d21e0fed0290f428d39c1806d6 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Sun, 3 Sep 2017 17:27:20 -0500 Subject: [PATCH 05/13] Java 5 / Java 8 language suggestions plus general cleanup. --- .../commons/category/CategoriesRenderer.java | 15 +-- .../commons/contributions/Contribution.java | 2 +- .../modifications/CategoryModifier.java | 2 +- .../modifications/ModifierSequence.java | 2 +- .../commons/upload/SingleUploadFragment.java | 115 ++++++++---------- .../fr/free/nrw/commons/utils/FileUtils.java | 2 +- 6 files changed, 62 insertions(+), 76 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoriesRenderer.java b/app/src/main/java/fr/free/nrw/commons/category/CategoriesRenderer.java index a138736cc..81cccdb72 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoriesRenderer.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoriesRenderer.java @@ -31,15 +31,12 @@ class CategoriesRenderer extends Renderer { @Override protected void hookListeners(View view) { - view.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - CategoryItem item = getContent(); - item.setSelected(!item.isSelected()); - checkedView.setChecked(item.isSelected()); - if (listener != null) { - listener.categoryClicked(item); - } + view.setOnClickListener(v -> { + CategoryItem item = getContent(); + item.setSelected(!item.isSelected()); + checkedView.setChecked(item.isSelected()); + if (listener != null) { + listener.categoryClicked(item); } }); } diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java index 983f361a4..338743f02 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java @@ -127,7 +127,7 @@ public class Contribution extends Media { } public String getPageContents() { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(); SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); buffer diff --git a/app/src/main/java/fr/free/nrw/commons/modifications/CategoryModifier.java b/app/src/main/java/fr/free/nrw/commons/modifications/CategoryModifier.java index 8f20c6e50..bb650513b 100644 --- a/app/src/main/java/fr/free/nrw/commons/modifications/CategoryModifier.java +++ b/app/src/main/java/fr/free/nrw/commons/modifications/CategoryModifier.java @@ -33,7 +33,7 @@ public class CategoryModifier extends PageModifier { JSONArray categories; categories = params.optJSONArray(PARAM_CATEGORIES); - StringBuffer categoriesString = new StringBuffer(); + StringBuilder categoriesString = new StringBuilder(); for(int i=0; i < categories.length(); i++) { String category = categories.optString(i); categoriesString.append("\n[[Category:").append(category).append("]]"); diff --git a/app/src/main/java/fr/free/nrw/commons/modifications/ModifierSequence.java b/app/src/main/java/fr/free/nrw/commons/modifications/ModifierSequence.java index 67152f85b..f2accfd51 100644 --- a/app/src/main/java/fr/free/nrw/commons/modifications/ModifierSequence.java +++ b/app/src/main/java/fr/free/nrw/commons/modifications/ModifierSequence.java @@ -48,7 +48,7 @@ public class ModifierSequence { } public String getEditSummary() { - StringBuffer editSummary = new StringBuffer(); + StringBuilder editSummary = new StringBuilder(); for(PageModifier modifier: modifiers) { editSummary.append(modifier.getEditSumary()).append(" "); } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java index 161054053..b3ac11f30 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java @@ -1,7 +1,6 @@ package fr.free.nrw.commons.upload; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; @@ -39,13 +38,10 @@ import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.settings.Prefs; import timber.log.Timber; -public class SingleUploadFragment extends Fragment { - private SharedPreferences prefs; - private String license; +import static android.view.MotionEvent.ACTION_DOWN; +import static android.view.MotionEvent.ACTION_UP; - public interface OnUploadActionInitiated { - void uploadActionInitiated(String title, String description); - } +public class SingleUploadFragment extends Fragment { @BindView(R.id.titleEdit) EditText titleEdit; @BindView(R.id.descEdit) EditText descEdit; @@ -53,13 +49,15 @@ public class SingleUploadFragment extends Fragment { @BindView(R.id.share_license_summary) TextView licenseSummaryView; @BindView(R.id.licenseSpinner) Spinner licenseSpinner; + private SharedPreferences prefs; + private String license; private OnUploadActionInitiated uploadActionInitiatedHandler; private TitleTextWatcher textWatcher = new TitleTextWatcher(); @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.activity_share, menu); - if(titleEdit != null) { + if (titleEdit != null) { menu.findItem(R.id.menu_upload_single).setEnabled(titleEdit.getText().length() != 0); } } @@ -89,7 +87,7 @@ public class SingleUploadFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_single_upload, null); + View rootView = inflater.inflate(R.layout.fragment_single_upload, container, false); ButterKnife.bind(this, rootView); @@ -112,10 +110,10 @@ public class SingleUploadFragment extends Fragment { Timber.d(license); ArrayAdapter adapter; - if (PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean("theme",false)) { + if (PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean("theme", false)) { // dark theme adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_dropdown_item, licenseItems); - }else { + } else { // light theme adapter = new ArrayAdapter<>(getActivity(), R.layout.light_simple_spinner_dropdown_item, licenseItems); } @@ -146,26 +144,27 @@ public class SingleUploadFragment extends Fragment { super.onDestroyView(); } - @OnItemSelected(R.id.licenseSpinner) void onLicenseSelected(AdapterView parent, View view, int position, long id) { + @OnItemSelected(R.id.licenseSpinner) + void onLicenseSelected(AdapterView parent, View view, int position, long id) { String licenseName = parent.getItemAtPosition(position).toString(); // Set selected color to white because it should be readable on random images. TextView selectedText = (TextView) licenseSpinner.getChildAt(0); - if (selectedText != null ) { + if (selectedText != null) { selectedText.setTextColor(Color.WHITE); selectedText.setBackgroundColor(Color.TRANSPARENT); } String license; - if(getString(R.string.license_name_cc0).equals(licenseName)) { + if (getString(R.string.license_name_cc0).equals(licenseName)) { license = Prefs.Licenses.CC0; - } else if(getString(R.string.license_name_cc_by).equals(licenseName)) { + } else if (getString(R.string.license_name_cc_by).equals(licenseName)) { license = Prefs.Licenses.CC_BY_3; - } else if(getString(R.string.license_name_cc_by_sa).equals(licenseName)) { + } else if (getString(R.string.license_name_cc_by_sa).equals(licenseName)) { license = Prefs.Licenses.CC_BY_SA_3; - } else if(getString(R.string.license_name_cc_by_four).equals(licenseName)) { + } else if (getString(R.string.license_name_cc_by_four).equals(licenseName)) { license = Prefs.Licenses.CC_BY_4; - } else if(getString(R.string.license_name_cc_by_sa_four).equals(licenseName)) { + } else if (getString(R.string.license_name_cc_by_sa_four).equals(licenseName)) { license = Prefs.Licenses.CC_BY_SA_4; } else { throw new IllegalStateException("Unknown licenseName: " + licenseName); @@ -177,10 +176,9 @@ public class SingleUploadFragment extends Fragment { editor.commit(); } - - - @OnTouch(R.id.share_license_summary) boolean showLicence(View view, MotionEvent motionEvent) { - if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) { + @OnTouch(R.id.share_license_summary) + boolean showLicence(View view, MotionEvent motionEvent) { + if (motionEvent.getActionMasked() == ACTION_DOWN) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse(Utils.licenseUrlFor(license))); @@ -191,7 +189,8 @@ public class SingleUploadFragment extends Fragment { } } - @OnClick(R.id.titleDescButton) void setTitleDescButton() { + @OnClick(R.id.titleDescButton) + void setTitleDescButton() { //Retrieve last title and desc entered SharedPreferences titleDesc = PreferenceManager.getDefaultSharedPreferences(getActivity()); String title = titleDesc.getString("Title", ""); @@ -205,57 +204,41 @@ public class SingleUploadFragment extends Fragment { /** * Copied from https://stackoverflow.com/a/26269435/8065933 */ - @OnTouch - (R.id.titleEdit) boolean titleInfo(View view, MotionEvent motionEvent) { + @OnTouch(R.id.titleEdit) + boolean titleInfo(View view, MotionEvent motionEvent) { //Should replace right with end to support different right-to-left languages as well final int value = titleEdit.getRight() - titleEdit.getCompoundDrawables()[2].getBounds().width(); - if (motionEvent.getAction() == motionEvent.ACTION_UP && motionEvent.getRawX() >= value) { - - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); - builder.setTitle(R.string.media_detail_title); - builder.setMessage(R.string.title_info); - builder.setCancelable(true); - builder.setNeutralButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - - AlertDialog alert = builder.create(); - alert.show(); + if (motionEvent.getAction() == ACTION_UP && motionEvent.getRawX() >= value) { + new AlertDialog.Builder(getContext()) + .setTitle(R.string.media_detail_title) + .setMessage(R.string.title_info) + .setCancelable(true) + .setNeutralButton(android.R.string.ok, (dialog, id) -> dialog.cancel()) + .create() + .show(); return true; } return false; } - @OnTouch - (R.id.descEdit) boolean descriptionInfo(View view, MotionEvent motionEvent) { + @OnTouch(R.id.descEdit) + boolean descriptionInfo(View view, MotionEvent motionEvent) { final int value = descEdit.getRight() - descEdit.getCompoundDrawables()[2].getBounds().width(); - if (motionEvent.getAction() == motionEvent.ACTION_UP && motionEvent.getRawX() >= value) { - - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); - builder.setTitle(R.string.media_detail_description); - builder.setMessage(R.string.description_info); - builder.setCancelable(true); - builder.setNeutralButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - - AlertDialog alert = builder.create(); - alert.show(); - return true; - + if (motionEvent.getAction() == ACTION_UP && motionEvent.getRawX() >= value) { + new AlertDialog.Builder(getContext()) + .setTitle(R.string.media_detail_description) + .setMessage(R.string.description_info) + .setCancelable(true) + .setNeutralButton(android.R.string.ok, (dialog, id) -> dialog.cancel()) + .create() + .show(); + return true; } return false; } - private void setLicenseSummary(String license) { licenseSummaryView.setText(getString(R.string.share_license_summary, getString(Utils.licenseNameFor(license)))); } @@ -279,16 +262,22 @@ public class SingleUploadFragment extends Fragment { } } + public interface OnUploadActionInitiated { + void uploadActionInitiated(String title, String description); + } + private class TitleTextWatcher implements TextWatcher { @Override - public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { } + public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { + } @Override - public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { } + public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { + } @Override public void afterTextChanged(Editable editable) { - if(getActivity() != null) { + if (getActivity() != null) { getActivity().invalidateOptionsMenu(); } } diff --git a/app/src/main/java/fr/free/nrw/commons/utils/FileUtils.java b/app/src/main/java/fr/free/nrw/commons/utils/FileUtils.java index 4d50f32aa..1c816b9e1 100644 --- a/app/src/main/java/fr/free/nrw/commons/utils/FileUtils.java +++ b/app/src/main/java/fr/free/nrw/commons/utils/FileUtils.java @@ -15,7 +15,7 @@ public class FileUtils { * @return the content of the file */ public static String readFromResource(String fileName) throws IOException { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(); BufferedReader reader = null; try { reader = new BufferedReader( From 15107e622b655d865079dc636d54ec55727b8d10 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Sun, 3 Sep 2017 17:55:45 -0500 Subject: [PATCH 06/13] Codacy suggestions for improvement. --- .../free/nrw/commons/CommonsApplication.java | 6 +- .../java/fr/free/nrw/commons/LicenseList.java | 40 ++---- .../main/java/fr/free/nrw/commons/Media.java | 136 +++++++++--------- .../commons/auth/AuthenticatedActivity.java | 11 +- .../auth/WikiAccountAuthenticator.java | 44 +++--- .../category/CategoryContentProvider.java | 41 +++--- .../contributions/ContributionController.java | 69 +++++---- .../contributions/ContributionsActivity.java | 118 ++++++++------- .../ContributionsContentProvider.java | 75 ++++++---- .../ContributionsListFragment.java | 44 +++--- .../ContributionsSyncAdapter.java | 46 +++--- .../media/MediaDetailPagerFragment.java | 116 +++++++-------- .../nrw/commons/nearby/NearbyInfoDialog.java | 4 +- 13 files changed, 405 insertions(+), 345 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java index f3494d46f..4c44f00f3 100644 --- a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java +++ b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java @@ -220,10 +220,8 @@ public class CommonsApplication extends Application { setIndex(getIndex() + 1); try { - if (accountManagerFuture != null) { - if (accountManagerFuture.getResult()) { - Timber.d("Account removed successfully."); - } + if (accountManagerFuture != null && accountManagerFuture.getResult()) { + Timber.d("Account removed successfully."); } } catch (OperationCanceledException | IOException | AuthenticatorException e) { e.printStackTrace(); diff --git a/app/src/main/java/fr/free/nrw/commons/LicenseList.java b/app/src/main/java/fr/free/nrw/commons/LicenseList.java index 28d5b3f34..382ceee3f 100644 --- a/app/src/main/java/fr/free/nrw/commons/LicenseList.java +++ b/app/src/main/java/fr/free/nrw/commons/LicenseList.java @@ -10,18 +10,16 @@ import java.util.Collection; import java.util.HashMap; import java.util.Locale; import java.util.Map; -import java.util.Set; public class LicenseList { - Map licenses = new HashMap<>(); - Resources res; - - private static String XMLNS_LICENSE = "https://www.mediawiki.org/wiki/Extension:UploadWizard/xmlns/licenses"; + private Map licenses = new HashMap<>(); + private Resources res; public LicenseList(Activity activity) { res = activity.getResources(); XmlPullParser parser = res.getXml(R.xml.wikimedia_licenses); - while (Utils.xmlFastForward(parser, XMLNS_LICENSE, "license")) { + String namespace = "https://www.mediawiki.org/wiki/Extension:UploadWizard/xmlns/licenses"; + while (Utils.xmlFastForward(parser, namespace, "license")) { String id = parser.getAttributeValue(null, "id"); String template = parser.getAttributeValue(null, "template"); String url = parser.getAttributeValue(null, "url"); @@ -31,10 +29,6 @@ public class LicenseList { } } - public Set keySet() { - return licenses.keySet(); - } - public Collection values() { return licenses.values(); } @@ -44,7 +38,7 @@ public class LicenseList { } @Nullable - public License licenseForTemplate(String template) { + License licenseForTemplate(String template) { String ucTemplate = new PageTitle(template).getDisplayText(); for (License license : values()) { if (ucTemplate.equals(new PageTitle(license.getTemplate()).getDisplayText())) { @@ -54,26 +48,16 @@ public class LicenseList { return null; } - public String nameIdForTemplate(String template) { + private String nameIdForTemplate(String template) { // hack :D (converts dashes and periods to underscores) // cc-by-sa-3.0 -> cc_by_sa_3_0 - return "license_name_" + template.toLowerCase(Locale.ENGLISH).replace("-", "_").replace(".", "_"); + return "license_name_" + template.toLowerCase(Locale.ENGLISH).replace("-", + "_").replace(".", "_"); } - private int stringIdByName(String stringId) { - return res.getIdentifier("fr.free.nrw.commons:string/" + stringId, null, null); - } - - public String nameForTemplate(String template) { - //Log.d("Commons", "LicenseList.nameForTemplate: template: " + template); - String stringId = nameIdForTemplate(template); - //Log.d("Commons", "LicenseList.nameForTemplate: stringId: " + stringId); - int nameId = stringIdByName(stringId); - //Log.d("Commons", "LicenseList.nameForTemplate: nameId: " + nameId); - if(nameId != 0) { - //Log.d("Commons", "LicenseList.nameForTemplate: name: " + name); - return res.getString(nameId); - } - return template; + private String nameForTemplate(String template) { + int nameId = res.getIdentifier("fr.free.nrw.commons:string/" + + nameIdForTemplate(template), null, null); + return (nameId != 0) ? res.getString(nameId) : template; } } \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/Media.java b/app/src/main/java/fr/free/nrw/commons/Media.java index 1d07e9c16..26a1d038b 100644 --- a/app/src/main/java/fr/free/nrw/commons/Media.java +++ b/app/src/main/java/fr/free/nrw/commons/Media.java @@ -29,12 +29,66 @@ public class Media implements Parcelable { } }; + private static Pattern displayTitlePattern = Pattern.compile("(.*)(\\.\\w+)", Pattern.CASE_INSENSITIVE); + // Primary metadata fields + protected Uri localUri; + protected String imageUrl; + protected String filename; + protected String description; // monolingual description on input... + protected long dataLength; + protected Date dateCreated; + protected @Nullable Date dateUploaded; + protected int width; + protected int height; + protected String license; + protected String creator; + protected ArrayList categories; // as loaded at runtime? + private Map descriptions; // multilingual descriptions as loaded + private HashMap tags = new HashMap<>(); + private @Nullable LatLng coordinates; + protected Media() { this.categories = new ArrayList<>(); this.descriptions = new HashMap<>(); } - private HashMap tags = new HashMap<>(); + public Media(String filename) { + this(); + this.filename = filename; + } + + public Media(Uri localUri, String imageUrl, String filename, String description, + long dataLength, Date dateCreated, @Nullable Date dateUploaded, String creator) { + this(); + this.localUri = localUri; + this.imageUrl = imageUrl; + this.filename = filename; + this.description = description; + this.dataLength = dataLength; + this.dateCreated = dateCreated; + this.dateUploaded = dateUploaded; + this.creator = creator; + } + + @SuppressWarnings("unchecked") + public Media(Parcel in) { + localUri = in.readParcelable(Uri.class.getClassLoader()); + imageUrl = in.readString(); + filename = in.readString(); + description = in.readString(); + dataLength = in.readLong(); + dateCreated = (Date) in.readSerializable(); + dateUploaded = (Date) in.readSerializable(); + creator = in.readString(); + tags = (HashMap) in.readSerializable(); + width = in.readInt(); + height = in.readInt(); + license = in.readString(); + if (categories != null) { + in.readStringList(categories); + } + descriptions = in.readHashMap(ClassLoader.getSystemClassLoader()); + } public Object getTag(String key) { return tags.get(key); @@ -44,15 +98,14 @@ public class Media implements Parcelable { tags.put(key, value); } - public static Pattern displayTitlePattern = Pattern.compile("(.*)(\\.\\w+)", Pattern.CASE_INSENSITIVE); - public String getDisplayTitle() { - if(filename == null) { + public String getDisplayTitle() { + if (filename == null) { return ""; } // FIXME: Gross hack bercause my regex skills suck maybe or I am too lazy who knows String title = getFilePageTitle().getDisplayText().replaceFirst("^File:", ""); Matcher matcher = displayTitlePattern.matcher(title); - if(matcher.matches()) { + if (matcher.matches()) { return matcher.group(1); } else { return title; @@ -68,7 +121,7 @@ public class Media implements Parcelable { } public String getImageUrl() { - if(imageUrl == null) { + if (imageUrl == null) { imageUrl = Utils.makeThumbBaseUrl(this.getFilename()); } return imageUrl; @@ -86,6 +139,10 @@ public class Media implements Parcelable { return description; } + public void setDescription(String description) { + this.description = description; + } + public long getDataLength() { return dataLength; } @@ -102,7 +159,8 @@ public class Media implements Parcelable { this.dateCreated = date; } - public @Nullable Date getDateUploaded() { + public @Nullable + Date getDateUploaded() { return dateUploaded; } @@ -138,7 +196,8 @@ public class Media implements Parcelable { this.license = license; } - public @Nullable LatLng getCoordinates() { + public @Nullable + LatLng getCoordinates() { return coordinates; } @@ -146,24 +205,9 @@ public class Media implements Parcelable { this.coordinates = coordinates; } - // Primary metadata fields - protected Uri localUri; - protected String imageUrl; - protected String filename; - protected String description; // monolingual description on input... - protected long dataLength; - protected Date dateCreated; - protected @Nullable Date dateUploaded; - protected int width; - protected int height; - protected String license; - private @Nullable LatLng coordinates; - protected String creator; - protected ArrayList categories; // as loaded at runtime? - protected Map descriptions; // multilingual descriptions as loaded - + @SuppressWarnings("unchecked") public ArrayList getCategories() { - return (ArrayList)categories.clone(); // feels dirty + return (ArrayList) categories.clone(); // feels dirty } public void setCategories(List categories) { @@ -171,7 +215,7 @@ public class Media implements Parcelable { this.categories.addAll(categories); } - public void setDescriptions(Map descriptions) { + void setDescriptions(Map descriptions) { for (String key : this.descriptions.keySet()) { this.descriptions.remove(key); } @@ -196,23 +240,6 @@ public class Media implements Parcelable { } } - public Media(String filename) { - this(); - this.filename = filename; - } - - public Media(Uri localUri, String imageUrl, String filename, String description, long dataLength, Date dateCreated, @Nullable Date dateUploaded, String creator) { - this(); - this.localUri = localUri; - this.imageUrl = imageUrl; - this.filename = filename; - this.description = description; - this.dataLength = dataLength; - this.dateCreated = dateCreated; - this.dateUploaded = dateUploaded; - this.creator = creator; - } - @Override public int describeContents() { return 0; @@ -235,27 +262,4 @@ public class Media implements Parcelable { parcel.writeStringList(categories); parcel.writeMap(descriptions); } - - public Media(Parcel in) { - localUri = in.readParcelable(Uri.class.getClassLoader()); - imageUrl = in.readString(); - filename = in.readString(); - description = in.readString(); - dataLength = in.readLong(); - dateCreated = (Date) in.readSerializable(); - dateUploaded = (Date) in.readSerializable(); - creator = in.readString(); - tags = (HashMap)in.readSerializable(); - width = in.readInt(); - height = in.readInt(); - license = in.readString(); - if (categories != null) { - in.readStringList(categories); - } - descriptions = in.readHashMap(ClassLoader.getSystemClassLoader()); - } - - public void setDescription(String description) { - this.description = description; - } } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java index 1fcec5389..4bd608917 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java @@ -18,7 +18,7 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { CommonsApplication app; private String authCookie; - + public AuthenticatedActivity() { this.accountType = AccountUtil.accountType(); } @@ -53,24 +53,24 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { } protected void requestAuthToken() { - if(authCookie != null) { + if (authCookie != null) { onAuthCookieAcquired(authCookie); return; } AccountManager accountManager = AccountManager.get(this); Account curAccount = app.getCurrentAccount(); - if(curAccount == null) { + if (curAccount == null) { addAccount(accountManager); } else { getAuthCookie(curAccount, accountManager); } } - + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); app = CommonsApplication.getInstance(); - if(savedInstanceState != null) { + if (savedInstanceState != null) { authCookie = savedInstanceState.getString("authCookie"); } } @@ -82,5 +82,6 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { } protected abstract void onAuthCookieAcquired(String authCookie); + protected abstract void onAuthFailure(); } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticator.java b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticator.java index 8ecfc67cb..ea574d432 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticator.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/WikiAccountAuthenticator.java @@ -16,21 +16,32 @@ import java.io.IOException; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.mwapi.MediaWikiApi; +import static android.accounts.AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION; +import static android.accounts.AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE; +import static android.accounts.AccountManager.KEY_ACCOUNT_NAME; +import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE; +import static android.accounts.AccountManager.KEY_AUTHTOKEN; +import static android.accounts.AccountManager.KEY_BOOLEAN_RESULT; +import static android.accounts.AccountManager.KEY_ERROR_CODE; +import static android.accounts.AccountManager.KEY_ERROR_MESSAGE; +import static android.accounts.AccountManager.KEY_INTENT; +import static fr.free.nrw.commons.auth.LoginActivity.PARAM_USERNAME; + public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { private Context context; - public WikiAccountAuthenticator(Context context) { + WikiAccountAuthenticator(Context context) { super(context); this.context = context; } private Bundle unsupportedOperation() { Bundle bundle = new Bundle(); - bundle.putInt(AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION); + bundle.putInt(KEY_ERROR_CODE, ERROR_CODE_UNSUPPORTED_OPERATION); // HACK: the docs indicate that this is a required key bit it's not displayed to the user. - bundle.putString(AccountManager.KEY_ERROR_MESSAGE, ""); + bundle.putString(KEY_ERROR_MESSAGE, ""); return bundle; } @@ -54,10 +65,10 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { private Bundle addAccount(AccountAuthenticatorResponse response) { Intent Intent = new Intent(context, LoginActivity.class); - Intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); + Intent.putExtra(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); Bundle bundle = new Bundle(); - bundle.putParcelable(AccountManager.KEY_INTENT, Intent); + bundle.putParcelable(KEY_INTENT, Intent); return bundle; } @@ -78,14 +89,16 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { MediaWikiApi api = CommonsApplication.getInstance().getMWApi(); //TODO add 2fa support here String result = api.login(username, password); - if(result.equals("PASS")) { + if (result.equals("PASS")) { return api.getAuthCookie(); } else { return null; } } + @Override - public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { + public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, + String authTokenType, Bundle options) throws NetworkErrorException { // Extract the username and password from the Account Manager, and ask // the server for an appropriate AuthToken. final AccountManager am = AccountManager.get(context); @@ -101,9 +114,9 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { } if (authCookie != null) { final Bundle result = new Bundle(); - result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); - result.putString(AccountManager.KEY_ACCOUNT_TYPE, AccountUtil.accountType()); - result.putString(AccountManager.KEY_AUTHTOKEN, authCookie); + result.putString(KEY_ACCOUNT_NAME, account.name); + result.putString(KEY_ACCOUNT_TYPE, AccountUtil.accountType()); + result.putString(KEY_AUTHTOKEN, authCookie); return result; } } @@ -112,10 +125,10 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { // need to re-prompt them for their credentials. We do that by creating // an intent to display our AuthenticatorActivity panel. final Intent intent = new Intent(context, LoginActivity.class); - intent.putExtra(LoginActivity.PARAM_USERNAME, account.name); - intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); + intent.putExtra(PARAM_USERNAME, account.name); + intent.putExtra(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); final Bundle bundle = new Bundle(); - bundle.putParcelable(AccountManager.KEY_INTENT, intent); + bundle.putParcelable(KEY_INTENT, intent); return bundle; } @@ -133,7 +146,7 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { @NonNull Account account, @NonNull String[] features) throws NetworkErrorException { Bundle bundle = new Bundle(); - bundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false); + bundle.putBoolean(KEY_BOOLEAN_RESULT, false); return bundle; } @@ -141,8 +154,7 @@ public class WikiAccountAuthenticator extends AbstractAccountAuthenticator { @Override public Bundle updateCredentials(@NonNull AccountAuthenticatorResponse response, @NonNull Account account, @Nullable String authTokenType, - @Nullable Bundle options) - throws NetworkErrorException { + @Nullable Bundle options) throws NetworkErrorException { return unsupportedOperation(); } diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryContentProvider.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryContentProvider.java index e75f1adcf..59db22230 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoryContentProvider.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryContentProvider.java @@ -15,31 +15,39 @@ import fr.free.nrw.commons.data.Category; import fr.free.nrw.commons.data.DBOpenHelper; import timber.log.Timber; +import static android.content.UriMatcher.NO_MATCH; +import static fr.free.nrw.commons.data.Category.Table.ALL_FIELDS; +import static fr.free.nrw.commons.data.Category.Table.COLUMN_ID; +import static fr.free.nrw.commons.data.Category.Table.TABLE_NAME; + public class CategoryContentProvider extends ContentProvider { + public static final String AUTHORITY = "fr.free.nrw.commons.categories.contentprovider"; // For URI matcher private static final int CATEGORIES = 1; private static final int CATEGORIES_ID = 2; - - public static final String AUTHORITY = "fr.free.nrw.commons.categories.contentprovider"; private static final String BASE_PATH = "categories"; public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH); - private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); + private static final UriMatcher uriMatcher = new UriMatcher(NO_MATCH); + static { uriMatcher.addURI(AUTHORITY, BASE_PATH, CATEGORIES); uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", CATEGORIES_ID); } + private DBOpenHelper dbOpenHelper; + public static Uri uriForId(int id) { return Uri.parse(BASE_URI.toString() + "/" + id); } - private DBOpenHelper dbOpenHelper; + @SuppressWarnings("ConstantConditions") @Override public boolean onCreate() { - dbOpenHelper = CommonsApplication.getInstance().getDBOpenHelper(); + CommonsApplication app = ((CommonsApplication) getContext().getApplicationContext()); + dbOpenHelper = app.getDBOpenHelper(); return false; } @@ -48,23 +56,23 @@ public class CategoryContentProvider extends ContentProvider { public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); - queryBuilder.setTables(Category.Table.TABLE_NAME); + queryBuilder.setTables(TABLE_NAME); int uriType = uriMatcher.match(uri); SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); Cursor cursor; - switch(uriType) { + switch (uriType) { case CATEGORIES: cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder); break; case CATEGORIES_ID: cursor = queryBuilder.query(db, - Category.Table.ALL_FIELDS, + ALL_FIELDS, "_id = ?", - new String[] { uri.getLastPathSegment() }, + new String[]{uri.getLastPathSegment()}, null, null, sortOrder @@ -92,7 +100,7 @@ public class CategoryContentProvider extends ContentProvider { long id; switch (uriType) { case CATEGORIES: - id = sqlDB.insert(Category.Table.TABLE_NAME, null, contentValues); + id = sqlDB.insert(TABLE_NAME, null, contentValues); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); @@ -115,9 +123,9 @@ public class CategoryContentProvider extends ContentProvider { sqlDB.beginTransaction(); switch (uriType) { case CATEGORIES: - for(ContentValues value: values) { + for (ContentValues value : values) { Timber.d("Inserting! %s", value); - sqlDB.insert(Category.Table.TABLE_NAME, null, value); + sqlDB.insert(TABLE_NAME, null, value); } break; default: @@ -145,13 +153,12 @@ public class CategoryContentProvider extends ContentProvider { int rowsUpdated; switch (uriType) { case CATEGORIES_ID: - int id = Integer.valueOf(uri.getLastPathSegment()); - if (TextUtils.isEmpty(selection)) { - rowsUpdated = sqlDB.update(Category.Table.TABLE_NAME, + int id = Integer.valueOf(uri.getLastPathSegment()); + rowsUpdated = sqlDB.update(TABLE_NAME, contentValues, - Category.Table.COLUMN_ID + " = ?", - new String[] { String.valueOf(id) } ); + COLUMN_ID + " = ?", + new String[]{String.valueOf(id)}); } else { throw new IllegalArgumentException( "Parameter `selection` should be empty when updating an ID"); diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java index 481b4cc7f..dd867a186 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java @@ -1,11 +1,12 @@ package fr.free.nrw.commons.contributions; -import android.app.Activity; +import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; import android.support.v4.content.FileProvider; import java.io.File; @@ -15,16 +16,25 @@ import fr.free.nrw.commons.upload.ShareActivity; import fr.free.nrw.commons.upload.UploadService; import timber.log.Timber; -public class ContributionController { +import static android.content.Intent.ACTION_GET_CONTENT; +import static android.content.Intent.ACTION_SEND; +import static android.content.Intent.EXTRA_STREAM; +import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION; +import static android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION; +import static android.provider.MediaStore.EXTRA_OUTPUT; +import static fr.free.nrw.commons.contributions.Contribution.SOURCE_CAMERA; +import static fr.free.nrw.commons.contributions.Contribution.SOURCE_GALLERY; +import static fr.free.nrw.commons.upload.UploadService.EXTRA_SOURCE; + +class ContributionController { + + private static final int SELECT_FROM_GALLERY = 1; + private static final int SELECT_FROM_CAMERA = 2; + private Fragment fragment; - private Activity activity; - private final static int SELECT_FROM_GALLERY = 1; - private final static int SELECT_FROM_CAMERA = 2; - - public ContributionController(Fragment fragment) { + ContributionController(Fragment fragment) { this.fragment = fragment; - this.activity = fragment.getActivity(); } // See http://stackoverflow.com/a/5054673/17865 for why this is done @@ -34,43 +44,44 @@ public class ContributionController { File photoFile = new File(fragment.getContext().getCacheDir() + "/images", new Date().getTime() + ".jpg"); photoFile.getParentFile().mkdirs(); + Context applicationContext = fragment.getActivity().getApplicationContext(); return FileProvider.getUriForFile( fragment.getContext(), - fragment.getActivity().getApplicationContext().getPackageName() + ".provider", + applicationContext.getPackageName() + ".provider", photoFile); } - public void startCameraCapture() { - Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + void startCameraCapture() { + Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); lastGeneratedCaptureUri = reGenerateImageCaptureUriInCache(); - takePictureIntent.setFlags( - Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, lastGeneratedCaptureUri); - fragment.startActivityForResult(takePictureIntent, SELECT_FROM_CAMERA); + pictureIntent.setFlags(FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION); + pictureIntent.putExtra(EXTRA_OUTPUT, lastGeneratedCaptureUri); + fragment.startActivityForResult(pictureIntent, SELECT_FROM_CAMERA); } - public void startGalleryPick() { + void startGalleryPick() { //FIXME: Starts gallery (opens Google Photos) - Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT); + Intent pickImageIntent = new Intent(ACTION_GET_CONTENT); pickImageIntent.setType("image/*"); fragment.startActivityForResult(pickImageIntent, SELECT_FROM_GALLERY); } - public void handleImagePicked(int requestCode, Intent data) { + void handleImagePicked(int requestCode, Intent data) { + FragmentActivity activity = fragment.getActivity(); Intent shareIntent = new Intent(activity, ShareActivity.class); - shareIntent.setAction(Intent.ACTION_SEND); - switch(requestCode) { + shareIntent.setAction(ACTION_SEND); + switch (requestCode) { case SELECT_FROM_GALLERY: //Handles image picked from gallery Uri imageData = data.getData(); shareIntent.setType(activity.getContentResolver().getType(imageData)); - shareIntent.putExtra(Intent.EXTRA_STREAM, imageData); - shareIntent.putExtra(UploadService.EXTRA_SOURCE, Contribution.SOURCE_GALLERY); + shareIntent.putExtra(EXTRA_STREAM, imageData); + shareIntent.putExtra(EXTRA_SOURCE, SOURCE_GALLERY); break; case SELECT_FROM_CAMERA: shareIntent.setType("image/jpeg"); //FIXME: Find out appropriate mime type - shareIntent.putExtra(Intent.EXTRA_STREAM, lastGeneratedCaptureUri); - shareIntent.putExtra(UploadService.EXTRA_SOURCE, Contribution.SOURCE_CAMERA); + shareIntent.putExtra(EXTRA_STREAM, lastGeneratedCaptureUri); + shareIntent.putExtra(EXTRA_SOURCE, SOURCE_CAMERA); break; } Timber.i("Image selected"); @@ -81,12 +92,14 @@ public class ContributionController { } } - public void saveState(Bundle outState) { - outState.putParcelable("lastGeneratedCaptureURI", lastGeneratedCaptureUri); + void saveState(Bundle outState) { + if (outState != null) { + outState.putParcelable("lastGeneratedCaptureURI", lastGeneratedCaptureUri); + } } - public void loadState(Bundle savedInstanceState) { - if(savedInstanceState != null) { + void loadState(Bundle savedInstanceState) { + if (savedInstanceState != null) { lastGeneratedCaptureUri = savedInstanceState.getParcelable("lastGeneratedCaptureURI"); } } diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java index fa1d2d96f..f27bfe210 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsActivity.java @@ -1,7 +1,6 @@ package fr.free.nrw.commons.contributions; import android.content.ComponentName; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; @@ -38,13 +37,17 @@ import io.reactivex.disposables.CompositeDisposable; import io.reactivex.schedulers.Schedulers; import timber.log.Timber; -public class ContributionsActivity - extends AuthenticatedActivity - implements LoaderManager.LoaderCallbacks, - AdapterView.OnItemClickListener, - MediaDetailPagerFragment.MediaDetailProvider, - FragmentManager.OnBackStackChangedListener, - ContributionsListFragment.SourceRefresher { +import static android.content.ContentResolver.requestSync; +import static fr.free.nrw.commons.contributions.Contribution.STATE_FAILED; +import static fr.free.nrw.commons.contributions.Contribution.Table.ALL_FIELDS; +import static fr.free.nrw.commons.contributions.ContributionsContentProvider.AUTHORITY; +import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI; +import static fr.free.nrw.commons.settings.Prefs.UPLOADS_SHOWING; + +public class ContributionsActivity extends AuthenticatedActivity + implements LoaderManager.LoaderCallbacks, AdapterView.OnItemClickListener, + MediaDetailPagerFragment.MediaDetailProvider, FragmentManager.OnBackStackChangedListener, + ContributionsListFragment.SourceRefresher { private Cursor allContributions; private ContributionsListFragment contributionsList; @@ -63,14 +66,18 @@ public class ContributionsActivity This is why Contribution.STATE_COMPLETED is -1. */ - private String CONTRIBUTION_SORT = Contribution.Table.COLUMN_STATE + " DESC, " + Contribution.Table.COLUMN_UPLOADED + " DESC , (" + Contribution.Table.COLUMN_TIMESTAMP + " * " + Contribution.Table.COLUMN_STATE + ")"; + private String CONTRIBUTION_SORT = Contribution.Table.COLUMN_STATE + " DESC, " + + Contribution.Table.COLUMN_UPLOADED + " DESC , (" + + Contribution.Table.COLUMN_TIMESTAMP + " * " + + Contribution.Table.COLUMN_STATE + ")"; private CompositeDisposable compositeDisposable = new CompositeDisposable(); private ServiceConnection uploadServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder binder) { - uploadService = (UploadService) ((HandlerService.HandlerServiceLocalBinder)binder).getService(); + uploadService = (UploadService) ((HandlerService.HandlerServiceLocalBinder) binder) + .getService(); isUploadServiceConnected = true; } @@ -86,7 +93,7 @@ public class ContributionsActivity compositeDisposable.clear(); getSupportFragmentManager().removeOnBackStackChangedListener(this); super.onDestroy(); - if(isUploadServiceConnected) { + if (isUploadServiceConnected) { unbindService(uploadServiceConnection); } } @@ -96,9 +103,9 @@ public class ContributionsActivity super.onResume(); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); boolean isSettingsChanged = - sharedPreferences.getBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED,false); + sharedPreferences.getBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED, false); SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED,false); + editor.putBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED, false); editor.apply(); if (isSettingsChanged) { refreshSource(); @@ -107,14 +114,16 @@ public class ContributionsActivity @Override protected void onAuthCookieAcquired(String authCookie) { - // Do a sync everytime we get here! - ContentResolver.requestSync(CommonsApplication.getInstance().getCurrentAccount(), ContributionsContentProvider.AUTHORITY, new Bundle()); + // Do a sync every time we get here! + CommonsApplication app = ((CommonsApplication) getApplication()); + requestSync(app.getCurrentAccount(), AUTHORITY, new Bundle()); Intent uploadServiceIntent = new Intent(this, UploadService.class); uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE); startService(uploadServiceIntent); bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE); - allContributions = getContentResolver().query(ContributionsContentProvider.BASE_URI, Contribution.Table.ALL_FIELDS, CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT); + allContributions = getContentResolver().query(BASE_URI, ALL_FIELDS, + CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT); getSupportLoaderManager().initLoader(0, null, this); } @@ -127,12 +136,13 @@ public class ContributionsActivity // Activity can call methods in the fragment by acquiring a // reference to the Fragment from FragmentManager, using findFragmentById() - contributionsList = (ContributionsListFragment)getSupportFragmentManager() + FragmentManager supportFragmentManager = getSupportFragmentManager(); + contributionsList = (ContributionsListFragment) supportFragmentManager .findFragmentById(R.id.contributionsListFragment); - getSupportFragmentManager().addOnBackStackChangedListener(this); + supportFragmentManager.addOnBackStackChangedListener(this); if (savedInstanceState != null) { - mediaDetails = (MediaDetailPagerFragment)getSupportFragmentManager() + mediaDetails = (MediaDetailPagerFragment) supportFragmentManager .findFragmentById(R.id.contributionsFragmentContainer); } requestAuthToken(); @@ -143,21 +153,25 @@ public class ContributionsActivity @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - outState.putBoolean("mediaDetailsVisible", (mediaDetails != null && mediaDetails.isVisible())); + boolean mediaDetailsVisible = mediaDetails != null && mediaDetails.isVisible(); + outState.putBoolean("mediaDetailsVisible", mediaDetailsVisible); } - /** Replace whatever is in the current contributionsFragmentContainer view with mediaDetailPagerFragment, - / and preserve previous state in back stack. - / Called when user selects a contribution. */ + /** + * Replace whatever is in the current contributionsFragmentContainer view with + * mediaDetailPagerFragment, and preserve previous state in back stack. + * Called when user selects a contribution. + */ private void showDetail(int i) { - if(mediaDetails == null ||!mediaDetails.isVisible()) { + if (mediaDetails == null || !mediaDetails.isVisible()) { mediaDetails = new MediaDetailPagerFragment(); - this.getSupportFragmentManager() + FragmentManager supportFragmentManager = getSupportFragmentManager(); + supportFragmentManager .beginTransaction() .replace(R.id.contributionsFragmentContainer, mediaDetails) .addToBackStack(null) .commit(); - this.getSupportFragmentManager().executePendingTransactions(); + supportFragmentManager.executePendingTransactions(); } mediaDetails.showImage(i); } @@ -165,7 +179,7 @@ public class ContributionsActivity public void retryUpload(int i) { allContributions.moveToPosition(i); Contribution c = Contribution.fromCursor(allContributions); - if(c.getState() == Contribution.STATE_FAILED) { + if (c.getState() == STATE_FAILED) { uploadService.queue(UploadService.ACTION_UPLOAD_FILE, c); Timber.d("Restarting for %s", c.toContentValues()); } else { @@ -176,9 +190,9 @@ public class ContributionsActivity public void deleteUpload(int i) { allContributions.moveToPosition(i); Contribution c = Contribution.fromCursor(allContributions); - if(c.getState() == Contribution.STATE_FAILED) { + if (c.getState() == STATE_FAILED) { Timber.d("Deleting failed contrib %s", c.toContentValues()); - c.setContentProviderClient(getContentResolver().acquireContentProviderClient(ContributionsContentProvider.AUTHORITY)); + c.setContentProviderClient(getContentResolver().acquireContentProviderClient(AUTHORITY)); c.delete(); } else { Timber.d("Skipping deletion for non-failed contrib %s", c.toContentValues()); @@ -187,9 +201,9 @@ public class ContributionsActivity @Override public boolean onOptionsItemSelected(MenuItem item) { - switch(item.getItemId()) { + switch (item.getItemId()) { case android.R.id.home: - if(mediaDetails.isVisible()) { + if (mediaDetails.isVisible()) { getSupportFragmentManager().popBackStack(); } return true; @@ -215,21 +229,20 @@ public class ContributionsActivity @Override public Loader onCreateLoader(int i, Bundle bundle) { - SharedPreferences sharedPref = - PreferenceManager.getDefaultSharedPreferences(this); - int uploads = sharedPref.getInt(Prefs.UPLOADS_SHOWING, 100); - return new CursorLoader(this, ContributionsContentProvider.BASE_URI, - Contribution.Table.ALL_FIELDS, CONTRIBUTION_SELECTION, null, + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); + int uploads = sharedPref.getInt(UPLOADS_SHOWING, 100); + return new CursorLoader(this, BASE_URI, + ALL_FIELDS, CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT + "LIMIT " + uploads); } @Override public void onLoadFinished(Loader cursorLoader, Cursor cursor) { - if(contributionsList.getAdapter() == null) { - contributionsList - .setAdapter(new ContributionsListAdapter(getApplicationContext(), cursor, 0)); + if (contributionsList.getAdapter() == null) { + contributionsList.setAdapter(new ContributionsListAdapter(getApplicationContext(), + cursor, 0)); } else { - ((CursorAdapter)contributionsList.getAdapter()).swapCursor(cursor); + ((CursorAdapter) contributionsList.getAdapter()).swapCursor(cursor); } setUploadCount(); @@ -249,34 +262,32 @@ public class ContributionsActivity if (contributionsList.getAdapter() == null) { // not yet ready to return data return null; - } else { + } else { return Contribution.fromCursor((Cursor) contributionsList.getAdapter().getItem(i)); } } @Override public int getTotalMediaCount() { - if(contributionsList.getAdapter() == null) { + if (contributionsList.getAdapter() == null) { return 0; } return contributionsList.getAdapter().getCount(); } + @SuppressWarnings("ConstantConditions") private void setUploadCount() { - CommonsApplication application = CommonsApplication.getInstance(); - + CommonsApplication app = ((CommonsApplication) getApplication()); compositeDisposable.add( - CommonsApplication.getInstance().getMWApi() - .getUploadCount(application.getCurrentAccount().name) + app.getMWApi() + .getUploadCount(app.getCurrentAccount().name) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( - uploadCount -> - getSupportActionBar().setSubtitle(getResources() - .getQuantityString(R.plurals.contributions_subtitle, - uploadCount, - uploadCount)), - throwable -> Timber.e(throwable, "Fetching upload count failed") + uploadCount -> getSupportActionBar().setSubtitle(getResources() + .getQuantityString(R.plurals.contributions_subtitle, + uploadCount, uploadCount)), + t -> Timber.e(t, "Fetching upload count failed") ) ); } @@ -332,8 +343,7 @@ public class ContributionsActivity } public static void startYourself(Context context) { - Intent contributionsIntent = new Intent(context, ContributionsActivity.class); - context.startActivity(contributionsIntent); + context.startActivity(new Intent(context, ContributionsActivity.class)); } } diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsContentProvider.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsContentProvider.java index 6e84065f2..ec1f02028 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsContentProvider.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsContentProvider.java @@ -13,17 +13,20 @@ import android.text.TextUtils; import fr.free.nrw.commons.CommonsApplication; import timber.log.Timber; -public class ContributionsContentProvider extends ContentProvider{ +import static android.content.UriMatcher.NO_MATCH; +import static fr.free.nrw.commons.contributions.Contribution.Table.ALL_FIELDS; +import static fr.free.nrw.commons.contributions.Contribution.Table.TABLE_NAME; + +public class ContributionsContentProvider extends ContentProvider { private static final int CONTRIBUTIONS = 1; private static final int CONTRIBUTIONS_ID = 2; - - public static final String AUTHORITY = "fr.free.nrw.commons.contributions.contentprovider"; private static final String BASE_PATH = "contributions"; + private static final UriMatcher uriMatcher = new UriMatcher(NO_MATCH); + public static final String AUTHORITY = "fr.free.nrw.commons.contributions.contentprovider"; public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH); - private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { uriMatcher.addURI(AUTHORITY, BASE_PATH, CONTRIBUTIONS); uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", CONTRIBUTIONS_ID); @@ -38,25 +41,29 @@ public class ContributionsContentProvider extends ContentProvider{ return false; } + @SuppressWarnings("ConstantConditions") @Override - public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { + public Cursor query(@NonNull Uri uri, String[] projection, String selection, + String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); - queryBuilder.setTables(Contribution.Table.TABLE_NAME); + queryBuilder.setTables(TABLE_NAME); int uriType = uriMatcher.match(uri); - SQLiteDatabase db = CommonsApplication.getInstance().getDBOpenHelper().getReadableDatabase(); + CommonsApplication app = (CommonsApplication) getContext().getApplicationContext(); + SQLiteDatabase db = app.getDBOpenHelper().getReadableDatabase(); Cursor cursor; - switch(uriType) { + switch (uriType) { case CONTRIBUTIONS: - cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder); + cursor = queryBuilder.query(db, projection, selection, selectionArgs, + null, null, sortOrder); break; case CONTRIBUTIONS_ID: cursor = queryBuilder.query(db, - Contribution.Table.ALL_FIELDS, + ALL_FIELDS, "_id = ?", - new String[] { uri.getLastPathSegment() }, + new String[]{uri.getLastPathSegment()}, null, null, sortOrder @@ -76,14 +83,16 @@ public class ContributionsContentProvider extends ContentProvider{ return null; } + @SuppressWarnings("ConstantConditions") @Override public Uri insert(@NonNull Uri uri, ContentValues contentValues) { int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase(); - long id = 0; + CommonsApplication app = (CommonsApplication) getContext().getApplicationContext(); + SQLiteDatabase sqlDB = app.getDBOpenHelper().getWritableDatabase(); + long id; switch (uriType) { case CONTRIBUTIONS: - id = sqlDB.insert(Contribution.Table.TABLE_NAME, null, contentValues); + id = sqlDB.insert(TABLE_NAME, null, contentValues); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); @@ -92,19 +101,21 @@ public class ContributionsContentProvider extends ContentProvider{ return Uri.parse(BASE_URI + "/" + id); } + @SuppressWarnings("ConstantConditions") @Override public int delete(@NonNull Uri uri, String s, String[] strings) { - int rows = 0; + int rows; int uriType = uriMatcher.match(uri); - SQLiteDatabase db = CommonsApplication.getInstance().getDBOpenHelper().getReadableDatabase(); + CommonsApplication app = (CommonsApplication) getContext().getApplicationContext(); + SQLiteDatabase sqlDB = app.getDBOpenHelper().getWritableDatabase(); - switch(uriType) { + switch (uriType) { case CONTRIBUTIONS_ID: Timber.d("Deleting contribution id %s", uri.getLastPathSegment()); - rows = db.delete(Contribution.Table.TABLE_NAME, + rows = sqlDB.delete(TABLE_NAME, "_id = ?", - new String[] { uri.getLastPathSegment() } + new String[]{uri.getLastPathSegment()} ); break; default: @@ -114,17 +125,19 @@ public class ContributionsContentProvider extends ContentProvider{ return rows; } + @SuppressWarnings("ConstantConditions") @Override public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) { Timber.d("Hello, bulk insert! (ContributionsContentProvider)"); int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase(); + CommonsApplication app = (CommonsApplication) getContext().getApplicationContext(); + SQLiteDatabase sqlDB = app.getDBOpenHelper().getWritableDatabase(); sqlDB.beginTransaction(); switch (uriType) { case CONTRIBUTIONS: - for(ContentValues value: values) { + for (ContentValues value : values) { Timber.d("Inserting! %s", value); - sqlDB.insert(Contribution.Table.TABLE_NAME, null, value); + sqlDB.insert(TABLE_NAME, null, value); } break; default: @@ -136,6 +149,7 @@ public class ContributionsContentProvider extends ContentProvider{ return values.length; } + @SuppressWarnings("ConstantConditions") @Override public int update(@NonNull Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) { /* @@ -146,25 +160,24 @@ public class ContributionsContentProvider extends ContentProvider{ In here, the only concat created argument is for id. It is cast to an int, and will error out otherwise. */ int uriType = uriMatcher.match(uri); - SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase(); - int rowsUpdated = 0; + CommonsApplication app = (CommonsApplication) getContext().getApplicationContext(); + SQLiteDatabase sqlDB = app.getDBOpenHelper().getWritableDatabase(); + int rowsUpdated; switch (uriType) { case CONTRIBUTIONS: - rowsUpdated = sqlDB.update(Contribution.Table.TABLE_NAME, - contentValues, - selection, - selectionArgs); + rowsUpdated = sqlDB.update(TABLE_NAME, contentValues, selection, selectionArgs); break; case CONTRIBUTIONS_ID: int id = Integer.valueOf(uri.getLastPathSegment()); if (TextUtils.isEmpty(selection)) { - rowsUpdated = sqlDB.update(Contribution.Table.TABLE_NAME, + rowsUpdated = sqlDB.update(TABLE_NAME, contentValues, Contribution.Table.COLUMN_ID + " = ?", - new String[] { String.valueOf(id) } ); + new String[]{String.valueOf(id)}); } else { - throw new IllegalArgumentException("Parameter `selection` should be empty when updating an ID"); + throw new IllegalArgumentException( + "Parameter `selection` should be empty when updating an ID"); } break; default: diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java index 3ead40bcf..b93a21fde 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java @@ -1,9 +1,7 @@ package fr.free.nrw.commons.contributions; -import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; @@ -30,17 +28,15 @@ import timber.log.Timber; import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.app.Activity.RESULT_OK; +import static android.content.Context.MODE_PRIVATE; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.view.View.GONE; public class ContributionsListFragment extends Fragment { - public interface SourceRefresher { - void refreshSource(); - } - @BindView(R.id.contributionsList) GridView contributionsList; @BindView(R.id.waitingMessage) TextView waitingMessage; @BindView(R.id.emptyMessage) TextView emptyMessage; - private ContributionController controller; @Override @@ -48,21 +44,21 @@ public class ContributionsListFragment extends Fragment { View v = inflater.inflate(R.layout.fragment_contributions, container, false); ButterKnife.bind(this, v); - contributionsList.setOnItemClickListener((AdapterView.OnItemClickListener)getActivity()); - if(savedInstanceState != null) { + contributionsList.setOnItemClickListener((AdapterView.OnItemClickListener) getActivity()); + if (savedInstanceState != null) { Timber.d("Scrolling to %d", savedInstanceState.getInt("grid-position")); contributionsList.setSelection(savedInstanceState.getInt("grid-position")); } //TODO: Should this be in onResume? - SharedPreferences prefs = this.getActivity().getSharedPreferences("prefs", Context.MODE_PRIVATE); + SharedPreferences prefs = getActivity().getSharedPreferences("prefs", MODE_PRIVATE); String lastModified = prefs.getString("lastSyncTimestamp", ""); Timber.d("Last Sync Timestamp: %s", lastModified); if (lastModified.equals("")) { waitingMessage.setVisibility(View.VISIBLE); } else { - waitingMessage.setVisibility(View.GONE); + waitingMessage.setVisibility(GONE); } return v; @@ -91,7 +87,7 @@ public class ContributionsListFragment extends Fragment { //FIXME: must get the file data for Google Photos when receive the intent answer, in the onActivityResult method super.onActivityResult(requestCode, resultCode, data); - if ( resultCode == RESULT_OK ) { + if (resultCode == RESULT_OK) { Timber.d("OnActivityResult() parameters: Req code: %d Result code: %d Data: %s", requestCode, resultCode, data); controller.handleImagePicked(requestCode, data); @@ -103,7 +99,7 @@ public class ContributionsListFragment extends Fragment { @Override public boolean onOptionsItemSelected(MenuItem item) { - switch(item.getItemId()) { + switch (item.getItemId()) { case R.id.menu_from_gallery: //Gallery crashes before reach ShareActivity screen so must implement permissions check here if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { @@ -111,7 +107,7 @@ public class ContributionsListFragment extends Fragment { // Here, thisActivity is the current activity if (ContextCompat.checkSelfPermission(getActivity(), READ_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { + != PERMISSION_GRANTED) { // Should we show an explanation? if (shouldShowRequestPermissionRationale(READ_EXTERNAL_STORAGE)) { @@ -161,14 +157,15 @@ public class ContributionsListFragment extends Fragment { } @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - - Timber.d("onRequestPermissionsResult: req code = " + " perm = " + permissions + " grant =" + grantResults); + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, + @NonNull int[] grantResults) { + Timber.d("onRequestPermissionsResult: req code = " + " perm = " + + permissions + " grant =" + grantResults); switch (requestCode) { // 1 = Storage allowed when gallery selected case 1: { - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) { Timber.d("Call controller.startGalleryPick()"); controller.startGalleryPick(); } @@ -176,7 +173,7 @@ public class ContributionsListFragment extends Fragment { break; // 2 = Location allowed when 'nearby places' selected case 2: { - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) { Timber.d("Location permission granted"); Intent nearbyIntent = new Intent(getActivity(), NearbyActivity.class); startActivity(nearbyIntent); @@ -191,7 +188,8 @@ public class ContributionsListFragment extends Fragment { menu.clear(); // See http://stackoverflow.com/a/8495697/17865 inflater.inflate(R.menu.fragment_contributions_list, menu); - if (!CommonsApplication.getInstance().deviceHasCamera()) { + CommonsApplication app = (CommonsApplication) getContext().getApplicationContext(); + if (!app.deviceHasCamera()) { menu.findItem(R.id.menu_from_camera).setEnabled(false); } } @@ -215,6 +213,10 @@ public class ContributionsListFragment extends Fragment { } protected void clearSyncMessage() { - waitingMessage.setVisibility(View.GONE); + waitingMessage.setVisibility(GONE); + } + + public interface SourceRefresher { + void refreshSource(); } } diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsSyncAdapter.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsSyncAdapter.java index 6d769e94c..fdcc52380 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsSyncAdapter.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsSyncAdapter.java @@ -23,8 +23,18 @@ import fr.free.nrw.commons.mwapi.LogEventResult; import fr.free.nrw.commons.mwapi.MediaWikiApi; import timber.log.Timber; +import static android.content.Context.MODE_PRIVATE; +import static fr.free.nrw.commons.contributions.Contribution.STATE_COMPLETED; +import static fr.free.nrw.commons.contributions.Contribution.Table.COLUMN_FILENAME; +import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI; + public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { + + private static final String[] existsQuery = {COLUMN_FILENAME}; + private static final String existsSelection = COLUMN_FILENAME + " = ?"; + private static final ContentValues[] EMPTY = {}; private static int COMMIT_THRESHOLD = 10; + public ContributionsSyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); } @@ -36,39 +46,38 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { return limit; // FIXME: Parameterize! } - private static final String[] existsQuery = { Contribution.Table.COLUMN_FILENAME }; - private static final String existsSelection = Contribution.Table.COLUMN_FILENAME + " = ?"; private boolean fileExists(ContentProviderClient client, String filename) { Cursor cursor = null; try { - cursor = client.query(ContributionsContentProvider.BASE_URI, + cursor = client.query(BASE_URI, existsQuery, existsSelection, - new String[] { filename }, + new String[]{filename}, "" ); - return cursor.getCount() != 0; + return cursor != null && cursor.getCount() != 0; } catch (RemoteException e) { throw new RuntimeException(e); } finally { - if ( cursor != null ) { + if (cursor != null) { cursor.close(); } } } @Override - public void onPerformSync(Account account, Bundle bundle, String s, ContentProviderClient contentProviderClient, SyncResult syncResult) { + public void onPerformSync(Account account, Bundle bundle, String authority, + ContentProviderClient contentProviderClient, SyncResult syncResult) { // This code is fraught with possibilities of race conditions, but lalalalala I can't hear you! String user = account.name; MediaWikiApi api = CommonsApplication.getInstance().getMWApi(); - SharedPreferences prefs = this.getContext().getSharedPreferences("prefs", Context.MODE_PRIVATE); + SharedPreferences prefs = getContext().getSharedPreferences("prefs", MODE_PRIVATE); String lastModified = prefs.getString("lastSyncTimestamp", ""); Date curTime = new Date(); LogEventResult result; Boolean done = false; String queryContinue = null; - while(!done) { + while (!done) { try { result = api.logEvents(user, lastModified, queryContinue, getLimit()); @@ -90,19 +99,21 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { continue; } String filename = image.getFilename(); - if(fileExists(contentProviderClient, filename)) { + if (fileExists(contentProviderClient, filename)) { Timber.d("Skipping %s", filename); continue; } String thumbUrl = Utils.makeThumbBaseUrl(filename); Date dateUpdated = image.getDateUpdated(); - Contribution contrib = new Contribution(null, thumbUrl, filename, "", -1, dateUpdated, dateUpdated, user, "", ""); - contrib.setState(Contribution.STATE_COMPLETED); + Contribution contrib = new Contribution(null, thumbUrl, filename, + "", -1, dateUpdated, dateUpdated, user, + "", ""); + contrib.setState(STATE_COMPLETED); imageValues.add(contrib.toContentValues()); - if(imageValues.size() % COMMIT_THRESHOLD == 0) { + if (imageValues.size() % COMMIT_THRESHOLD == 0) { try { - contentProviderClient.bulkInsert(ContributionsContentProvider.BASE_URI, imageValues.toArray(new ContentValues[]{})); + contentProviderClient.bulkInsert(BASE_URI, imageValues.toArray(EMPTY)); } catch (RemoteException e) { throw new RuntimeException(e); } @@ -110,20 +121,21 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { } } - if(imageValues.size() != 0) { + if (imageValues.size() != 0) { try { - contentProviderClient.bulkInsert(ContributionsContentProvider.BASE_URI, imageValues.toArray(new ContentValues[]{})); + contentProviderClient.bulkInsert(BASE_URI, imageValues.toArray(EMPTY)); } catch (RemoteException e) { throw new RuntimeException(e); } } queryContinue = result.getQueryContinue(); - if(TextUtils.isEmpty(queryContinue)) { + if (TextUtils.isEmpty(queryContinue)) { done = true; } } prefs.edit().putString("lastSyncTimestamp", Utils.toMWDate(curTime)).apply(); Timber.d("Oh hai, everyone! Look, a kitty!"); } + } diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java index 271ac5c92..42c463dca 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java @@ -1,11 +1,8 @@ package fr.free.nrw.commons.media; -import android.Manifest; import android.annotation.SuppressLint; import android.app.DownloadManager; -import android.content.Context; import android.content.Intent; -import android.content.pm.PackageManager; import android.database.DataSetObserver; import android.net.Uri; import android.os.Build; @@ -34,23 +31,16 @@ import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.contributions.ContributionsActivity; import fr.free.nrw.commons.mwapi.EventLog; +import static android.Manifest.permission.READ_EXTERNAL_STORAGE; +import static android.content.Context.DOWNLOAD_SERVICE; +import static android.content.Intent.ACTION_VIEW; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static fr.free.nrw.commons.CommonsApplication.EVENT_SHARE_ATTEMPT; + public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPageChangeListener { - public interface MediaDetailProvider { - Media getMediaAtPosition(int i); - - int getTotalMediaCount(); - - void notifyDatasetChanged(); - - void registerDataSetObserver(DataSetObserver observer); - - void unregisterDataSetObserver(DataSetObserver observer); - } - private ViewPager pager; private Boolean editable; - private CommonsApplication app; public MediaDetailPagerFragment() { this(false); @@ -61,30 +51,10 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa this.editable = editable; } - //FragmentStatePagerAdapter allows user to swipe across collection of images (no. of images undetermined) - private class MediaDetailAdapter extends FragmentStatePagerAdapter { - - public MediaDetailAdapter(FragmentManager fm) { - super(fm); - } - - @Override - public Fragment getItem(int i) { - if (i == 0) { - // See bug https://code.google.com/p/android/issues/detail?id=27526 - pager.postDelayed(() -> getActivity().supportInvalidateOptionsMenu(), 5); - } - return MediaDetailFragment.forMedia(i, editable); - } - - @Override - public int getCount() { - return ((MediaDetailProvider)getActivity()).getTotalMediaCount(); - } - } - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + public View onCreateView(LayoutInflater inflater, + ViewGroup container, + Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_media_detail_pager, container, false); pager = (ViewPager) view.findViewById(R.id.mediaDetailsPager); pager.addOnPageChangeListener(this); @@ -120,18 +90,18 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa if (savedInstanceState != null) { editable = savedInstanceState.getBoolean("editable"); } - app = CommonsApplication.getInstance(); setHasOptionsMenu(true); } @Override public boolean onOptionsItemSelected(MenuItem item) { - MediaDetailProvider provider = (MediaDetailProvider)getActivity(); + MediaDetailProvider provider = (MediaDetailProvider) getActivity(); Media m = provider.getMediaAtPosition(pager.getCurrentItem()); - switch(item.getItemId()) { + switch (item.getItemId()) { case R.id.menu_share_current_image: // Share - this is just logs it, intent set in onCreateOptionsMenu, around line 252 - EventLog.schema(CommonsApplication.EVENT_SHARE_ATTEMPT) + CommonsApplication app = (CommonsApplication) getActivity().getApplication(); + EventLog.schema(EVENT_SHARE_ATTEMPT) .param("username", app.getCurrentAccount().name) .param("filename", m.getFilename()) .log(); @@ -139,7 +109,7 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa case R.id.menu_browser_current_image: // View in browser Intent viewIntent = new Intent(); - viewIntent.setAction(Intent.ACTION_VIEW); + viewIntent.setAction(ACTION_VIEW); viewIntent.setData(m.getFilePageTitle().getMobileUri()); startActivity(viewIntent); return true; @@ -149,12 +119,12 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa return true; case R.id.menu_retry_current_image: // Retry - ((ContributionsActivity)getActivity()).retryUpload(pager.getCurrentItem()); + ((ContributionsActivity) getActivity()).retryUpload(pager.getCurrentItem()); getActivity().getSupportFragmentManager().popBackStack(); return true; case R.id.menu_cancel_current_image: // todo: delete image - ((ContributionsActivity)getActivity()).deleteUpload(pager.getCurrentItem()); + ((ContributionsActivity) getActivity()).deleteUpload(pager.getCurrentItem()); getActivity().getSupportFragmentManager().popBackStack(); return true; default: @@ -170,7 +140,7 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa */ private void downloadMedia(Media m) { String imageUrl = m.getImageUrl(), - fileName = m.getFilename(); + fileName = m.getFilename(); // Strip 'File:' from beginning of filename, we really shouldn't store it fileName = fileName.replaceFirst("^File:", ""); Uri imageUri = Uri.parse(imageUrl); @@ -185,14 +155,15 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa req.allowScanningByMediaScanner(); req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !(ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M + && !(ContextCompat.checkSelfPermission(getContext(), + READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED)) { Snackbar.make(getView(), R.string.storage_permission_rationale, - Snackbar.LENGTH_INDEFINITE) - .setAction(R.string.ok, view -> ActivityCompat.requestPermissions(getActivity(), - new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1)).show(); + Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok, + view -> ActivityCompat.requestPermissions(getActivity(), + new String[]{READ_EXTERNAL_STORAGE}, 1)).show(); } else { - final DownloadManager manager = (DownloadManager)getActivity().getSystemService(Context.DOWNLOAD_SERVICE); - manager.enqueue(req); + ((DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE)).enqueue(req); } } @@ -202,7 +173,7 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa menu.clear(); // see http://stackoverflow.com/a/8495697/17865 inflater.inflate(R.menu.fragment_image_detail, menu); if (pager != null) { - MediaDetailProvider provider = (MediaDetailProvider)getActivity(); + MediaDetailProvider provider = (MediaDetailProvider) getActivity(); Media m = provider.getMediaAtPosition(pager.getCurrentItem()); if (m != null) { // Enable default set of actions, then re-enable different set of actions only if it is a failed contrib @@ -225,8 +196,8 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa } if (m instanceof Contribution) { - Contribution c = (Contribution)m; - switch(c.getState()) { + Contribution c = (Contribution) m; + switch (c.getState()) { case Contribution.STATE_FAILED: menu.findItem(R.id.menu_retry_current_image).setEnabled(true).setVisible(true); menu.findItem(R.id.menu_cancel_current_image).setEnabled(true).setVisible(true); @@ -267,6 +238,39 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa @Override public void onPageScrollStateChanged(int i) { + } + public interface MediaDetailProvider { + Media getMediaAtPosition(int i); + + int getTotalMediaCount(); + + void notifyDatasetChanged(); + + void registerDataSetObserver(DataSetObserver observer); + + void unregisterDataSetObserver(DataSetObserver observer); + } + + //FragmentStatePagerAdapter allows user to swipe across collection of images (no. of images undetermined) + private class MediaDetailAdapter extends FragmentStatePagerAdapter { + + public MediaDetailAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int i) { + if (i == 0) { + // See bug https://code.google.com/p/android/issues/detail?id=27526 + pager.postDelayed(() -> getActivity().supportInvalidateOptionsMenu(), 5); + } + return MediaDetailFragment.forMedia(i, editable); + } + + @Override + public int getCount() { + return ((MediaDetailProvider) getActivity()).getTotalMediaCount(); + } } } \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyInfoDialog.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyInfoDialog.java index 1203d5a0d..2e677f33d 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyInfoDialog.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyInfoDialog.java @@ -63,10 +63,10 @@ public class NearbyInfoDialog extends OverlayDialog { overflowButton.setVisibility(showMenu() ? View.VISIBLE : View.GONE); - overflowButton.setOnClickListener(this::popupMenuListener); + overflowButton.setOnClickListener(v -> popupMenuListener()); } - private void popupMenuListener(View v) { + private void popupMenuListener() { PopupMenu popupMenu = new PopupMenu(getActivity(), overflowButton); popupMenu.inflate(R.menu.nearby_info_dialog_options); From 1c50e8539b2362f2a1ee76927fc30a3804c8ea37 Mon Sep 17 00:00:00 2001 From: Neslihan Date: Tue, 12 Sep 2017 22:47:31 +0300 Subject: [PATCH 07/13] Request write permission for older android versions, too. --- .../contributions/ContributionController.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java index 481b4cc7f..35df0a606 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java @@ -1,7 +1,10 @@ package fr.free.nrw.commons.contributions; import android.app.Activity; +import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; @@ -10,6 +13,7 @@ import android.support.v4.content.FileProvider; import java.io.File; import java.util.Date; +import java.util.List; import fr.free.nrw.commons.upload.ShareActivity; import fr.free.nrw.commons.upload.UploadService; @@ -41,14 +45,28 @@ public class ContributionController { } public void startCameraCapture() { + Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); lastGeneratedCaptureUri = reGenerateImageCaptureUriInCache(); - takePictureIntent.setFlags( - Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + + // Intent.setFlags doesn't work for API level <20 + requestWritePermission(fragment.getContext(), takePictureIntent, lastGeneratedCaptureUri); + takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, lastGeneratedCaptureUri); fragment.startActivityForResult(takePictureIntent, SELECT_FROM_CAMERA); } + private static void requestWritePermission(Context context, Intent intent, Uri uri){ + + List resInfoList = context.getPackageManager().queryIntentActivities(intent, + PackageManager.MATCH_DEFAULT_ONLY); + for (ResolveInfo resolveInfo : resInfoList) { + String packageName = resolveInfo.activityInfo.packageName; + context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | + Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + } + public void startGalleryPick() { //FIXME: Starts gallery (opens Google Photos) Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT); From c52c0b4a7f24248e04a539540a92cbec77c03c71 Mon Sep 17 00:00:00 2001 From: Neslihan Date: Tue, 12 Sep 2017 22:47:57 +0300 Subject: [PATCH 08/13] Fix coding style --- .../free/nrw/commons/contributions/ContributionController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java index 35df0a606..dd5f99190 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java @@ -56,7 +56,7 @@ public class ContributionController { fragment.startActivityForResult(takePictureIntent, SELECT_FROM_CAMERA); } - private static void requestWritePermission(Context context, Intent intent, Uri uri){ + private static void requestWritePermission(Context context, Intent intent, Uri uri) { List resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); From 4d9e63227c8239b1bd63040d7c9bf85f6ff1fce1 Mon Sep 17 00:00:00 2001 From: Neslihan Date: Tue, 12 Sep 2017 23:14:58 +0300 Subject: [PATCH 09/13] Fix codacy issue --- .../nrw/commons/contributions/ContributionController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java index dd5f99190..96dc171d9 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java @@ -62,8 +62,8 @@ public class ContributionController { PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo : resInfoList) { String packageName = resolveInfo.activityInfo.packageName; - context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | - Intent.FLAG_GRANT_READ_URI_PERMISSION); + context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION + | Intent.FLAG_GRANT_READ_URI_PERMISSION); } } From 1253f76e0140a23c0ae952b668024a6c3fdecca1 Mon Sep 17 00:00:00 2001 From: "translatewiki.net" Date: Thu, 14 Sep 2017 07:15:25 +0200 Subject: [PATCH 10/13] Localisation updates from https://translatewiki.net. --- app/src/main/res/values-ar/strings.xml | 8 ++++++++ app/src/main/res/values-pl/strings.xml | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 108eadc9b..513fdc47c 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -47,6 +47,8 @@ تصنيفات البحث احفظ أنعش + تفعيل GPS + لا مرفوعات بعد لا توجد تصنيفات تطابق %1$s أضف التصانيف لتسهل اكتشاف صورك على ويكيميديا كومنز.\n\nابدأ الكتاب لتضيف التصانيف.\nانقر هذه الرسالة لتتجاوز هذه الخطوة. تصنيفات @@ -85,6 +87,12 @@ نعم لا العنوان + عنوان الوسيط الوصف + الترخيص + الإحداثيات + استخدم ويكي بيانات + الرئيسية الإعدادات + صفحة ملف كومنز diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 58d8f01e5..ac4298055 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -42,6 +42,7 @@ Nie można zalogować - sprawdź hasło Zbyt wiele nieudanych prób zalogowania. Spróbuj ponownie za kilka minut. Przepraszamy, ten użytkownik został zablokowany na Commons + Wprowadź swój kod dla dwuetapowej autoryzacji. Logowanie nie powiodło się Prześlij Nazwij ten zestaw @@ -52,6 +53,7 @@ Odśwież GPS w twoim urządzeniu jest wyłączony. Czy chcesz go włączyć? Włącz GPS + Na razie brak przesłanych plików! Przesłano @string/contributions_subtitle_zero Przesłano %d plik @@ -151,6 +153,8 @@ Dołącz do kanału bety w Google Play i dostań wczesny dostęp do nowych funkcji i łatek Użyj Wikidanych Kod 2FA + Górna Granica + Nie można wyświetlić ponad 500 Uwierzytelnianie dwuskładnikowe obecnie nie jest obsługiwane. Czy na pewno wylogować? Logo Commons @@ -160,8 +164,10 @@ Lamy Rainbow Bridge Tulipan + Brak Selfie Witaj na Wikipedii Witaj w prawach autorskich. + Opera Sydnej Anuluj Otwórz Zamknij From 3b5811921cd3a95aeb57a14cce4b9f9d674797bb Mon Sep 17 00:00:00 2001 From: Vishan Seru Date: Sat, 16 Sep 2017 20:12:57 +0530 Subject: [PATCH 11/13] Moved sign up process redirection urls to build.gradle as buildConfig fields specific to beta and prod flavors and added necessary usages to SignupActivity --- app/build.gradle | 4 ++++ .../main/java/fr/free/nrw/commons/auth/SignupActivity.java | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4358c4699..69819c3f6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -86,6 +86,8 @@ android { buildConfigField "String", "MOBILE_HOME_URL", "\"https://commons.m.wikimedia.org/wiki/\"" buildConfigField "String", "EVENTLOG_URL", "\"https://www.wikimedia.org/beacon/event\"" buildConfigField "String", "EVENTLOG_WIKI", "\"commonswiki\"" + buildConfigField "String", "SIGNUP_LANDING_URL", "\"https://commons.m.wikimedia.org/w/index.php?title=Special:CreateAccount&returnto=Main+Page&returntoquery=welcome%3Dyes\"" + buildConfigField "String", "SIGNUP_SUCCESS_REDIRECTION_URL", "\"https://commons.m.wikimedia.org/w/index.php?title=Main_Page&welcome=yes\"" } beta { @@ -97,6 +99,8 @@ android { buildConfigField "String", "MOBILE_HOME_URL", "\"https://commons.m.wikimedia.beta.wmflabs.org/wiki/\"" buildConfigField "String", "EVENTLOG_URL", "\"https://commons.wikimedia.beta.wmflabs.org/beacon/event\"" buildConfigField "String", "EVENTLOG_WIKI", "\"commonswiki\"" + buildConfigField "String", "SIGNUP_LANDING_URL", "\"https://commons.m.wikimedia.beta.wmflabs.org/w/index.php?title=Special:CreateAccount&returnto=Main+Page&returntoquery=welcome%3Dyes\"" + buildConfigField "String", "SIGNUP_SUCCESS_REDIRECTION_URL", "\"https://commons.m.wikimedia.beta.wmflabs.org/w/index.php?title=Main_Page&welcome=yes\"" } } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java index db810fa84..72b16f223 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java @@ -6,6 +6,7 @@ import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; +import fr.free.nrw.commons.BuildConfig; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.theme.BaseActivity; import timber.log.Timber; @@ -27,13 +28,13 @@ public class SignupActivity extends BaseActivity { //Needed to refresh Captcha. Might introduce XSS vulnerabilities, but we can trust Wikimedia's site... right? webSettings.setJavaScriptEnabled(true); - webView.loadUrl("https://commons.m.wikimedia.org/w/index.php?title=Special:CreateAccount&returnto=Main+Page&returntoquery=welcome%3Dyes"); + webView.loadUrl(BuildConfig.SIGNUP_LANDING_URL); } private class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (url.equals("https://commons.m.wikimedia.org/w/index.php?title=Main_Page&welcome=yes")) { + if (url.equals(BuildConfig.SIGNUP_SUCCESS_REDIRECTION_URL)) { //Signup success, so clear cookies, notify user, and load LoginActivity again Timber.d("Overriding URL %s", url); From b3a0093c2c116ffcaa900e4db477c83fa4fd27cb Mon Sep 17 00:00:00 2001 From: "translatewiki.net" Date: Mon, 18 Sep 2017 13:14:47 +0200 Subject: [PATCH 12/13] Localisation updates from https://translatewiki.net. --- app/src/main/res/values-ar/strings.xml | 6 +++++ app/src/main/res/values-diq/strings.xml | 7 +++++ app/src/main/res/values-sd/strings.xml | 36 ++++++++++++++++++++----- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 513fdc47c..471896835 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -83,6 +83,7 @@ ترخيص غير معلوم تحديث موافق + الأماكن القريبة تحذير نعم لا @@ -92,7 +93,12 @@ الترخيص الإحداثيات استخدم ويكي بيانات + الحد الأقصى الرئيسية + رفع + بالقرب من هنا + حول الإعدادات + تسجيل الخروج صفحة ملف كومنز diff --git a/app/src/main/res/values-diq/strings.xml b/app/src/main/res/values-diq/strings.xml index 8d04e2d08..6a4485828 100644 --- a/app/src/main/res/values-diq/strings.xml +++ b/app/src/main/res/values-diq/strings.xml @@ -111,4 +111,11 @@ Tembe kem E + Sername + Lisans + Koordinati + Bıtexelne + Ake + Keye + Bar ke diff --git a/app/src/main/res/values-sd/strings.xml b/app/src/main/res/values-sd/strings.xml index 36a914281..69b135129 100644 --- a/app/src/main/res/values-sd/strings.xml +++ b/app/src/main/res/values-sd/strings.xml @@ -2,7 +2,7 @@ العام ترتيبون - يُوزرنانءُ + واھپ (يوزر)-نانءُ ڳجھولفظ داخل ٿيو کاتو کوليو @@ -20,11 +20,11 @@ %1$s جو چاڙھ مڪمل ٿيندي %1$s جو چاڙھڻ ناڪام ويو ڏسڻ لاءِ ٺونگيو - - 1 فائيل چاڙھيندي + + %d فائيل چاڙھيندي %d فائيلَ چاڙھيندي - منھنجا چاڙھ + منھنجا تازا چاڙھ قطار ۾ ناڪام %1$d%% مڪمل @@ -38,7 +38,7 @@ عنوان تشريح ناقابلِ داخل ٿيڻ - باھمڄار ناڪامي - ناقابلِ داخل ٿيڻ - براءِ مھرباني پنھنجو يُوزرنانءُ چڪاسيو + ناقابلِ داخل ٿيڻ - براءِ مھرباني پنھنجو واھپ (يوزر)-نانءُ چڪاسيو ناقابل داخل ٿيڻ - براءِ مھرباني پنھنجو ڳجھولفظ چڪاسيو ھيڪانديون ناڪام ڪوششون. براءِ مھرباني ڪجھ منٽن کانپوءِ ٻيھر ڪوشش ڪريو. افسوس، ھي واھپ العام تي بندشيل آھي @@ -50,6 +50,8 @@ زمرا ڳوليو سانڍيو تازو ڪيو + جي پي ايس چالو ڪيو (اين ايبل جي پي ايس) + اڃان تائين ڪو به ڄاڙهه (اَپلوڊ) نه ٿيو آهي اڃان تائين ڪو چاڙھ ناھي 1 چاڙھ @@ -121,7 +123,7 @@ توھان سمجھو ٿا توھان سمجھي ويئو؟ ھا! زمرا - اتاريندي… + لاهيندي (لوڊنگ) ڪوبہ چونڊيل ناھي ڪا تشريح ناھي اڻڄاتل لائسنس @@ -137,6 +139,28 @@ عنوان ابلاغ جو عنوان تشريح + چاڙهڻ جي تاريخ (اَپلوڊ ڊيٽ) + لائسنس (اجازت نامو) آزمائشي آزمائيندڙ ٿيو وڪيڊيٽا استعماڪ ڪريو + منهنجي تازي چاڙهڻ (اَپلوڊ) جي حد (لِمٽ) + وڌ ۾ وڌ حد (ميگزيمم لِمٽ) + ڪا به تصوير نه ملي + تصوير چاڙهيو (اَپلوڊ اميج) + گل لالا (ٽيولپ) + ڪي به پاڻفيون نه (نو سيلفيز) + سڃاڻپ واري تصوير (پروپرائٽري اميج) + وڪيپيڊيا تي ڀليڪار + حقن ۽ واسطن جي آجيان (ويلڪم ڪاپي رائيٽ) + سڊني اوپيرا هائوس + رد + کوليو + چاڙهيو + بابت + ترتيبون (سيٽنگس) + اوهان جي راءِ + سکيا (ٽيوٽوريل) + ڪا به وضاحت نه ملي + ڪامن فائيل جو ورق + وڪيڊيٽا جزو (وڪيڊيٽا آئيٽم) From e41ef51a313f28faf703ae13fa94d4f5bb3d1b0a Mon Sep 17 00:00:00 2001 From: "translatewiki.net" Date: Thu, 21 Sep 2017 09:18:58 +0200 Subject: [PATCH 13/13] Localisation updates from https://translatewiki.net. --- app/src/main/res/values-bn/strings.xml | 3 + app/src/main/res/values-fi/strings.xml | 51 +++++---- app/src/main/res/values-fr/strings.xml | 8 +- app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values-sd/strings.xml | 12 +-- app/src/main/res/values-xmf/error.xml | 7 ++ app/src/main/res/values-xmf/strings.xml | 138 ++++++++++++++++++++++++ 7 files changed, 192 insertions(+), 28 deletions(-) create mode 100644 app/src/main/res/values-xmf/error.xml create mode 100644 app/src/main/res/values-xmf/strings.xml diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index 21a05851c..3d8f98247 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -85,6 +85,7 @@ পুনঃচেষ্টা করুন বাতিল এই ছবিটি %1$s এর অধীনে লাইসেন্স করা হবে + এই চিত্র জমা দেয়ার দ্বারা, আমি ঘোষণা দিচ্ছি যে এটি আমার নিজস্ব কাজ, এতে কপিরাইটযুক্ত উপাদান নেই বা এটই সেলফি নয়, এবং <a href=\"https://commons.wikimedia.org/wiki/Commons:Policies_and_guidelines/bn\">উইকিমিডিয়া কমন্স নীতি</a> অনুসরণ করে। ডাউনলোড লাইসেন্স পূর্ববর্তী শিরোনাম/বিবরণ ব্যবহার করুন @@ -148,6 +149,7 @@ আপলোডের তারিখ লাইসেন্স স্থানাঙ্কসমূহ + কিছু দেয়া হয়নি বিটা টেস্টার হোন উইকিউপাত্ত ব্যবহার করুন (সতর্কতা: এটি নিষ্ক্রিয় করা অধিক পরিমাণে মোবাইল ডেটা খরচ হওয়ার কারণ হতে পারে) @@ -166,6 +168,7 @@ রংধনুর সেতু টিউলিপ কোন সেলফি নয় + মালিকানা চিত্র উইকিপিডিয়ায় স্বাগতম স্বাগতম কপিরাইট সিডনি অপেরা হাউস diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index eafc67609..bf4ebdf0f 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -14,7 +14,7 @@ Tunnistautuminen epäonnistui! Tallentaminen aloitettiin! %1$s tallennettiin! - Napauta katsoaksesi tallennuksen + Napauta katsoaksesi tallennusta Aloitetaan tiedoston %1$s tallennusta Tallennetaan %1$s %1$s tallennettu @@ -29,7 +29,7 @@ Epäonnistui %1$d%% valmis Tallennetaan - Olemassaoleva + Galleriasta Ota kuva Lähistöllä Omat tallennukset @@ -39,7 +39,7 @@ Kuvaus Kirjautuminen epäonnistui - verkkovirhe Kirjautuminen epäonnistui - tarkista käyttäjätunnus - Kirjautuminen epäonnistui - tarkista salasana + Kirjautuminen epäonnistui - tarkista salasanasi Liikaa epäonnistuneita yrityksiä. Yritä uudelleen parin minuutin kuluttua. Pahoittelut, tämä käyttäjä on estetty Commonsissa Anna kaksivaiheisen tunnistuksen koodi. @@ -54,18 +54,18 @@ GPS ei ole käytössä. Haluatko ottaa sen käyttöön? Ota GPS käyttöön Ei tallennuksia vielä - - Ei tallennuksia - 1 tallennus + + \@string/contributions_subtitle_zero + %d tallennus %d tallennusta - - 1 tallennus alkaa - %d tallennusta alkaa + + aloitetaan %d tallennus + aloitetaan %d tallennusta - - 1 lataus - %d latausta + + %d tallennus + %d tallennusta Luokkaa %1$s ei löytynyt Lisää luokkia tehdäksesi kuvistasi helpommin löydettäviä.\n\nAloita kirjoittaminen lisätäksesi luokkia.\nNapauta tätä viestiä (tai paina takaisin) ohittaaksesi tämän vaiheen. @@ -73,7 +73,7 @@ Asetukset Rekisteröidy Tietoja - Tämä on vapaan lähdekoodin ohjelmisto, joka on julkaistu <a href=\"https://github.com/commons-app/apps-android-commons/blob/master/COPYING\">Apache License v2</a> -lisenssin alaisena. Wikimedia Commons ja sen logo ovat Wikimedia Foundationin tavaramerkkejä ja niitä käytetään Wikimedia Foundationin luvalla. Emme ole hyväksyttyjä tai sidoksissa Wikimedia Foundationioniin. + Tämä on vapaan lähdekoodin ohjelmisto, joka on julkaistu <a href=\"https://github.com/commons-app/apps-android-commons/blob/master/COPYING\">Apache License v2</a> -lisenssin alaisena. Wikimedia Commons ja sen logo ovat Wikimedia Foundationin tavaramerkkejä ja niitä käytetään Wikimedia Foundationin luvalla. Emme ole hyväksyttyjä tai sidoksissa Wikimedia Foundationioniin. <a href=\"https://github.com/commons-app/apps-android-commons\">Lähde</a> ja <a href=\"https://commons-app.github.io/\">nettisivusto</a> GitHubissa. Luo uusi <a href=\"https://github.com/commons-app/apps-android-commons/issues\">GitHub-issue</a> bugiraporteille ja ehdotuksille. <a href=\"https://wikimediafoundation.org/wiki/Privacy_policy\">Yksityisyydensuoja</a> <a href=\"https://github.com/commons-app/apps-android-commons/blob/master/CREDITS\">Tekijät</a> @@ -86,6 +86,7 @@ Yritä uudelleen Peruuta Tiedosto tallennetaan lisenssin %1$s ehtojen mukaisesti. + Lisäämällä kuvan, ilmoitan tämän olevan oma työ ja että se ei sisällä tekijänoikeuden alaista materiaalia tai selfietä ja muuten noudattaa <a href=\"https://commons.wikimedia.org/wiki/Commons:Policies_and_guidelines\">Wikimedia Commons policies</a>. Lataa Lisenssi Käytä edellistä otsikkoa/kuvausta @@ -115,15 +116,15 @@ CC0 Wikimedia Commonsiin on tallennettu lähes kaikki Wikipediassa käytetyt kuvat. Kuvasi auttavat ihmisiä kaikkialta maailmasta ymmärtämään maailmaa! - Tallenna kuvia, jotka sinä itse olet kuvannot tai luonut: + Tallenna kuvia, jotka sinä itse olet ottanut tai luonut: - Luontokohteet (kukat, eläimet, vuoret)\n- Hyödylliset esineet (polkupyörät, rautatieasemat)\n- Kuuluisat henkilöt (kaupunginjohtajasi, tapaamasi olympiaurheilijat) - Älä tallenna seuraavia: + ÄLÄ tallenna seuraavia: - Selfiet tai kuvat ystävistäsi\n- Netistä ladatut kuvat\n- Kuvakaappaukset kaupallisista sovelluksista Tallennusesimerkki: - Nimi: Sydneyn operatalo\n- Kuvaus: Sydneyn oopperatalo katsottuna lahden toisella puolella\n- Luokat: Sydneyn oopperatalo, Sydneyn oopperatalo lännestä, Sydneyn oopperatalo remote views Herätä Wikipedia-artikkelit eloon kuvillasi! Tuo kuvasi Wikipediaan. Wikipedian kuvat tulevat Wikimedia Commonsista. - Kuvat auttavat useita ihmisiä ympäri maailmaa artikkeleiden ymmärtämisessä. + Kuvasi auttavat useita ihmisiä ympäri maailmaa artikkeleiden ymmärtämisessä. Vältä tekijänoikeuksien alaista materiaalia, kuten julisteita, kirjan kansia ja useimpia Internetistä löydettyjä kuvia. Luuletko ymmärtäneesi tämän? Kyllä! @@ -134,8 +135,9 @@ Tuntematon lisenssi Päivitä Vaadittu oikeus: Ulkoisen tallennustilan luku. Appi ei toimi ilman tätä oikeutta. + Valinnainen lupa: Saada tämänhetkinen sijainti loukkasuosituksia varten. OK - Läheiset paikat + Lähellä olevat paikat Lähistöltä ei löytynyt paikkoja Varoitus Tämä tiedosto on jo Wikimedia Commonsissa. Haluatko varmasti jatkaa? @@ -147,14 +149,24 @@ Tallennuspäivämäärä Lisenssi Koordinaatit + ei annettu Ryhdy beetatestaajaksi Käytä Wikidataa + (Varoitus: poiskytkeminen voi aiheuttaa suuren mobiilidatankäytön) + Maksimimäärä + Ei voida näyttää enempää, kuin 500 Kaksivaiheinen tunnistus ei ole vielä tuettu. - Haluatko kirjautua ulos? + Haluatko varmasti kirjautua ulos? + Commons Logo + Taustakuva + Kuvaa ei löytynyt Lataa kuva + Zao-vuori + Sateenkaarisilta Tulppaani Ei selfieitä Tervetuloa Wikipediaan + Tervetuloa tekijänoikeus Sydneyn oopperatalo Peru Avaa @@ -166,6 +178,9 @@ Asetukset Palaute Kirjaudu ulos + Opas + Lähellä olevia paikkoja ei voida näyttää ilman sijaintilupaa Commons-tiedostosivu Wikidata-kohde + Tiedoston yksilöllinen ja kuvaava otsikko, jota käytetään tiedostonimenä. Voit käyttää tavallista kieltä välilyönnein. Älä sisällytä tiedoston päätettä. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 34d47a881..bcb7d187e 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -114,7 +114,7 @@ CC BY-SA 4.0 CC BY 4.0 CC Zéro - Wikimédia Communs héberge la plupart des images qui sont utilisées dans Wikipédia + Wikimedia Commons héberge la plupart des images qui sont utilisées dans Wikipédia. Vos images aident à éduquer les gens dans le monde entier ! Veuillez téléverser des images qui sont prises ou créées entièrement par vous : - Objets naturels (fleurs, animaux, montagnes) \n- Objets utiles (bicyclettes, gares ferroviaires) \n- Personnes célèbres (votre maire, les athlètes olympiques que vous avez rencontrés) @@ -140,7 +140,7 @@ Endroits à proximité Rien trouvé dans le voisinage Avertissement - Ce fichier existe déjà sur Communs. Êtes-vous sûr de vouloir continuer ? + Ce fichier existe déjà sur Commons. Êtes-vous sûr de vouloir continuer ? Oui Non Titre @@ -162,7 +162,7 @@ Fixer la limite de téléversement récent L’authentification à deux facteurs n’est pas prise en charge pour le moment. Voulez-vous vraiment vous déconnecter ? - Logo de Communs + Logo de Commons Image de fond Échec sur l’image du média Aucune image trouvée @@ -189,7 +189,7 @@ Tutoriel Les endroits proches ne peuvent pas être affichés si vous ne partagez pas votre position géographique. aucune description trouvée - Page des fichiers de Communs + Page des fichiers de Commons Élément de Wikidata Erreur en mettant les images en cache Un titre descriptif unique pour le fichier, qui servira de nom de fichier. Vous pouvez utiliser un langage simple avec des espaces. N’incluez pas l’extension du fichier diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 896de23b6..c089ef77e 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -153,6 +153,7 @@ Дата загрузки Лицензия Координаты + Не предоставлены Стать бета-тестером Подпишитесь на наш канал бета-версии на Google Play и получите ранний доступ к новым функциям и исправлениям ошибок Использовать Викиданные diff --git a/app/src/main/res/values-sd/strings.xml b/app/src/main/res/values-sd/strings.xml index 69b135129..2bbe7d7c2 100644 --- a/app/src/main/res/values-sd/strings.xml +++ b/app/src/main/res/values-sd/strings.xml @@ -2,7 +2,7 @@ العام ترتيبون - واھپ (يوزر)-نانءُ + واپرائيندڙ-نانءُ ڳجھولفظ داخل ٿيو کاتو کوليو @@ -38,10 +38,10 @@ عنوان تشريح ناقابلِ داخل ٿيڻ - باھمڄار ناڪامي - ناقابلِ داخل ٿيڻ - براءِ مھرباني پنھنجو واھپ (يوزر)-نانءُ چڪاسيو + ناقابلِ داخل ٿيڻ - براءِ مھرباني پنھنجو واپرائيندڙ-نانءُ چڪاسيو ناقابل داخل ٿيڻ - براءِ مھرباني پنھنجو ڳجھولفظ چڪاسيو ھيڪانديون ناڪام ڪوششون. براءِ مھرباني ڪجھ منٽن کانپوءِ ٻيھر ڪوشش ڪريو. - افسوس، ھي واھپ العام تي بندشيل آھي + افسوس، ھي واپرائيندڙ العام تي بندشيل آھي داخل ٿيڻ ناڪام چاڙھيو ھن سيٽ کي نالو ڏيو @@ -123,7 +123,7 @@ توھان سمجھو ٿا توھان سمجھي ويئو؟ ھا! زمرا - لاهيندي (لوڊنگ) + لاهيندي... ڪوبہ چونڊيل ناھي ڪا تشريح ناھي اڻڄاتل لائسنس @@ -145,8 +145,8 @@ وڪيڊيٽا استعماڪ ڪريو منهنجي تازي چاڙهڻ (اَپلوڊ) جي حد (لِمٽ) وڌ ۾ وڌ حد (ميگزيمم لِمٽ) - ڪا به تصوير نه ملي - تصوير چاڙهيو (اَپلوڊ اميج) + ڪوبہ عڪس نہ لڌو + عڪس چاڙهيو گل لالا (ٽيولپ) ڪي به پاڻفيون نه (نو سيلفيز) سڃاڻپ واري تصوير (پروپرائٽري اميج) diff --git a/app/src/main/res/values-xmf/error.xml b/app/src/main/res/values-xmf/error.xml new file mode 100644 index 000000000..850dde9fd --- /dev/null +++ b/app/src/main/res/values-xmf/error.xml @@ -0,0 +1,7 @@ + + + ვიკიოწკარუექ აკორთუ + უი. მუდგაინქ ქჷმოხვადუǃ + ქომწით მუს აკეთენდით დო ქჷმომჯღონით ელექტრონული ფოსტათ. თენა ჩქი პრობლემაშ გიშათინუა ქემეხვარებჷნა! + დიდი მარდიǃ + diff --git a/app/src/main/res/values-xmf/strings.xml b/app/src/main/res/values-xmf/strings.xml new file mode 100644 index 000000000..23933ab25 --- /dev/null +++ b/app/src/main/res/values-xmf/strings.xml @@ -0,0 +1,138 @@ + + + ვიკიოწკარუე + პარამეტრეფი + მახვარებუშ ჯოხო + პაროლი + მიშულა + რეგისტრაცია + სისტემაშა მიშულა + ქორთხინთ ქიმიცადით … + სისტემაშა მიშულაქ წჷმოძინელო გეთუ! + სისტემაშა მიშულაქ ვემიხუჯინუ! + ფაილქ ვეგორუ. ქორთხინთ, ქოცადით შხვა ფაილი. + აუთენტიფიკაციაქ ვემიხუჯინუ! + ეხარგუაქ ქჷდიჭყუ! + %1$ ეხარგილი რე! + ქეგუწკანტეთ თქვანი ეხარგუაშ ოძირაფალო + ქჷდიჭყუ %1$ ეხარგუაქ + %1$ იხარგუ + ეხარგუაშ თება %1$ + %1$ ეხარგუაქ ვემიხუჯინუ + ოძირაფალო ქეგუწკანტეთ + + %d ფაილი იხარგუ + %d ფაილი იხარგუ + + ჩქიმი ბოლო ეხარგუეფი + რადი + ვემიხუჯინუ + %1$d%% გეთუ + იხარგუაფუ + გალერეაშე + ფოტოშ გინოღალა + გოხოლუას + ჩქიმი ეხარგუეფი + გობჟინაფა + ბრაუზერს გონწყუმა + დუდჯოხო + ეჭარუა + მიშულაქ ვემიხუჯინუ - რშვილიშ ჩილათა + მიშულაქ ვემიხუჯინუ - ქორთხინთ გეგნაჯინით ჯოხოს + მიშულაქ ვემიხუჯინუ - ქორთხინთ გეგნაჯინით პაროლს + ძალამ მიარე უმწუძინუ ცადება. ქორთხინ, მუხირენ წუთშა ხოლო ქოცადით. + მორდება, თე მახვარებუ ბლოკირი რე ვიკიოწკარუეს + თქვა გემშიონათ ოკო ჟირფაქტორიანი ავტორიზაციაშ კოდი. + მიშულაქ ვემიხუჯინუ + ეხარგუა + სერიაშ ჯოხო + მოდიფიკაციეფი + ეხარგუა + კატეგორიაშ გიშაგორუა + ჩუალა + გოახალაფა + თქვან მონწყილობას GPS თიშილი რე. თახმო გოკონანო ჩართება? + GPS-იშ ჩართება + ეხარგუეფი ვა რე + + \@string/contributions_subtitle_zero + %d ეხარგუა + %d ეხარგუა + + + იჭყაფუ %d ეხარგუა + იჭყაფუ %d ეხარგუა + + + %d ეხარგუა + %d ეხარგუა + + კატეგორია + პარამეტრეფი + რეგისტრაცია + პროგრამაშ გეშა + გომაჟირაფა + გოუქვაფა + თე სურათი გიბჟინუ %1$s ლიცენზიათ + გინოჭარუა + ლიცენზია + წჷმი სათაურიშ/ეჭარუაშ გჷმორინაფა + ასეიანი ორენიშ ავტომატური მეღება + სერიშ რეჟიმი + რუმე თემაშ გჷმორინაფა + Attribution-ShareAlike 4.0 + Attribution 4.0 + Attribution-ShareAlike 3.0 + Attribution 3.0 + CC0 + CC BY-SA 3.0 + CC BY-SA 3.0 (ავსტრია) + CC BY-SA 3.0 (გერმანია) + CC BY-SA 3.0 (ესტონეთი) + CC BY-SA 3.0 (ესპანეთი) + CC BY-SA 3.0 (ხორვატია) + CC BY-SA 3.0 (ლუქსემბურგი) + CC BY-SA 3.0 (ნიდერლანდი) + CC BY-SA 3.0 (ნორვეგია) + CC BY-SA 3.0 (პოლონეთი) + CC BY-SA 3.0 (რუმინეთი) + CC BY-SA 3.0 + CC BY-SA 4.0 + CC BY 4.0 + CC Zero + ქორთხინთ გეხარგეთ, ხვალე თქვანით ინოღალირი ვარდა აკოქიმინელი სურათეფი: + - ორთაშობური ობიექტეფი (პიოლეფი, ჩხოლარეფი, გვალეფი)\n- ორგებელი ობიექტეფი (ველოსიპედეფი, მახინწალიშ დგჷმიელფი)\n- ჩინებული ადამიერეფი (თქვანი ნოღაშ მერი, ოლიმპიარი სპორტსმენეფი, ნამუეფსჷთ შეხვალამუთჷნ) + ქორთხინთ ვეხარგათ: + - სელფი ვარდა მაჸალეეფიშ სურათეფი\n- ინტერნეტშე გჷმოხარგილი ფოტოეფი\n- ვადუდიშული აპლიკაციეფიშ სკრინშოტეფი + ეხარგუაშ მინუში: + - დუდჯოხო: სიდნეიშ ოპერაშ თეატრი\n- ეჭარუა: სიდნეიშ ოპერაშ თეატრიშ მიოჯინი ლუბაშე\n- კატეგორიეფი: Sydney Opera House, Sydney Opera House from the west, Sydney Opera House remote views + გეხარგეთ თქვანი ფოტოეფი. ქემეხვარით ვიკიპედიაშ სტატიეფიშ გაჭყანიერებას! + ვიკიპედიაშ ფოტოეფი ვიკიოწკარუეს იჩუალუაფუ. + თქვანი სურათეფი კათაშ გონათუას ოხვარუ ედომუშამ მოსოფელს. + ქოǃ + კატეგორიეფი + იხარგუ... + მუთუნ ვა რე გიშაგორილი + ვა რე ეჭარუა + უჩინებუ ლიცენზია + გოახალაფა + OK + გოხოლუაშ აბანეფი + გოხოლუაშ აბანეფქ ვეგორუ + გათხილება + ქო + ვარი + დუდჯოხო + მედიაფაილიშ დუდჯოხო + ეჭარუა + ეხარგუაშ თარიღი + ლიცენზია + კოორდინატეფი + ბეტა ტესტირებას კათაფი + ვიკიმუნაჩემეფიშ გჷმორინაფა + 2ფა კოდი + ჩქიმი ბოლო ეხარგუეფიშ ლიმიტი + მაქსიმალური ლიმიტი + 500-შე უმოსიშ ძირაფა ვეშილებე + ბოლო ეხარგუეფიშ ლიმიტიშ გერინაფა +