Skip to content

Commit 3cdfdcf

Browse files
madhurgupta10misaochannicolas-raoulneslihanturan
authored
Merge 4.0-release into master (#5028)
* Fix string for custom selector * Fix bug #4950 back arrow still present on top-level activity (#4952) * Fix bug #4949 by correctly setting previous db version number (#4956) * Fix bug #4949 by correctly setting previous db version number * Fix failing tests * Fix bug #4959 by correctly setting previous db version number and updating the current db version (#4960) * Fix bug #4957 (#4961) * Update library to new version that handles older Java VMs Fixes #4972 I believe. * Versioning for v4.0.0 * Changelog for v4.0.0 * Fix bug #4984 Added queries for package name for Android API 30+ (#4987) * Update mapbox sdk version (#4989) * Versioning for v4.0.1 * Changelog for v4.0.1 * Remove network type information from NetworkUtils (#4996) * Remove network type information from NetworkUtils * Ignore dependent tests * Fix #4992 invert the equals condition to be null safe (#4995) * Fix java.lang.NullPointerException for username in ContributionBoundaryCallback (#5003) * Fix failing tests for PR #5003 (#5004) * Fix java.lang.NullPointerException for username in ContributionBoundaryCallback * Fix failing tests * Update Room DB Version (#5011) * Fix #5001 (#5010) * Fix DB update issue (#5016) * [WIP] Fix both timezone problem and saved date problem (#5019) * Fix both timezone problem and saved date problem * Fixaccidental test code and add comments * Add issue link to the comments * Fix format issue and null checks * Versioning for v4.0.2 * Changelog for v4.0.2 * Add "Report Violation" menu option (#5025) * Add "Report Violation" menu option * Update email template * Update email address * Fixed typo Co-authored-by: Josephine Lim <josephinelim86@gmail.com> * Versioning for v4.0.3 * Changelog for v4.0.3 Co-authored-by: Josephine Lim <josephinelim86@gmail.com> Co-authored-by: Nicolas Raoul <nicolas.raoul@gmail.com> Co-authored-by: neslihanturan <tur.neslihan@gmail.com>
1 parent 1de8968 commit 3cdfdcf

29 files changed

+406
-72
lines changed

CHANGELOG.md

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

3+
## v4.0.3
4+
- Added "Report" button for Google UGC policy
5+
6+
## v4.0.2
7+
- Fixed bug with wrong dates taken from EXIF
8+
- Fixed various crashes
9+
10+
## v4.0.1
11+
- Fixed bug with no browser found
12+
- Updated Mapbox SDK to fix hamburger crash
13+
14+
## v4.0.0
15+
- Added map showing nearby Commons pictures
16+
- Added custom SPARQL queries
17+
- Added user profiles
18+
- Added custom picture selector
19+
- Various bugfixes
20+
- Updated target SDK to 30
21+
322
## v3.1.1
423
- Optimized Nearby query
524
- Added Sweden's property for WLM 2021

app/build.gradle

+6-6
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ dependencies {
3838
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
3939
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
4040
implementation 'com.github.pedrovgs:renderers:3.3.3'
41-
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.1.0'
42-
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v8:0.11.0'
43-
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.4.0'
44-
implementation 'com.mapbox.mapboxsdk:mapbox-android-telemetry:6.1.0'
41+
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1'
42+
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v9:0.12.0'
43+
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.5.0'
44+
implementation 'com.mapbox.mapboxsdk:mapbox-android-telemetry:7.0.0'
4545
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
4646
implementation 'com.dinuscxj:circleprogressbar:1.1.1'
4747
implementation 'com.karumi:dexter:5.0.0'
@@ -173,8 +173,8 @@ android {
173173
defaultConfig {
174174
//applicationId 'fr.free.nrw.commons'
175175

176-
versionCode 1025
177-
versionName '3.1.1'
176+
versionCode 1029
177+
versionName '4.0.3'
178178
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
179179

180180
minSdkVersion 19

app/src/main/AndroidManifest.xml

+10
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@
1818
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
1919
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
2020

21+
<queries>
22+
<!-- Browser -->
23+
<intent>
24+
<action android:name="android.intent.action.VIEW" />
25+
<category android:name="android.intent.category.BROWSABLE" />
26+
<data android:scheme="https" />
27+
</intent>
28+
<!-- Google Maps -->
29+
<package android:name="com.google.android.apps.maps" />
30+
</queries>
2131

2232

2333
<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->

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

+4
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ public class CommonsApplication extends MultiDexApplication {
110110

111111
public static final String FEEDBACK_EMAIL_SUBJECT = "Commons Android App Feedback";
112112

113+
public static final String REPORT_EMAIL = "commons-app-android-private@googlegroups.com";
114+
115+
public static final String REPORT_EMAIL_SUBJECT = "Report a violation";
116+
113117
public static final String NOTIFICATION_CHANNEL_ID_ALL = "CommonsNotificationAll";
114118

115119
public static final String FEEDBACK_EMAIL_TEMPLATE_HEADER = "-- Technical information --";

app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ protected void onCreate(@Nullable final Bundle savedInstanceState) {
155155
addCredits();
156156
getToolbarUI();
157157

158-
if (activity.equals("UploadActivity")) {
158+
if ("UploadActivity".equals(activity)) {
159159
placeSelectedButton.setVisibility(View.GONE);
160160
modifyLocationButton.setVisibility(View.VISIBLE);
161161
showInMapButton.setVisibility(View.VISIBLE);

app/src/main/java/fr/free/nrw/commons/bookmarks/items/BookmarkItemsDao.java

+4-8
Original file line numberDiff line numberDiff line change
@@ -309,22 +309,18 @@ public static void onUpdate(final SQLiteDatabase db, int from, final int to) {
309309
if (from == to) {
310310
return;
311311
}
312-
if (from < 7) {
312+
if (from < 18) {
313+
// doesn't exist yet
313314
from++;
314315
onUpdate(db, from, to);
315316
return;
316317
}
317318

318-
if (from == 7) {
319+
if (from == 18) {
320+
// table added in version 19
319321
onCreate(db);
320322
from++;
321323
onUpdate(db, from, to);
322-
return;
323-
}
324-
325-
if (from == 8) {
326-
from++;
327-
onUpdate(db, from, to);
328324
}
329325
}
330326
}

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

+12-3
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,11 @@ List<CategoryItem> recentCategories(int limit) {
9393
// fixme add a limit on the original query instead of falling out of the loop?
9494
while (cursor != null && cursor.moveToNext()
9595
&& cursor.getPosition() < limit) {
96-
items.add(new CategoryItem(fromCursor(cursor).getName(),
97-
fromCursor(cursor).getDescription(), fromCursor(cursor).getThumbnail(),
98-
false));
96+
if (fromCursor(cursor).getName() != null ) {
97+
items.add(new CategoryItem(fromCursor(cursor).getName(),
98+
fromCursor(cursor).getDescription(), fromCursor(cursor).getThumbnail(),
99+
false));
100+
}
99101
}
100102
} catch (RemoteException e) {
101103
throw new RuntimeException(e);
@@ -193,6 +195,13 @@ public static void onUpdate(SQLiteDatabase db, int from, int to) {
193195
onUpdate(db, from, to);
194196
return;
195197
}
198+
if (from == 17) {
199+
db.execSQL("ALTER TABLE categories ADD COLUMN description STRING;");
200+
db.execSQL("ALTER TABLE categories ADD COLUMN thumbnail STRING;");
201+
from++;
202+
onUpdate(db, from, to);
203+
return;
204+
}
196205
}
197206
}
198207
}

app/src/main/java/fr/free/nrw/commons/category/CategoryItem.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import android.os.Parcelable
44
import kotlinx.android.parcel.Parcelize
55

66
@Parcelize
7-
data class CategoryItem(val name: String, val description: String,
8-
val thumbnail: String, var isSelected: Boolean) : Parcelable {
7+
data class CategoryItem(val name: String, val description: String?,
8+
val thumbnail: String?, var isSelected: Boolean) : Parcelable {
99

1010
override fun toString(): String {
1111
return "CategoryItem: '$name'"

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

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ data class Contribution constructor(
3838
val localUri: Uri? = null,
3939
var dataLength: Long = 0,
4040
var dateCreated: Date? = null,
41+
var dateCreatedString: String? = null,
4142
var dateModified: Date? = null,
4243
var hasInvalidLocation : Int = 0,
4344
var contentUri: Uri? = null,
@@ -70,6 +71,7 @@ data class Contribution constructor(
7071
depictedItems = depictedItems,
7172
wikidataPlace = from(item.place),
7273
contentUri = item.contentUri,
74+
dateCreatedString = item.fileCreatedDateString,
7375
imageSHA1 = imageSHA1
7476
)
7577

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

+12-10
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class ContributionBoundaryCallback @Inject constructor(
2121
@param:Named(CommonsApplicationModule.IO_THREAD) private val ioThreadScheduler: Scheduler
2222
) : BoundaryCallback<Contribution>() {
2323
private val compositeDisposable: CompositeDisposable = CompositeDisposable()
24-
lateinit var userName: String
24+
var userName: String? = null
2525

2626

2727
/**
@@ -53,13 +53,13 @@ class ContributionBoundaryCallback @Inject constructor(
5353
/**
5454
* Fetches contributions using the MediaWiki API
5555
*/
56-
fun fetchContributions() {
56+
private fun fetchContributions() {
5757
if (sessionManager.userName != null) {
58-
compositeDisposable.add(
59-
mediaClient.getMediaListForUser(userName!!)
58+
userName?.let { userName ->
59+
mediaClient.getMediaListForUser(userName)
6060
.map { mediaList ->
61-
mediaList.map {
62-
Contribution(media = it, state = Contribution.STATE_COMPLETED)
61+
mediaList.map { media ->
62+
Contribution(media = media, state = Contribution.STATE_COMPLETED)
6363
}
6464
}
6565
.subscribeOn(ioThreadScheduler)
@@ -69,11 +69,13 @@ class ContributionBoundaryCallback @Inject constructor(
6969
error.message
7070
)
7171
}
72-
)
73-
}else {
74-
if (compositeDisposable != null){
75-
compositeDisposable.clear()
72+
}?.let {
73+
compositeDisposable.add(
74+
it
75+
)
7676
}
77+
}else {
78+
compositeDisposable.clear()
7779
}
7880
}
7981

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ public Integer getContributionStateAt(int position) {
661661
}
662662

663663
public boolean backButtonClicked() {
664-
if (null != mediaDetailPagerFragment && mediaDetailPagerFragment.isVisible()) {
664+
if (mediaDetailPagerFragment != null && mediaDetailPagerFragment.isVisible()) {
665665
if (store.getBoolean("displayNearbyCardView", true) && !isUserProfile) {
666666
if (nearbyNotificationCardView.cardViewVisibilityState == NearbyNotificationCardView.CardViewVisibilityState.READY) {
667667
nearbyNotificationCardView.setVisibility(View.VISIBLE);
@@ -678,9 +678,10 @@ public boolean backButtonClicked() {
678678
}else {
679679
fetchCampaigns();
680680
}
681-
if(getActivity() instanceof MainActivity) {
681+
if (getActivity() instanceof MainActivity) {
682682
// Fragment is associated with MainActivity
683-
((MainActivity)getActivity()).showTabs();
683+
((BaseActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
684+
((MainActivity) getActivity()).showTabs();
684685
}
685686
return true;
686687
}

app/src/main/java/fr/free/nrw/commons/data/DBOpenHelper.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
import android.database.sqlite.SQLiteDatabase;
55
import android.database.sqlite.SQLiteException;
66
import android.database.sqlite.SQLiteOpenHelper;
7-
87
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao;
9-
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table;
108
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
119
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao;
1210
import fr.free.nrw.commons.category.CategoryDao;
@@ -16,7 +14,7 @@
1614
public class DBOpenHelper extends SQLiteOpenHelper {
1715

1816
private static final String DATABASE_NAME = "commons.db";
19-
private static final int DATABASE_VERSION = 19;
17+
private static final int DATABASE_VERSION = 20;
2018
public static final String CONTRIBUTIONS_TABLE = "contributions";
2119
private final String DROP_TABLE_STATEMENT="DROP TABLE IF EXISTS %s";
2220

app/src/main/java/fr/free/nrw/commons/db/AppDatabase.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import fr.free.nrw.commons.upload.depicts.DepictsDao
1414
* The database for accessing the respective DAOs
1515
*
1616
*/
17-
@Database(entities = [Contribution::class, Depicts::class, UploadedStatus::class], version = 12, exportSchema = false)
17+
@Database(entities = [Contribution::class, Depicts::class, UploadedStatus::class], version = 13, exportSchema = false)
1818
@TypeConverters(Converters::class)
1919
abstract class AppDatabase : RoomDatabase() {
2020
abstract fun contributionDao(): ContributionDao

app/src/main/java/fr/free/nrw/commons/description/DescriptionEditActivity.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,7 @@ class DescriptionEditActivity : BaseActivity(), UploadMediaDetailAdapter.EventLi
154154
buffer.append("}}, ")
155155
}
156156
}
157-
buffer.deleteCharAt(buffer.length - 1)
158-
buffer.deleteCharAt(buffer.length - 1)
157+
buffer.replace(", $".toRegex(), "")
159158
buffer.append(descriptionEnd)
160159
}
161160
val returningIntent = Intent()

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

+34-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
import java.io.File;
1414
import java.io.IOException;
15+
import java.text.ParseException;
16+
import java.text.SimpleDateFormat;
1517
import java.util.Date;
1618

1719
import fr.free.nrw.commons.upload.FileUtils;
@@ -124,13 +126,30 @@ private DateTimeWithSource getFileCreatedDateFromCP(Context context) {
124126
private DateTimeWithSource getDateTimeFromExif() {
125127
try {
126128
ExifInterface exif = new ExifInterface(file.getAbsolutePath());
127-
@SuppressLint("RestrictedApi") Long dateTime = exif.getDateTime();
128-
if(dateTime != null){
129-
Date date = new Date(dateTime);
130-
return new DateTimeWithSource(date, DateTimeWithSource.EXIF_SOURCE);
129+
// TAG_DATETIME returns the last edited date, we need TAG_DATETIME_ORIGINAL for creation date
130+
// See issue https://github.com/commons-app/apps-android-commons/issues/1971
131+
String dateTimeSubString = exif.getAttribute(ExifInterface.TAG_DATETIME_ORIGINAL);
132+
if (dateTimeSubString!=null) { //getAttribute may return null
133+
String year = dateTimeSubString.substring(0,4);
134+
String month = dateTimeSubString.substring(5,7);
135+
String day = dateTimeSubString.substring(8,10);
136+
// This date is stored as a string (not as a date), the rason is we don't want to include timezones
137+
String dateCreatedString = String.format("%04d-%02d-%02d", Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day));
138+
if (dateCreatedString.length() == 10) { //yyyy-MM-dd format of date is expected
139+
@SuppressLint("RestrictedApi") Long dateTime = exif.getDateTimeOriginal();
140+
if(dateTime != null){
141+
Date date = new Date(dateTime);
142+
return new DateTimeWithSource(date, dateCreatedString, DateTimeWithSource.EXIF_SOURCE);
143+
}
144+
}
131145
}
146+
132147
} catch (IOException e) {
133148
e.printStackTrace();
149+
} catch (NumberFormatException e) {
150+
e.printStackTrace();
151+
} catch (IndexOutOfBoundsException e) {
152+
e.printStackTrace();
134153
}
135154
return null;
136155
}
@@ -149,6 +168,7 @@ public class DateTimeWithSource {
149168
public static final String EXIF_SOURCE = "exif";
150169

151170
private final long epochDate;
171+
private String dateString; // this does not includes timezone information
152172
private final String source;
153173

154174
public DateTimeWithSource(long epochDate, String source) {
@@ -161,10 +181,20 @@ public DateTimeWithSource(Date date, String source) {
161181
this.source = source;
162182
}
163183

184+
public DateTimeWithSource(Date date, String dateString, String source) {
185+
this.epochDate = date.getTime();
186+
this.dateString = dateString;
187+
this.source = source;
188+
}
189+
164190
public long getEpochDate() {
165191
return epochDate;
166192
}
167193

194+
public String getDateString() {
195+
return dateString;
196+
}
197+
168198
public String getSource() {
169199
return source;
170200
}

0 commit comments

Comments
 (0)