Skip to content

Commit ddd3e12

Browse files
ashishkumar468macgillssivaraamkbhardwaj123VitalyVPinchuk
authored
Sync master with release (#3922)
* #3624 DateTimeFormat wrong - match pattern returned from servers (#3625) * Revert "Fixes: #3179 Make category search non case-sensitive (#3326)" (#3636) Simply lower casing the name of the category sent to the server doesn't result in the server doing a case insensitive category search. In fact, it reduces the category search space as only categories that has a lower case character is searched even if the search text contains upper case characters. The test case did not catch this issue as the first character of the title is case insensitive[1]. So, revert the changes done in commit afdeaae. See further disucssion in the issue thread of #3179 starting from [2]. [1]: https://www.mediawiki.org/wiki/Manual:Page_title [2]: #3179 (comment) * Bugfix/security exception (#3627) * Fixes #3626 * Check is file is actually created before writing to file, file picker android * Handle Security exception * Fixes #3436 and #2881: Media Detail design Overhaul (#3505) * ic_map_dark_24dp: map icon for white background * ic_info_outline_dark_24dp: info icon for dark background * MediaDetailFragment: update the spacer as per image aspect ratio * fragment_media_detail: design overhaul * fragment_media_detail: remove redundant background color statements * make requested changes * add dark mode support * minor ui tweak * white map icon in dark mode * make rquested changes * make requested changes to layout * fix misalignment of category list * subtle amendments * convert comments to javadocs * minor amendments * minor changes * add styles for media detail * Media detail fragment refactored * make suggested changes * minor name fix * fix the delete button border * Fixes #3639 (Fix Save State implementation of CheckBoxTriState ) (#3686) * Add #3723 and #3721 to 2.13 release, fix conflicts Conflicts were caused by merging #3723 before #3721 , so I just rolled both into one commit. * Fix NullPointer when clicking on image in MediaDetailFragment (#3730)… (#3739) * Update changelog.md * Versioning for v2.13 * Fixes #3705 (Crash when viewing pic I just uploaded) (#3782) * Fixes #3705 * Let the MediaDetailPager fragment know when the contributions have been updated * Handle NPE, null check on adapter in MediaDetailPagerFragment * Fixed BookmarkLocationsDao DB migration (#3793) * Fixes #3725 (#3795) * Downgraded okhttp version to support Api 19 devices * Handled null CompoundDrawable[2] in etTitle-> UploadMediaDetailsFragment (#3828) * DownSample Upload image to be shown in UploadMediaDetailFragment to handle OOM, Bitmap Too large exception (#3830) * Fixes #3829 * DownSample Upload image to be shown in UploadMediaDetailFragment to handle OOM, Bitmap Too large exception * removed unused imports, handled possible exceptions * Let Fresco handle the downsampling of image * invalidate in onTransformEnd * Expose an interface TransformationListener in ZoomableDraweeView to listen to transformation change end * removed photoView dependency * removed unused imports in ZoomableActivity * Bugfix, expand/collapse * changed functio name * Bugfix/p18 uploads (#3869) * updated gradle plugin version * BugFix #3856 * Do not use preference for deciding acceptable lat long for nearby uploads, instead save the corresponding location in the Contribution via UploadItem * Marshall contribution's hasInvalidLocation * reset un-related changes * Fixed test cases * Minor code formatting and docs * Fixes #3882 (#3883) * Make hasInvalidLocation non-null integer with default value 0 Co-authored-by: Ashish Kumar <ashish@Ashishs-MacBook-Air.local> * Fixes #3766, Added OPENSTREET attribution (#3889) * Fixes #3766 * Added OPENSTREET attribution in nearby * Added custom text attribution in Nearby * Deleted unused class CustomBorderTextView * review suggested changes * modified telemetry summary string * Versioning and changelog for v2.13.1 (#3908) * Update changelog.md * Versioning for v2.13.1 * Fixes #3914 (#3915) * Verify user login before setting upload count * fixed compile-time error * fix erros * delete emptied files * remove empty file CategoriesModel.java Co-authored-by: Seán Mac Gillicuddy <seantheappdev@gmail.com> Co-authored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com> Co-authored-by: Kshitij Bhardwaj <44129798+kbhardwaj123@users.noreply.github.com> Co-authored-by: Vitaly V. Pinchuk <vetal.978@gmail.com> Co-authored-by: Josephine Lim <josephinelim86@gmail.com> Co-authored-by: Ashish Kumar <ashish@Ashishs-MacBook-Air.local>
1 parent abdd16c commit ddd3e12

31 files changed

+607
-515
lines changed

CHANGELOG.md

+12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Wikimedia Commons for Android
22

3+
## v2.13.1
4+
- Added OpenStreetMap attribution
5+
- Fixed various crashes
6+
- Fixed SQLite error in Nearby map
7+
- Fixed issue with Nearby uploads not being associated with Wikidata p18
8+
9+
## v2.13.0
10+
- New media details UI, ability to zoom and pan around image
11+
- Added suggestions for a place that needs photos if user uploads a photo that is near one of them
12+
- Modifications and fixes to Nearby filters based on user feedback
13+
- Multiple crash and bug fixes
14+
315
## v2.12.3
416
- Fixed issue with EXIF data, including coords, being removed from uploads
517

app/build.gradle

+9-6
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ dependencies {
2121
// Utils
2222
implementation 'in.yuvi:http.fluent:1.3'
2323
implementation 'com.google.code.gson:gson:2.8.5'
24-
implementation 'com.squareup.okhttp3:okhttp:4.8.0'
24+
implementation ("com.squareup.okhttp3:okhttp:$OKHTTP_VERSION"){
25+
force = true //API 19 support
26+
}
2527
implementation 'com.squareup.okio:okio:2.2.2'
2628
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
2729
implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
@@ -35,6 +37,7 @@ dependencies {
3537
// UI
3638
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
3739
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
40+
implementation 'com.github.pedrovgs:renderers:3.3.3'
3841
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:8.6.2'
3942
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v8:0.11.0'
4043
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.4.0'
@@ -51,7 +54,7 @@ dependencies {
5154
testImplementation "androidx.paging:paging-common-ktx:$PAGING_VERSION"
5255
implementation "androidx.paging:paging-rxjava2-ktx:$PAGING_VERSION"
5356
implementation "androidx.recyclerview:recyclerview:1.2.0-alpha02"
54-
implementation 'com.squareup.okhttp3:okhttp-ws:3.4.1'
57+
implementation "com.squareup.okhttp3:okhttp-ws:$OKHTTP_VERSION"
5558

5659
// Logging
5760
implementation 'ch.acra:acra-dialog:5.3.0'
@@ -60,7 +63,7 @@ dependencies {
6063
api('com.github.tony19:logback-android-classic:1.1.1-6') {
6164
exclude group: 'com.google.android', module: 'android'
6265
}
63-
implementation "com.squareup.okhttp3:logging-interceptor:4.5.0"
66+
implementation "com.squareup.okhttp3:logging-interceptor:$OKHTTP_VERSION"
6467

6568
// Dependency injector
6669
implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION"
@@ -81,7 +84,7 @@ dependencies {
8184
testImplementation 'junit:junit:4.13'
8285
testImplementation 'org.robolectric:robolectric:4.3'
8386
testImplementation 'androidx.test:core:1.2.0'
84-
testImplementation "com.squareup.okhttp3:mockwebserver:4.8.0"
87+
testImplementation "com.squareup.okhttp3:mockwebserver:$OKHTTP_VERSION"
8588
testImplementation "org.powermock:powermock-module-junit4:2.0.0-beta.5"
8689
testImplementation "org.powermock:powermock-api-mockito2:2.0.0-beta.5"
8790
testImplementation 'org.mockito:mockito-core:2.23.0'
@@ -139,8 +142,8 @@ android {
139142

140143
defaultConfig {
141144
//applicationId 'fr.free.nrw.commons'
142-
versionCode 561
143-
versionName '2.12.3'
145+
versionCode 775
146+
versionName '2.13.1'
144147
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
145148

146149
minSdkVersion 19

app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsDao.java

+38-18
Original file line numberDiff line numberDiff line change
@@ -248,24 +248,44 @@ public static void onDelete(SQLiteDatabase db) {
248248

249249
public static void onUpdate(SQLiteDatabase db, int from, int to) {
250250
Timber.d("bookmarksLocations db is updated from:"+from+", to:"+to);
251-
switch (from) {
252-
case 7: onCreate(db);
253-
case 8: // No change
254-
case 9: // No change
255-
case 10:
256-
try {
257-
db.execSQL("ALTER TABLE bookmarksLocations ADD COLUMN location_pic STRING;");
258-
} catch (SQLiteException exception){
259-
Timber.e(exception);
260-
}
261-
case 11: // No change
262-
case 12:
263-
try {
264-
db.execSQL("ALTER TABLE bookmarksLocations ADD COLUMN location_destroyed STRING;");
265-
}catch (SQLiteException exception){
266-
Timber.e(exception);
267-
}
268-
break;
251+
if (from == to) {
252+
return;
253+
}
254+
if (from < 7) {
255+
// doesn't exist yet
256+
from++;
257+
onUpdate(db, from, to);
258+
return;
259+
}
260+
if (from == 7) {
261+
// table added in version 8
262+
onCreate(db);
263+
from++;
264+
onUpdate(db, from, to);
265+
return;
266+
}
267+
if (from == 8) {
268+
from++;
269+
onUpdate(db, from, to);
270+
return;
271+
}
272+
if (from == 10) {
273+
//This is safe, and can be called clean, as we/I do not remember the appropriate version for this
274+
//We are anyways switching to room, these things won't be necessary then
275+
try {
276+
db.execSQL("ALTER TABLE bookmarksLocations ADD COLUMN location_pic STRING;");
277+
}catch (SQLiteException exception){
278+
Timber.e(exception);//
279+
}
280+
return;
281+
}
282+
if (from == 12) {
283+
try {
284+
db.execSQL(
285+
"ALTER TABLE bookmarksLocations ADD COLUMN location_destroyed STRING;");
286+
} catch (SQLiteException exception) {
287+
Timber.e(exception);
288+
}
269289
}
270290
}
271291
}

app/src/main/java/fr/free/nrw/commons/contributions/Contribution.kt

+14-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ data class Contribution constructor(
3838
val localUri: Uri? = null,
3939
var dataLength: Long = 0,
4040
var dateCreated: Date? = null,
41-
var dateModified: Date? = null
41+
var dateModified: Date? = null,
42+
var hasInvalidLocation : Int = 0
4243
) : Parcelable {
4344

4445
fun completeWith(media: Media): Contribution {
@@ -65,6 +66,18 @@ data class Contribution constructor(
6566
wikidataPlace = from(item.place)
6667
)
6768

69+
/**
70+
* Set this true when ImageProcessor has said that the location is invalid
71+
* @param hasInvalidLocation
72+
*/
73+
fun setHasInvalidLocation(hasInvalidLocation: Boolean) {
74+
this.hasInvalidLocation = if (hasInvalidLocation) 1 else 0
75+
}
76+
77+
fun hasInvalidLocation(): Boolean {
78+
return hasInvalidLocation == 1
79+
}
80+
6881
companion object {
6982
const val STATE_COMPLETED = -1
7083
const val STATE_FAILED = 1

app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java

+20-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@
2222
import androidx.fragment.app.Fragment;
2323
import androidx.fragment.app.FragmentManager.OnBackStackChangedListener;
2424
import androidx.fragment.app.FragmentTransaction;
25+
26+
import fr.free.nrw.commons.MediaDataExtractor;
27+
import fr.free.nrw.commons.auth.SessionManager;
28+
import io.reactivex.disposables.Disposable;
29+
import java.util.List;
30+
31+
import javax.inject.Inject;
32+
import javax.inject.Named;
33+
2534
import butterknife.BindView;
2635
import butterknife.ButterKnife;
2736
import fr.free.nrw.commons.Media;
@@ -83,6 +92,9 @@ public class ContributionsFragment
8392

8493
@Inject ContributionsPresenter contributionsPresenter;
8594

95+
@Inject
96+
SessionManager sessionManager;
97+
8698
private LatLng curLatLng;
8799

88100
private boolean firstLocationUpdate = true;
@@ -143,7 +155,14 @@ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
143155

144156
initFragments();
145157

146-
if (!ConfigUtils.isBetaFlavour()) {
158+
if(shouldShowMediaDetailsFragment){
159+
showMediaDetailPagerFragment();
160+
}else{
161+
showContributionsListFragment();
162+
}
163+
164+
if (!ConfigUtils.isBetaFlavour() && sessionManager.isUserLoggedIn()
165+
&& sessionManager.getCurrentAccount() != null) {
147166
setUploadCount();
148167
}
149168

app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ private void initRecyclerView() {
132132
getSpanCount(getResources().getConfiguration().orientation));
133133
rvContributionsList.setLayoutManager(layoutManager);
134134
contributionsListPresenter.setup();
135-
contributionsListPresenter.contributionList.observe(this, adapter::submitList);
135+
contributionsListPresenter.contributionList.observe(this.getViewLifecycleOwner(), adapter::submitList);
136136
rvContributionsList.setAdapter(adapter);
137137
}
138138

app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java

+14-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import android.view.inputmethod.InputMethodManager;
88
import androidx.collection.LruCache;
99
import androidx.room.Room;
10+
import androidx.room.migration.Migration;
11+
import androidx.sqlite.db.SupportSQLiteDatabase;
1012
import com.google.gson.Gson;
1113
import dagger.Module;
1214
import dagger.Provides;
@@ -49,6 +51,15 @@ public class CommonsApplicationModule {
4951
private Context applicationContext;
5052
public static final String IO_THREAD="io_thread";
5153
public static final String MAIN_THREAD="main_thread";
54+
private AppDatabase appDatabase;
55+
56+
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
57+
@Override
58+
public void migrate(SupportSQLiteDatabase database) {
59+
database.execSQL("ALTER TABLE contribution "
60+
+ " ADD COLUMN hasInvalidLocation INTEGER NOT NULL DEFAULT 0");
61+
}
62+
};
5263

5364
public CommonsApplicationModule(Context applicationContext) {
5465
this.applicationContext = applicationContext;
@@ -103,11 +114,6 @@ public ContentProviderClient provideCategoryContentProviderClient(Context contex
103114
return context.getContentResolver().acquireContentProviderClient(BuildConfig.CATEGORY_AUTHORITY);
104115
}
105116

106-
/**
107-
* This method is used to provide instance of DepictsContentProviderClient
108-
* @param context context
109-
* @return DepictsContentProviderClient*/
110-
111117
/**
112118
* This method is used to provide instance of RecentSearchContentProviderClient
113119
* which provides content of Recent Searches from database
@@ -224,9 +230,11 @@ public String provideLoggedInUsername() {
224230
@Provides
225231
@Singleton
226232
public AppDatabase provideAppDataBase() {
227-
return Room.databaseBuilder(applicationContext, AppDatabase.class, "commons_room.db")
233+
appDatabase = Room.databaseBuilder(applicationContext, AppDatabase.class, "commons_room.db")
234+
.addMigrations(MIGRATION_1_2)
228235
.fallbackToDestructiveMigration()
229236
.build();
237+
return appDatabase;
230238
}
231239

232240
@Provides

app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public HttpLoggingInterceptor provideHttpLoggingInterceptor() {
7676
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(message -> {
7777
Timber.tag("OkHttp").v(message);
7878
});
79-
httpLoggingInterceptor.level(BuildConfig.DEBUG ? Level.BODY: Level.BASIC);
79+
httpLoggingInterceptor.setLevel(BuildConfig.DEBUG ? Level.BODY: Level.BASIC);
8080
return httpLoggingInterceptor;
8181
}
8282

app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public static void handleActivityResult(int requestCode, int resultCode, Intent
166166
public static List<UploadableFile> handleExternalImagesPicked(Intent data, Activity activity) {
167167
try {
168168
return getFilesFromGalleryPictures(data, activity);
169-
} catch (IOException e) {
169+
} catch (IOException | SecurityException e) {
170170
e.printStackTrace();
171171
}
172172
return new ArrayList<>();
@@ -207,7 +207,7 @@ private static void onPictureReturnedFromGallery(Intent data, Activity activity,
207207
}
208208
}
209209

210-
private static List<UploadableFile> getFilesFromGalleryPictures(Intent data, Activity activity) throws IOException {
210+
private static List<UploadableFile> getFilesFromGalleryPictures(Intent data, Activity activity) throws IOException, SecurityException {
211211
List<UploadableFile> files = new ArrayList<>();
212212
ClipData clipData = data.getClipData();
213213
if (clipData == null) {

app/src/main/java/fr/free/nrw/commons/filepicker/PickedFiles.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,15 @@ static void scanCopiedImages(Context context, List<File> copiedImages) {
104104
});
105105
}
106106

107-
static UploadableFile pickedExistingPicture(@NonNull Context context, Uri photoUri) throws IOException {
107+
static UploadableFile pickedExistingPicture(@NonNull Context context, Uri photoUri) throws IOException, SecurityException {// SecurityException for those file providers who share URI but forget to grant necessary permissions
108108
InputStream pictureInputStream = context.getContentResolver().openInputStream(photoUri);
109109
File directory = tempImageDirectory(context);
110110
File photoFile = new File(directory, UUID.randomUUID().toString() + "." + getMimeType(context, photoUri));
111-
photoFile.createNewFile();
112-
writeToFile(pictureInputStream, photoFile);
111+
if (photoFile.createNewFile()) {
112+
writeToFile(pictureInputStream, photoFile);
113+
} else {
114+
throw new IOException("could not create photoFile to write upon");
115+
}
113116
return new UploadableFile(photoUri, photoFile);
114117
}
115118

app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,9 @@ public void showImage(int i) {
295295
* The method notify the viewpager that number of items have changed.
296296
*/
297297
public void notifyDataSetChanged(){
298-
adapter.notifyDataSetChanged();
298+
if (null != adapter) {
299+
adapter.notifyDataSetChanged();
300+
}
299301
}
300302

301303
@Override

app/src/main/java/fr/free/nrw/commons/media/ZoomableActivity.java

-7
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,11 @@
2323
import com.facebook.drawee.generic.GenericDraweeHierarchy;
2424
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
2525
import com.facebook.drawee.interfaces.DraweeController;
26-
import android.view.LayoutInflater;
2726
import android.view.View;
28-
import android.view.ViewGroup;
2927
import android.widget.ProgressBar;
3028

31-
import com.facebook.drawee.view.SimpleDraweeView;
3229
import com.facebook.imagepipeline.image.ImageInfo;
33-
import com.github.chrisbanes.photoview.PhotoView;
3430

35-
import java.io.InputStream;
36-
import java.net.HttpURLConnection;
37-
import java.net.URL;
3831

3932
public class ZoomableActivity extends AppCompatActivity {
4033
private Uri imageUri;

app/src/main/java/fr/free/nrw/commons/media/zoomControllers/zoomable/ZoomableDraweeView.java

+18-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public class ZoomableDraweeView extends DraweeView<GenericDraweeHierarchy>
4747

4848
private boolean mIsDialtoneEnabled = false;
4949
private boolean mZoomingEnabled = true;
50+
private TransformationListener transformationListener;
5051

5152
private final ControllerListener mControllerListener =
5253
new BaseControllerListener<Object>() {
@@ -73,9 +74,18 @@ public void onTransformChanged(Matrix transform) {
7374
}
7475

7576
@Override
76-
public void onTransformEnd(Matrix transform) {}
77+
public void onTransformEnd(Matrix transform) {
78+
if (null != transformationListener) {
79+
transformationListener.onTransformationEnd();
80+
}
81+
}
7782
};
7883

84+
public void setTransformationListener(
85+
TransformationListener transformationListener) {
86+
this.transformationListener = transformationListener;
87+
}
88+
7989
private final GestureListenerWrapper mTapListenerWrapper = new GestureListenerWrapper();
8090

8191
public ZoomableDraweeView(Context context, GenericDraweeHierarchy hierarchy) {
@@ -397,4 +407,11 @@ protected Class<?> getLogTag() {
397407
protected ZoomableController createZoomableController() {
398408
return AnimatedZoomableController.newInstance();
399409
}
410+
411+
/**
412+
* Use this, If someone is willing to listen to scale change
413+
*/
414+
public interface TransformationListener{
415+
void onTransformationEnd();
416+
}
400417
}

0 commit comments

Comments
 (0)