Skip to content

Commit 276c90e

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 4ae16ef + bcc545c commit 276c90e

File tree

113 files changed

+4799
-2502
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+4799
-2502
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Wikimedia Commons for Android
22

3+
## v2.11.0
4+
- Refactored upload process, explore/media details, and peer review to use MVP architecture
5+
- Refactored all AsyncTasks to use RxAndroid
6+
- Partial migration to Retrofit
7+
- Allow users to remove EXIF tags from their uploads if desired
8+
- Multiple crash and bug fixes
9+
310
## v2.10.2
411
- Fixed remaining issues with date image taken
512
- Fixed database crash

CREDITS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ their contribution to the product.
4646
* Ilgaz Er
4747
* Alicia Bendz
4848
* Kaartic Sivaraam
49+
* Vanshika Arora
4950

5051
3rd party open source libraries used:
5152
* Butterknife

app/build.gradle

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,23 @@ dependencies {
1919

2020
// Utils
2121
implementation 'com.github.nicolas-raoul:Quadtree:ac16ea8035bf07'
22-
implementation 'com.google.code.gson:gson:2.8.5'
2322
implementation 'in.yuvi:http.fluent:1.3'
2423
implementation 'com.squareup.okhttp3:okhttp:3.12.1'
2524
implementation 'com.squareup.okio:okio:1.15.0'
26-
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
27-
implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
2825
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
2926
implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.1.1'
3027
implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.1.1'
3128
implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.1.1'
3229
implementation 'com.facebook.fresco:fresco:1.13.0'
33-
implementation 'com.drewnoakes:metadata-extractor:2.11.0'
3430
implementation 'com.dmitrybrant:wikimedia-android-data-client:0.0.18'
3531
implementation 'org.apache.commons:commons-lang3:3.8.1'
3632

3733
// UI
3834
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
3935
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
4036
implementation 'com.github.pedrovgs:renderers:3.3.3'
41-
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:6.8.0'
42-
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization:0.6.0'
37+
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:7.2.0'
38+
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v7:0.7.0'
4339
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
4440
implementation 'com.dinuscxj:circleprogressbar:1.1.1'
4541
implementation 'com.karumi:dexter:5.0.0'
@@ -49,14 +45,12 @@ dependencies {
4945
// Logging
5046
implementation 'ch.acra:acra-dialog:5.3.0'
5147
implementation 'ch.acra:acra-mail:5.3.0'
52-
implementation 'com.jakewharton.timber:timber:4.7.1'
5348
implementation 'org.slf4j:slf4j-api:1.7.25'
5449
api('com.github.tony19:logback-android-classic:1.1.1-6') {
5550
exclude group: 'com.google.android', module: 'android'
5651
}
5752

5853
// Dependency injector
59-
implementation "com.google.dagger:dagger:$DAGGER_VERSION"
6054
implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION"
6155
kapt "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"
6256
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
@@ -98,8 +92,6 @@ dependencies {
9892

9993
//swipe_layout
10094
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
101-
//metadata extractor
102-
implementation 'com.drewnoakes:metadata-extractor:2.11.0'
10395
}
10496

10597
android {
@@ -108,8 +100,8 @@ android {
108100

109101
defaultConfig {
110102
applicationId 'fr.free.nrw.commons'
111-
versionCode 243
112-
versionName '2.10.2'
103+
versionCode 475
104+
versionName '2.11.0'
113105
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
114106

115107
minSdkVersion 19
@@ -168,7 +160,7 @@ android {
168160
versionNameSuffix "-debug-" + getBranchName()
169161
}
170162
}
171-
163+
172164
if (isRunningOnTravisAndIsNotPRBuild) {
173165
// configure keystore based on env vars in Travis for automated alpha builds
174166
signingConfigs.release.storeFile = file("../nr-commons.keystore")

app/src/main/java/fr/free/nrw/commons/achievements/AchievementsActivity.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ void shareScreen(Bitmap bitmap) {
199199
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
200200
intent.putExtra(Intent.EXTRA_STREAM, fileUri);
201201
intent.setType("image/png");
202-
startActivity(Intent.createChooser(intent, "Share image via"));
202+
startActivity(Intent.createChooser(intent, getString(R.string.share_image_via)));
203203
} catch (IOException e) {
204204
e.printStackTrace();
205205
}
@@ -316,8 +316,8 @@ private void setUploadProgress(int uploadCount){
316316

317317
private void setZeroAchievements() {
318318
AlertDialog.Builder builder=new AlertDialog.Builder(this)
319-
.setMessage("You haven't made any contributions yet")
320-
.setPositiveButton("Ok", (dialog, which) -> {
319+
.setMessage(getString(R.string.no_achievements_yet))
320+
.setPositiveButton(getString(R.string.ok), (dialog, which) -> {
321321
});
322322
AlertDialog dialog = builder.create();
323323
dialog.show();

app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import android.widget.Toast;
88

99
import fr.free.nrw.commons.BuildConfig;
10+
import fr.free.nrw.commons.R;
1011
import fr.free.nrw.commons.theme.BaseActivity;
1112
import timber.log.Timber;
1213

@@ -39,7 +40,7 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) {
3940
Timber.d("Overriding URL %s", url);
4041

4142
Toast toast = Toast.makeText(SignupActivity.this,
42-
"Account created!", Toast.LENGTH_LONG);
43+
R.string.account_created, Toast.LENGTH_LONG);
4344
toast.show();
4445
// terminate on task completion.
4546
finish();

app/src/main/java/fr/free/nrw/commons/category/CategoriesModel.java

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,21 @@ public CategoriesModel(MediaWikiApi mwApi,
4848
*/
4949
public Comparator<CategoryItem> sortBySimilarity(final String filter) {
5050
Comparator<String> stringSimilarityComparator = StringSortingUtils.sortBySimilarity(filter);
51-
return (firstItem, secondItem) -> stringSimilarityComparator
52-
.compare(firstItem.getName(), secondItem.getName());
51+
return (firstItem, secondItem) -> {
52+
//if the category is selected, it should get precedence
53+
if (null != firstItem && firstItem.isSelected()) {
54+
if (null != secondItem && secondItem.isSelected()) {
55+
return stringSimilarityComparator
56+
.compare(firstItem.getName(), secondItem.getName());
57+
}
58+
return -1;
59+
}
60+
if (null != secondItem && secondItem.isSelected()) {
61+
return 1;
62+
}
63+
return stringSimilarityComparator
64+
.compare(firstItem.getName(), secondItem.getName());
65+
};
5366
}
5467

5568
/**
@@ -255,4 +268,38 @@ public void cleanUp() {
255268
this.categoriesCache.clear();
256269
this.selectedCategories.clear();
257270
}
271+
272+
/**
273+
* Search for categories
274+
*/
275+
public Observable<CategoryItem> searchCategories(String query, List<String> imageTitleList) {
276+
if (TextUtils.isEmpty(query)) {
277+
return gpsCategories()
278+
.concatWith(titleCategories(imageTitleList))
279+
.concatWith(recentCategories());
280+
}
281+
282+
return mwApi
283+
.searchCategories(query, SEARCH_CATS_LIMIT)
284+
.map(s -> new CategoryItem(s, false));
285+
}
286+
287+
/**
288+
* Returns default categories
289+
*/
290+
public Observable<CategoryItem> getDefaultCategories(List<String> titleList) {
291+
Observable<CategoryItem> directCategories = directCategories();
292+
if (hasDirectCategories()) {
293+
Timber.d("Image has direct Categories");
294+
return directCategories
295+
.concatWith(gpsCategories())
296+
.concatWith(titleCategories(titleList))
297+
.concatWith(recentCategories());
298+
} else {
299+
Timber.d("Image has no direct Categories");
300+
return gpsCategories()
301+
.concatWith(titleCategories(titleList))
302+
.concatWith(recentCategories());
303+
}
304+
}
258305
}

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

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class Contribution extends Media {
2929
private static final String TEMPLATE_DATE_ACC_TO_EXIF = "{{According to EXIF data|%s}}";
3030

3131
//{{date|2009|1|9}} → 9 January 2009
32-
private static final String TEMPLATE_DATA_OTHER_SOURCE = "{{date|%d|%d|%d}}";
32+
private static final String TEMPLATE_DATA_OTHER_SOURCE = "{{date|%s}}";
3333

3434
public static Creator<Contribution> CREATOR = new Creator<Contribution>() {
3535
@Override
@@ -201,16 +201,11 @@ public String getPageContents(Context applicationContext) {
201201
*/
202202
private String getTemplatizedCreatedDate() {
203203
if (dateCreated != null) {
204+
java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat("yyyy-MM-dd");
204205
if (UploadableFile.DateTimeWithSource.EXIF_SOURCE.equals(dateCreatedSource)) {
205-
return String.format(Locale.ENGLISH, TEMPLATE_DATE_ACC_TO_EXIF, DateUtil.getDateStringWithSkeletonPattern(dateCreated, "yyyy-MM-dd")) + "\n";
206+
return String.format(Locale.ENGLISH, TEMPLATE_DATE_ACC_TO_EXIF, dateFormat.format(dateCreated)) + "\n";
206207
} else {
207-
Calendar calendar = Calendar.getInstance();
208-
calendar.setTime(dateCreated);
209-
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
210-
return String.format(Locale.ENGLISH, TEMPLATE_DATA_OTHER_SOURCE,
211-
calendar.get(Calendar.YEAR),
212-
calendar.get(Calendar.MONTH),
213-
calendar.get(Calendar.DAY_OF_MONTH)) + "\n";
208+
return String.format(Locale.ENGLISH, TEMPLATE_DATA_OTHER_SOURCE, dateFormat.format(dateCreated)) + "\n";
214209
}
215210
}
216211
return "";

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

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@
3131
import fr.free.nrw.commons.auth.AuthenticatedActivity;
3232
import fr.free.nrw.commons.auth.SessionManager;
3333
import fr.free.nrw.commons.location.LocationServiceManager;
34-
import fr.free.nrw.commons.nearby.NearbyFragment;
3534
import fr.free.nrw.commons.nearby.NearbyNotificationCardView;
35+
import fr.free.nrw.commons.nearby.fragments.NearbyParentFragment;
36+
import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter;
3637
import fr.free.nrw.commons.notification.Notification;
3738
import fr.free.nrw.commons.notification.NotificationActivity;
3839
import fr.free.nrw.commons.notification.NotificationController;
@@ -47,13 +48,15 @@
4748

4849
public class MainActivity extends AuthenticatedActivity implements FragmentManager.OnBackStackChangedListener {
4950

50-
@Inject
51-
SessionManager sessionManager;
52-
@Inject ContributionController controller;
5351
@BindView(R.id.tab_layout)
5452
TabLayout tabLayout;
5553
@BindView(R.id.pager)
5654
public UnswipableViewPager viewPager;
55+
56+
@Inject
57+
SessionManager sessionManager;
58+
@Inject
59+
ContributionController controller;
5760
@Inject
5861
public LocationServiceManager locationManager;
5962
@Inject
@@ -72,29 +75,16 @@ public class MainActivity extends AuthenticatedActivity implements FragmentManag
7275
public boolean isContributionsFragmentVisible = true; // False means nearby fragment is visible
7376
private Menu menu;
7477

75-
private boolean onOrientationChanged = false;
76-
7778
private MenuItem notificationsMenuItem;
7879
private TextView notificationCount;
7980

8081
public void onCreate(Bundle savedInstanceState) {
8182
super.onCreate(savedInstanceState);
8283
setContentView(R.layout.activity_contributions);
8384
ButterKnife.bind(this);
84-
8585
requestAuthToken();
8686
initDrawer();
8787
setTitle(getString(R.string.navigation_item_home)); // Should I create a new string variable with another name instead?
88-
89-
90-
if (savedInstanceState != null ) {
91-
onOrientationChanged = true; // Will be used in nearby fragment to determine significant update of map
92-
93-
//If nearby map was visible, call on Tab Selected to call all nearby operations
94-
/*if (savedInstanceState.getInt("viewPagerCurrentItem") == 1) {
95-
((NearbyFragment)contributionsActivityPagerAdapter.getItem(1)).onTabSelected(onOrientationChanged);
96-
}*/
97-
}
9888
}
9989

10090
@Override
@@ -161,9 +151,7 @@ public void setNumOfUploads(int uploadCount) {
161151
* tab won't change and vice versa. So we have to notify each of them.
162152
*/
163153
private void setTabAndViewPagerSynchronisation() {
164-
//viewPager.canScrollHorizontally(false);
165154
viewPager.setFocusableInTouchMode(true);
166-
167155
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
168156
@Override
169157
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
@@ -178,15 +166,14 @@ public void onPageSelected(int position) {
178166
tabLayout.getTabAt(CONTRIBUTIONS_TAB_POSITION).select();
179167
isContributionsFragmentVisible = true;
180168
updateMenuItem();
181-
182169
break;
183170
case NEARBY_TAB_POSITION:
184171
Timber.d("Nearby tab selected");
185172
tabLayout.getTabAt(NEARBY_TAB_POSITION).select();
186173
isContributionsFragmentVisible = false;
187174
updateMenuItem();
188175
// Do all permission and GPS related tasks on tab selected, not on create
189-
((NearbyFragment)contributionsActivityPagerAdapter.getItem(1)).onTabSelected(onOrientationChanged);
176+
NearbyParentFragmentPresenter.getInstance().onTabSelected();
190177
break;
191178
default:
192179
tabLayout.getTabAt(CONTRIBUTIONS_TAB_POSITION).select();
@@ -267,15 +254,7 @@ public void onBackPressed() {
267254
}
268255
} else if (getSupportFragmentManager().findFragmentByTag(nearbyFragmentTag) != null && !isContributionsFragmentVisible) {
269256
// Means that nearby fragment is visible (not contributions fragment)
270-
NearbyFragment nearbyFragment = (NearbyFragment) contributionsActivityPagerAdapter.getItem(1);
271-
272-
if(nearbyFragment.isBottomSheetExpanded()) {
273-
// Back should first hide the bottom sheet if it is expanded
274-
nearbyFragment.listOptionMenuItemClicked();
275-
} else {
276-
// Otherwise go back to contributions fragment
277-
viewPager.setCurrentItem(0);
278-
}
257+
NearbyParentFragmentPresenter.getInstance().backButtonClicked();
279258
} else {
280259
super.onBackPressed();
281260
}
@@ -332,12 +311,12 @@ private void updateMenuItem() {
332311
// Display notifications menu item
333312
menu.findItem(R.id.notifications).setVisible(true);
334313
menu.findItem(R.id.list_sheet).setVisible(false);
335-
Timber.d("Contributions activity notifications menu item is visible");
314+
Timber.d("Contributions fragment notifications menu item is visible");
336315
} else {
337316
// Display bottom list menu item
338317
menu.findItem(R.id.notifications).setVisible(false);
339318
menu.findItem(R.id.list_sheet).setVisible(true);
340-
Timber.d("Contributions activity list sheet menu item is visible");
319+
Timber.d("Nearby fragment list sheet menu item is visible");
341320
}
342321
}
343322
}
@@ -351,7 +330,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
351330
return true;
352331
case R.id.list_sheet:
353332
if (contributionsActivityPagerAdapter.getItem(1) != null) {
354-
((NearbyFragment)contributionsActivityPagerAdapter.getItem(1)).listOptionMenuItemClicked();
333+
((NearbyParentFragment)contributionsActivityPagerAdapter.getItem(1)).listOptionMenuItemClicked();
355334
}
356335
return true;
357336
default:
@@ -361,8 +340,6 @@ public boolean onOptionsItemSelected(MenuItem item) {
361340

362341
public class ContributionsActivityPagerAdapter extends FragmentPagerAdapter {
363342
FragmentManager fragmentManager;
364-
private boolean isContributionsListFragment = true; // to know what to put in first tab, Contributions of Media Details
365-
366343

367344
public ContributionsActivityPagerAdapter(FragmentManager fragmentManager) {
368345
super(fragmentManager);
@@ -392,12 +369,12 @@ public Fragment getItem(int position) {
392369
}
393370

394371
case 1:
395-
NearbyFragment retainedNearbyFragment = getNearbyFragment(1);
372+
NearbyParentFragment retainedNearbyFragment = getNearbyFragment(1);
396373
if (retainedNearbyFragment != null) {
397374
return retainedNearbyFragment;
398375
} else {
399376
// If we reach here, retainedNearbyFragment is null
400-
return new NearbyFragment();
377+
return new NearbyParentFragment();
401378
}
402379
default:
403380
return null;
@@ -419,9 +396,9 @@ private ContributionsFragment getContributionsFragment(int position) {
419396
* @param position index of tabs, in our case 0 or 1
420397
* @return
421398
*/
422-
private NearbyFragment getNearbyFragment(int position) {
399+
private NearbyParentFragment getNearbyFragment(int position) {
423400
String tag = makeFragmentName(R.id.pager, position);
424-
return (NearbyFragment)fragmentManager.findFragmentByTag(tag);
401+
return (NearbyParentFragment)fragmentManager.findFragmentByTag(tag);
425402
}
426403

427404
/**
@@ -444,7 +421,6 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
444421
controller.handleActivityResult(this, requestCode, resultCode, data);
445422
}
446423

447-
@Override
448424
protected void onResume() {
449425
super.onResume();
450426
setNotificationCount();

0 commit comments

Comments
 (0)