Skip to content

Commit 052ee6a

Browse files
committed
Merge branch 'master' into tests
2 parents 053a765 + 99c6f5f commit 052ee6a

File tree

137 files changed

+3258
-1580
lines changed

Some content is hidden

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

137 files changed

+3258
-1580
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,4 @@ app/src/main/jniLibs
3838
#Below removes all the HTML files related to OpenCV documentation. The documentation can be otherwise found at:
3939
#https://docs.opencv.org/3.3.0/
4040
/libraries/opencv/javadoc/
41+
captures/*

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ android:
2323
licenses:
2424
- android-sdk-license-.+
2525
script:
26-
- "./gradlew -Pcoverage clean check jacocoTestReport"
26+
- "./gradlew -Pcoverage lintBetaDebug pmd checkstyle jacocoTestBetaDebugUnitTestReport"
2727
- if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
2828
mkdir -p app/src/prodRelease/play/release-notes/en-US;
2929
fi

app/build.gradle

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
plugins {
2-
id 'com.github.triplet.play' version '2.2.1' apply false
2+
id 'com.github.triplet.play' version '2.7.2' apply false
33
}
44
apply from: '../gitutils.gradle'
55
apply plugin: 'com.android.application'
66
apply plugin: 'kotlin-android'
77
apply plugin: 'kotlin-kapt'
8-
apply plugin: 'jacoco-android'
8+
apply plugin: "com.hiya.jacoco-android"
99
apply from: 'quality.gradle'
1010

1111
def isRunningOnTravisAndIsNotPRBuild = System.getenv("CI") == "true" && file('../play.p12').exists()
@@ -102,15 +102,22 @@ dependencies {
102102

103103
//swipe_layout
104104
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
105+
106+
//Room
107+
def room_version= '2.2.3'
108+
implementation "androidx.room:room-runtime:$room_version"
109+
kapt "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor
105110
implementation 'com.squareup.retrofit2:retrofit:2.7.1'
111+
implementation "androidx.room:room-rxjava2:$room_version"
112+
testImplementation "androidx.arch.core:core-testing:2.1.0"
106113
}
107114

108115
android {
109116
compileSdkVersion 28
110117
buildToolsVersion "28.0.3"
111118

112119
defaultConfig {
113-
applicationId 'fr.free.nrw.commons'
120+
//applicationId 'fr.free.nrw.commons'
114121
versionCode 561
115122
versionName '2.12.3'
116123
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())

app/src/main/AndroidManifest.xml

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
android:excludeFromRecents="true"
4242
android:finishOnTaskLaunch="true" />
4343

44+
<activity
45+
android:name=".media.ZoomableActivity" />
46+
4447
<activity android:name=".auth.LoginActivity">
4548
<intent-filter>
4649
<category android:name="android.intent.category.LAUNCHER" />
@@ -82,7 +85,7 @@
8285
android:name=".contributions.MainActivity"
8386
android:icon="@mipmap/ic_launcher"
8487
android:label="@string/app_name"
85-
android:configChanges="screenSize|keyboard" />
88+
android:configChanges="screenSize|keyboard|orientation" />
8689
<activity
8790
android:name=".settings.SettingsActivity"
8891
android:label="@string/title_activity_settings" />
@@ -154,18 +157,6 @@
154157
android:name="android.accounts.AccountAuthenticator"
155158
android:resource="@xml/authenticator" />
156159
</service>
157-
<service
158-
android:name=".contributions.ContributionsSyncService"
159-
android:exported="true"
160-
android:process=":sync">
161-
<intent-filter>
162-
<action android:name="android.content.SyncAdapter" />
163-
</intent-filter>
164-
165-
<meta-data
166-
android:name="android.content.SyncAdapter"
167-
android:resource="@xml/contributions_sync_adapter" />
168-
</service>
169160

170161
<service
171162
android:name="org.acra.sender.SenderService"
@@ -181,12 +172,6 @@
181172
android:name="android.support.FILE_PROVIDER_PATHS"
182173
android:resource="@xml/provider_paths" />
183174
</provider>
184-
<provider
185-
android:name=".contributions.ContributionsContentProvider"
186-
android:authorities="${applicationId}.contributions.contentprovider"
187-
android:exported="false"
188-
android:label="@string/provider_contributions"
189-
android:syncable="true" />
190175

191176
<provider
192177
android:name=".category.CategoryContentProvider"

app/src/main/java/fr/free/nrw/commons/CommonsApplication.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import android.app.NotificationManager;
77
import android.content.Context;
88
import android.database.sqlite.SQLiteDatabase;
9+
import android.database.sqlite.SQLiteException;
910
import android.os.Build;
1011
import android.os.Process;
1112
import android.util.Log;
@@ -44,8 +45,8 @@
4445
import fr.free.nrw.commons.category.CategoryDao;
4546
import fr.free.nrw.commons.concurrency.BackgroundPoolExceptionHandler;
4647
import fr.free.nrw.commons.concurrency.ThreadPoolService;
47-
import fr.free.nrw.commons.contributions.ContributionDao;
4848
import fr.free.nrw.commons.data.DBOpenHelper;
49+
import fr.free.nrw.commons.db.AppDatabase;
4950
import fr.free.nrw.commons.di.ApplicationlessInjection;
5051
import fr.free.nrw.commons.kvstore.JsonKvStore;
5152
import fr.free.nrw.commons.logging.FileLoggingTree;
@@ -60,6 +61,7 @@
6061
import okhttp3.OkHttpClient;
6162
import timber.log.Timber;
6263

64+
import static fr.free.nrw.commons.data.DBOpenHelper.CONTRIBUTIONS_TABLE;
6365
import static org.acra.ReportField.ANDROID_VERSION;
6466
import static org.acra.ReportField.APP_VERSION_CODE;
6567
import static org.acra.ReportField.APP_VERSION_NAME;
@@ -126,6 +128,9 @@ public AppLanguageLookUpTable getLanguageLookUpTable() {
126128
return languageLookUpTable;
127129
}
128130

131+
@Inject
132+
AppDatabase appDatabase;
133+
129134
/**
130135
* Used to declare and initialize various components and dependencies
131136
*/
@@ -306,11 +311,13 @@ private void updateAllDatabases() {
306311
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
307312

308313
CategoryDao.Table.onDelete(db);
309-
ContributionDao.Table.onDelete(db);
314+
dbOpenHelper.deleteTable(db,CONTRIBUTIONS_TABLE);//Delete the contributions table in the existing db on older versions
315+
appDatabase.getContributionDao().deleteAll();
310316
BookmarkPicturesDao.Table.onDelete(db);
311317
BookmarkLocationsDao.Table.onDelete(db);
312318
}
313319

320+
314321
/**
315322
* Interface used to get log-out events
316323
*/

app/src/main/java/fr/free/nrw/commons/Media.java

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import androidx.annotation.NonNull;
88
import androidx.annotation.Nullable;
9+
import androidx.room.Entity;
10+
import androidx.room.PrimaryKey;
911

1012
import org.apache.commons.lang3.StringUtils;
1113
import org.wikipedia.dataclient.mwapi.MwQueryPage;
@@ -26,6 +28,7 @@
2628
import fr.free.nrw.commons.utils.CommonsDateUtil;
2729
import fr.free.nrw.commons.utils.MediaDataExtractorUtil;
2830

31+
@Entity
2932
public class Media implements Parcelable {
3033

3134
public static final Media EMPTY = new Media("");
@@ -42,25 +45,25 @@ public Media[] newArray(int i) {
4245
};
4346

4447
// Primary metadata fields
45-
protected Uri localUri;
46-
private String thumbUrl;
47-
protected String imageUrl;
48-
protected String filename;
49-
protected String description; // monolingual description on input...
50-
protected String discussion;
51-
protected long dataLength;
52-
protected Date dateCreated;
53-
protected @Nullable Date dateUploaded;
54-
protected int width;
55-
protected int height;
56-
protected String license;
57-
protected String licenseUrl;
58-
protected String creator;
59-
protected ArrayList<String> categories; // as loaded at runtime?
60-
protected boolean requestedDeletion;
61-
private Map<String, String> descriptions; // multilingual descriptions as loaded
62-
private HashMap<String, Object> tags = new HashMap<>();
63-
private @Nullable LatLng coordinates;
48+
public Uri localUri;
49+
public String thumbUrl;
50+
public String imageUrl;
51+
public String filename;
52+
public String description; // monolingual description on input...
53+
public String discussion;
54+
long dataLength;
55+
public Date dateCreated;
56+
@Nullable public Date dateUploaded;
57+
public int width;
58+
public int height;
59+
public String license;
60+
public String licenseUrl;
61+
public String creator;
62+
public ArrayList<String> categories; // as loaded at runtime?
63+
public boolean requestedDeletion;
64+
public HashMap<String, String> descriptions; // multilingual descriptions as loaded
65+
public HashMap<String, String> tags = new HashMap<>();
66+
@Nullable public LatLng coordinates;
6467

6568
/**
6669
* Provides local constructor
@@ -118,7 +121,7 @@ public Media(Parcel in) {
118121
dateCreated = (Date) in.readSerializable();
119122
dateUploaded = (Date) in.readSerializable();
120123
creator = in.readString();
121-
tags = (HashMap<String, Object>) in.readSerializable();
124+
tags = (HashMap<String, String>) in.readSerializable();
122125
width = in.readInt();
123126
height = in.readInt();
124127
license = in.readString();
@@ -218,7 +221,7 @@ public Object getTag(String key) {
218221
* @param key Media key
219222
* @param value Media value
220223
*/
221-
public void setTag(String key, Object value) {
224+
public void setTag(String key, String value) {
222225
tags.put(key, value);
223226
}
224227

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

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ public class AchievementsActivity extends NavigationBaseActivity {
110110

111111
private CompositeDisposable compositeDisposable = new CompositeDisposable();
112112

113+
// To keep track of the number of wiki edits made by a user
114+
private int numberOfEdits = 0;
115+
113116
/**
114117
* This method helps in the creation Achievement screen and
115118
* dynamically set the size of imageView
@@ -140,8 +143,8 @@ protected void onCreate(Bundle savedInstanceState) {
140143
progressBar.setVisibility(View.VISIBLE);
141144

142145
hideLayouts();
143-
setAchievements();
144146
setWikidataEditCount();
147+
setAchievements();
145148
initDrawer();
146149
}
147150

@@ -230,12 +233,24 @@ private void setAchievements() {
230233
Timber.d("success");
231234
layoutImageReverts.setVisibility(View.INVISIBLE);
232235
imageView.setVisibility(View.INVISIBLE);
233-
showSnackBarWithRetry();
236+
// If the number of edits made by the user are more than 150,000
237+
// in some cases such high number of wiki edit counts cause the
238+
// achievements calculator to fail in some cases, for more details
239+
// refer Issue: #3295
240+
if (numberOfEdits <= 150000) {
241+
showSnackBarWithRetry(false);
242+
} else {
243+
showSnackBarWithRetry(true);
244+
}
234245
}
235246
},
236247
t -> {
237248
Timber.e(t, "Fetching achievements statistics failed");
238-
showSnackBarWithRetry();
249+
if (numberOfEdits <= 150000) {
250+
showSnackBarWithRetry(false);
251+
} else {
252+
showSnackBarWithRetry(true);
253+
}
239254
}
240255
));
241256
}
@@ -259,19 +274,31 @@ private void setWikidataEditCount() {
259274
.getWikidataEdits(userName)
260275
.subscribeOn(Schedulers.io())
261276
.observeOn(AndroidSchedulers.mainThread())
262-
.subscribe(edits -> wikidataEditsText.setText(String.valueOf(edits)), e -> {
277+
.subscribe(edits -> {
278+
numberOfEdits = edits;
279+
wikidataEditsText.setText(String.valueOf(edits));
280+
}, e -> {
263281
Timber.e("Error:" + e);
264282
}));
265283
}
266284

267285
/**
268286
* Shows a snack bar which has an action button which on click dismisses the snackbar and invokes the
269287
* listener passed
288+
* @param tooManyAchievements if this value is true it means that the number of achievements of the
289+
* user are so high that it wrecks havoc with the Achievements calculator due to which request may time
290+
* out. Well this is the Ultimate Achievement
270291
*/
271-
private void showSnackBarWithRetry() {
272-
progressBar.setVisibility(View.GONE);
273-
ViewUtil.showDismissibleSnackBar(findViewById(android.R.id.content),
274-
R.string.achievements_fetch_failed, R.string.retry, view -> setAchievements());
292+
private void showSnackBarWithRetry(boolean tooManyAchievements) {
293+
if (tooManyAchievements) {
294+
progressBar.setVisibility(View.GONE);
295+
ViewUtil.showDismissibleSnackBar(findViewById(android.R.id.content),
296+
R.string.achievements_fetch_failed_ultimate_achievement, R.string.retry, view -> setAchievements());
297+
} else {
298+
progressBar.setVisibility(View.GONE);
299+
ViewUtil.showDismissibleSnackBar(findViewById(android.R.id.content),
300+
R.string.achievements_fetch_failed, R.string.retry, view -> setAchievements());
301+
}
275302
}
276303

277304
/**
@@ -504,4 +531,4 @@ private boolean checkAccount(){
504531
return true;
505532
}
506533

507-
}
534+
}

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import fr.free.nrw.commons.kvstore.JsonKvStore;
5656
import fr.free.nrw.commons.theme.NavigationBaseActivity;
5757
import fr.free.nrw.commons.utils.ConfigUtils;
58+
import fr.free.nrw.commons.utils.SystemThemeUtils;
5859
import fr.free.nrw.commons.utils.ViewUtil;
5960
import io.reactivex.disposables.CompositeDisposable;
6061
import retrofit2.Call;
@@ -83,6 +84,9 @@ public class LoginActivity extends AccountAuthenticatorActivity {
8384
@Inject
8485
LoginClient loginClient;
8586

87+
@Inject
88+
SystemThemeUtils systemThemeUtils;
89+
8690
@BindView(R.id.login_button)
8791
Button loginButton;
8892

@@ -121,7 +125,7 @@ public void onCreate(Bundle savedInstanceState) {
121125
.getCommonsApplicationComponent()
122126
.inject(this);
123127

124-
boolean isDarkTheme = applicationKvStore.getBoolean("theme", false);
128+
boolean isDarkTheme = systemThemeUtils.isDeviceInNightMode();
125129
setTheme(isDarkTheme ? R.style.DarkAppTheme : R.style.LightAppTheme);
126130
getDelegate().installViewFactory();
127131
getDelegate().onCreate(savedInstanceState);
@@ -133,7 +137,7 @@ public void onCreate(Bundle savedInstanceState) {
133137
usernameEdit.addTextChangedListener(textWatcher);
134138
passwordEdit.addTextChangedListener(textWatcher);
135139
twoFactorEdit.addTextChangedListener(textWatcher);
136-
140+
137141
if (ConfigUtils.isBetaFlavour()) {
138142
loginCredentials.setText(getString(R.string.login_credential));
139143
} else {
@@ -264,7 +268,7 @@ private void doLogin(String username, String password, String twoFactorCode) {
264268
new Callback<MwQueryResponse>() {
265269
@Override
266270
public void onResponse(Call<MwQueryResponse> call,
267-
Response<MwQueryResponse> response) {
271+
Response<MwQueryResponse> response) {
268272
loginClient.login(commonsWikiSite, username, password, null, twoFactorCode,
269273
response.body().query().loginToken(), new LoginCallback() {
270274
@Override
@@ -275,7 +279,7 @@ public void success(@NonNull LoginResult result) {
275279

276280
@Override
277281
public void twoFactorPrompt(@NonNull Throwable caught,
278-
@Nullable String token) {
282+
@Nullable String token) {
279283
Timber.d("Requesting 2FA prompt");
280284
hideProgress();
281285
askUserForTwoFactorAuth();

0 commit comments

Comments
 (0)