mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
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>
This commit is contained in:
parent
1de8968fa8
commit
3cdfdcffe1
29 changed files with 406 additions and 72 deletions
19
CHANGELOG.md
19
CHANGELOG.md
|
|
@ -1,5 +1,24 @@
|
||||||
# Wikimedia Commons for Android
|
# Wikimedia Commons for Android
|
||||||
|
|
||||||
|
## v4.0.3
|
||||||
|
- Added "Report" button for Google UGC policy
|
||||||
|
|
||||||
|
## v4.0.2
|
||||||
|
- Fixed bug with wrong dates taken from EXIF
|
||||||
|
- Fixed various crashes
|
||||||
|
|
||||||
|
## v4.0.1
|
||||||
|
- Fixed bug with no browser found
|
||||||
|
- Updated Mapbox SDK to fix hamburger crash
|
||||||
|
|
||||||
|
## v4.0.0
|
||||||
|
- Added map showing nearby Commons pictures
|
||||||
|
- Added custom SPARQL queries
|
||||||
|
- Added user profiles
|
||||||
|
- Added custom picture selector
|
||||||
|
- Various bugfixes
|
||||||
|
- Updated target SDK to 30
|
||||||
|
|
||||||
## v3.1.1
|
## v3.1.1
|
||||||
- Optimized Nearby query
|
- Optimized Nearby query
|
||||||
- Added Sweden's property for WLM 2021
|
- Added Sweden's property for WLM 2021
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,10 @@ dependencies {
|
||||||
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
|
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
|
||||||
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
|
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
|
||||||
implementation 'com.github.pedrovgs:renderers:3.3.3'
|
implementation 'com.github.pedrovgs:renderers:3.3.3'
|
||||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.1.0'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1'
|
||||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v8:0.11.0'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v9:0.12.0'
|
||||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.4.0'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.5.0'
|
||||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-telemetry:6.1.0'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-telemetry:7.0.0'
|
||||||
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
|
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
|
||||||
implementation 'com.dinuscxj:circleprogressbar:1.1.1'
|
implementation 'com.dinuscxj:circleprogressbar:1.1.1'
|
||||||
implementation 'com.karumi:dexter:5.0.0'
|
implementation 'com.karumi:dexter:5.0.0'
|
||||||
|
|
@ -173,8 +173,8 @@ android {
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
//applicationId 'fr.free.nrw.commons'
|
//applicationId 'fr.free.nrw.commons'
|
||||||
|
|
||||||
versionCode 1025
|
versionCode 1029
|
||||||
versionName '3.1.1'
|
versionName '4.0.3'
|
||||||
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
|
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
|
||||||
|
|
||||||
minSdkVersion 19
|
minSdkVersion 19
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,16 @@
|
||||||
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
|
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
|
<queries>
|
||||||
|
<!-- Browser -->
|
||||||
|
<intent>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<data android:scheme="https" />
|
||||||
|
</intent>
|
||||||
|
<!-- Google Maps -->
|
||||||
|
<package android:name="com.google.android.apps.maps" />
|
||||||
|
</queries>
|
||||||
|
|
||||||
|
|
||||||
<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
|
<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,10 @@ public class CommonsApplication extends MultiDexApplication {
|
||||||
|
|
||||||
public static final String FEEDBACK_EMAIL_SUBJECT = "Commons Android App Feedback";
|
public static final String FEEDBACK_EMAIL_SUBJECT = "Commons Android App Feedback";
|
||||||
|
|
||||||
|
public static final String REPORT_EMAIL = "commons-app-android-private@googlegroups.com";
|
||||||
|
|
||||||
|
public static final String REPORT_EMAIL_SUBJECT = "Report a violation";
|
||||||
|
|
||||||
public static final String NOTIFICATION_CHANNEL_ID_ALL = "CommonsNotificationAll";
|
public static final String NOTIFICATION_CHANNEL_ID_ALL = "CommonsNotificationAll";
|
||||||
|
|
||||||
public static final String FEEDBACK_EMAIL_TEMPLATE_HEADER = "-- Technical information --";
|
public static final String FEEDBACK_EMAIL_TEMPLATE_HEADER = "-- Technical information --";
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
||||||
addCredits();
|
addCredits();
|
||||||
getToolbarUI();
|
getToolbarUI();
|
||||||
|
|
||||||
if (activity.equals("UploadActivity")) {
|
if ("UploadActivity".equals(activity)) {
|
||||||
placeSelectedButton.setVisibility(View.GONE);
|
placeSelectedButton.setVisibility(View.GONE);
|
||||||
modifyLocationButton.setVisibility(View.VISIBLE);
|
modifyLocationButton.setVisibility(View.VISIBLE);
|
||||||
showInMapButton.setVisibility(View.VISIBLE);
|
showInMapButton.setVisibility(View.VISIBLE);
|
||||||
|
|
|
||||||
|
|
@ -309,22 +309,18 @@ public class BookmarkItemsDao {
|
||||||
if (from == to) {
|
if (from == to) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (from < 7) {
|
if (from < 18) {
|
||||||
|
// doesn't exist yet
|
||||||
from++;
|
from++;
|
||||||
onUpdate(db, from, to);
|
onUpdate(db, from, to);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (from == 7) {
|
if (from == 18) {
|
||||||
|
// table added in version 19
|
||||||
onCreate(db);
|
onCreate(db);
|
||||||
from++;
|
from++;
|
||||||
onUpdate(db, from, to);
|
onUpdate(db, from, to);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (from == 8) {
|
|
||||||
from++;
|
|
||||||
onUpdate(db, from, to);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,9 +93,11 @@ public class CategoryDao {
|
||||||
// fixme add a limit on the original query instead of falling out of the loop?
|
// fixme add a limit on the original query instead of falling out of the loop?
|
||||||
while (cursor != null && cursor.moveToNext()
|
while (cursor != null && cursor.moveToNext()
|
||||||
&& cursor.getPosition() < limit) {
|
&& cursor.getPosition() < limit) {
|
||||||
items.add(new CategoryItem(fromCursor(cursor).getName(),
|
if (fromCursor(cursor).getName() != null ) {
|
||||||
fromCursor(cursor).getDescription(), fromCursor(cursor).getThumbnail(),
|
items.add(new CategoryItem(fromCursor(cursor).getName(),
|
||||||
false));
|
fromCursor(cursor).getDescription(), fromCursor(cursor).getThumbnail(),
|
||||||
|
false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|
@ -193,6 +195,13 @@ public class CategoryDao {
|
||||||
onUpdate(db, from, to);
|
onUpdate(db, from, to);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (from == 17) {
|
||||||
|
db.execSQL("ALTER TABLE categories ADD COLUMN description STRING;");
|
||||||
|
db.execSQL("ALTER TABLE categories ADD COLUMN thumbnail STRING;");
|
||||||
|
from++;
|
||||||
|
onUpdate(db, from, to);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import android.os.Parcelable
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.android.parcel.Parcelize
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class CategoryItem(val name: String, val description: String,
|
data class CategoryItem(val name: String, val description: String?,
|
||||||
val thumbnail: String, var isSelected: Boolean) : Parcelable {
|
val thumbnail: String?, var isSelected: Boolean) : Parcelable {
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "CategoryItem: '$name'"
|
return "CategoryItem: '$name'"
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ data class Contribution constructor(
|
||||||
val localUri: Uri? = null,
|
val localUri: Uri? = null,
|
||||||
var dataLength: Long = 0,
|
var dataLength: Long = 0,
|
||||||
var dateCreated: Date? = null,
|
var dateCreated: Date? = null,
|
||||||
|
var dateCreatedString: String? = null,
|
||||||
var dateModified: Date? = null,
|
var dateModified: Date? = null,
|
||||||
var hasInvalidLocation : Int = 0,
|
var hasInvalidLocation : Int = 0,
|
||||||
var contentUri: Uri? = null,
|
var contentUri: Uri? = null,
|
||||||
|
|
@ -70,6 +71,7 @@ data class Contribution constructor(
|
||||||
depictedItems = depictedItems,
|
depictedItems = depictedItems,
|
||||||
wikidataPlace = from(item.place),
|
wikidataPlace = from(item.place),
|
||||||
contentUri = item.contentUri,
|
contentUri = item.contentUri,
|
||||||
|
dateCreatedString = item.fileCreatedDateString,
|
||||||
imageSHA1 = imageSHA1
|
imageSHA1 = imageSHA1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class ContributionBoundaryCallback @Inject constructor(
|
||||||
@param:Named(CommonsApplicationModule.IO_THREAD) private val ioThreadScheduler: Scheduler
|
@param:Named(CommonsApplicationModule.IO_THREAD) private val ioThreadScheduler: Scheduler
|
||||||
) : BoundaryCallback<Contribution>() {
|
) : BoundaryCallback<Contribution>() {
|
||||||
private val compositeDisposable: CompositeDisposable = CompositeDisposable()
|
private val compositeDisposable: CompositeDisposable = CompositeDisposable()
|
||||||
lateinit var userName: String
|
var userName: String? = null
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -53,13 +53,13 @@ class ContributionBoundaryCallback @Inject constructor(
|
||||||
/**
|
/**
|
||||||
* Fetches contributions using the MediaWiki API
|
* Fetches contributions using the MediaWiki API
|
||||||
*/
|
*/
|
||||||
fun fetchContributions() {
|
private fun fetchContributions() {
|
||||||
if (sessionManager.userName != null) {
|
if (sessionManager.userName != null) {
|
||||||
compositeDisposable.add(
|
userName?.let { userName ->
|
||||||
mediaClient.getMediaListForUser(userName!!)
|
mediaClient.getMediaListForUser(userName)
|
||||||
.map { mediaList ->
|
.map { mediaList ->
|
||||||
mediaList.map {
|
mediaList.map { media ->
|
||||||
Contribution(media = it, state = Contribution.STATE_COMPLETED)
|
Contribution(media = media, state = Contribution.STATE_COMPLETED)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.subscribeOn(ioThreadScheduler)
|
.subscribeOn(ioThreadScheduler)
|
||||||
|
|
@ -69,11 +69,13 @@ class ContributionBoundaryCallback @Inject constructor(
|
||||||
error.message
|
error.message
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
}?.let {
|
||||||
}else {
|
compositeDisposable.add(
|
||||||
if (compositeDisposable != null){
|
it
|
||||||
compositeDisposable.clear()
|
)
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
|
compositeDisposable.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -661,7 +661,7 @@ public class ContributionsFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean backButtonClicked() {
|
public boolean backButtonClicked() {
|
||||||
if (null != mediaDetailPagerFragment && mediaDetailPagerFragment.isVisible()) {
|
if (mediaDetailPagerFragment != null && mediaDetailPagerFragment.isVisible()) {
|
||||||
if (store.getBoolean("displayNearbyCardView", true) && !isUserProfile) {
|
if (store.getBoolean("displayNearbyCardView", true) && !isUserProfile) {
|
||||||
if (nearbyNotificationCardView.cardViewVisibilityState == NearbyNotificationCardView.CardViewVisibilityState.READY) {
|
if (nearbyNotificationCardView.cardViewVisibilityState == NearbyNotificationCardView.CardViewVisibilityState.READY) {
|
||||||
nearbyNotificationCardView.setVisibility(View.VISIBLE);
|
nearbyNotificationCardView.setVisibility(View.VISIBLE);
|
||||||
|
|
@ -678,9 +678,10 @@ public class ContributionsFragment
|
||||||
}else {
|
}else {
|
||||||
fetchCampaigns();
|
fetchCampaigns();
|
||||||
}
|
}
|
||||||
if(getActivity() instanceof MainActivity) {
|
if (getActivity() instanceof MainActivity) {
|
||||||
// Fragment is associated with MainActivity
|
// Fragment is associated with MainActivity
|
||||||
((MainActivity)getActivity()).showTabs();
|
((BaseActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
||||||
|
((MainActivity) getActivity()).showTabs();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,7 @@ import android.content.Context;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteException;
|
import android.database.sqlite.SQLiteException;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
|
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao;
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao;
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table;
|
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
||||||
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao;
|
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao;
|
||||||
import fr.free.nrw.commons.category.CategoryDao;
|
import fr.free.nrw.commons.category.CategoryDao;
|
||||||
|
|
@ -16,7 +14,7 @@ import fr.free.nrw.commons.recentlanguages.RecentLanguagesDao;
|
||||||
public class DBOpenHelper extends SQLiteOpenHelper {
|
public class DBOpenHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
private static final String DATABASE_NAME = "commons.db";
|
private static final String DATABASE_NAME = "commons.db";
|
||||||
private static final int DATABASE_VERSION = 19;
|
private static final int DATABASE_VERSION = 20;
|
||||||
public static final String CONTRIBUTIONS_TABLE = "contributions";
|
public static final String CONTRIBUTIONS_TABLE = "contributions";
|
||||||
private final String DROP_TABLE_STATEMENT="DROP TABLE IF EXISTS %s";
|
private final String DROP_TABLE_STATEMENT="DROP TABLE IF EXISTS %s";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import fr.free.nrw.commons.upload.depicts.DepictsDao
|
||||||
* The database for accessing the respective DAOs
|
* The database for accessing the respective DAOs
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Database(entities = [Contribution::class, Depicts::class, UploadedStatus::class], version = 12, exportSchema = false)
|
@Database(entities = [Contribution::class, Depicts::class, UploadedStatus::class], version = 13, exportSchema = false)
|
||||||
@TypeConverters(Converters::class)
|
@TypeConverters(Converters::class)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
abstract fun contributionDao(): ContributionDao
|
abstract fun contributionDao(): ContributionDao
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,7 @@ class DescriptionEditActivity : BaseActivity(), UploadMediaDetailAdapter.EventLi
|
||||||
buffer.append("}}, ")
|
buffer.append("}}, ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffer.deleteCharAt(buffer.length - 1)
|
buffer.replace(", $".toRegex(), "")
|
||||||
buffer.deleteCharAt(buffer.length - 1)
|
|
||||||
buffer.append(descriptionEnd)
|
buffer.append(descriptionEnd)
|
||||||
}
|
}
|
||||||
val returningIntent = Intent()
|
val returningIntent = Intent()
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ import androidx.exifinterface.media.ExifInterface;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import fr.free.nrw.commons.upload.FileUtils;
|
import fr.free.nrw.commons.upload.FileUtils;
|
||||||
|
|
@ -124,13 +126,30 @@ public class UploadableFile implements Parcelable {
|
||||||
private DateTimeWithSource getDateTimeFromExif() {
|
private DateTimeWithSource getDateTimeFromExif() {
|
||||||
try {
|
try {
|
||||||
ExifInterface exif = new ExifInterface(file.getAbsolutePath());
|
ExifInterface exif = new ExifInterface(file.getAbsolutePath());
|
||||||
@SuppressLint("RestrictedApi") Long dateTime = exif.getDateTime();
|
// TAG_DATETIME returns the last edited date, we need TAG_DATETIME_ORIGINAL for creation date
|
||||||
if(dateTime != null){
|
// See issue https://github.com/commons-app/apps-android-commons/issues/1971
|
||||||
Date date = new Date(dateTime);
|
String dateTimeSubString = exif.getAttribute(ExifInterface.TAG_DATETIME_ORIGINAL);
|
||||||
return new DateTimeWithSource(date, DateTimeWithSource.EXIF_SOURCE);
|
if (dateTimeSubString!=null) { //getAttribute may return null
|
||||||
|
String year = dateTimeSubString.substring(0,4);
|
||||||
|
String month = dateTimeSubString.substring(5,7);
|
||||||
|
String day = dateTimeSubString.substring(8,10);
|
||||||
|
// This date is stored as a string (not as a date), the rason is we don't want to include timezones
|
||||||
|
String dateCreatedString = String.format("%04d-%02d-%02d", Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day));
|
||||||
|
if (dateCreatedString.length() == 10) { //yyyy-MM-dd format of date is expected
|
||||||
|
@SuppressLint("RestrictedApi") Long dateTime = exif.getDateTimeOriginal();
|
||||||
|
if(dateTime != null){
|
||||||
|
Date date = new Date(dateTime);
|
||||||
|
return new DateTimeWithSource(date, dateCreatedString, DateTimeWithSource.EXIF_SOURCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -149,6 +168,7 @@ public class UploadableFile implements Parcelable {
|
||||||
public static final String EXIF_SOURCE = "exif";
|
public static final String EXIF_SOURCE = "exif";
|
||||||
|
|
||||||
private final long epochDate;
|
private final long epochDate;
|
||||||
|
private String dateString; // this does not includes timezone information
|
||||||
private final String source;
|
private final String source;
|
||||||
|
|
||||||
public DateTimeWithSource(long epochDate, String source) {
|
public DateTimeWithSource(long epochDate, String source) {
|
||||||
|
|
@ -161,10 +181,20 @@ public class UploadableFile implements Parcelable {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DateTimeWithSource(Date date, String dateString, String source) {
|
||||||
|
this.epochDate = date.getTime();
|
||||||
|
this.dateString = dateString;
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
public long getEpochDate() {
|
public long getEpochDate() {
|
||||||
return epochDate;
|
return epochDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDateString() {
|
||||||
|
return dateString;
|
||||||
|
}
|
||||||
|
|
||||||
public String getSource() {
|
public String getSource() {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package fr.free.nrw.commons.media;
|
||||||
import static fr.free.nrw.commons.Utils.handleWebUrl;
|
import static fr.free.nrw.commons.Utils.handleWebUrl;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
@ -12,7 +13,9 @@ import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Toast;
|
||||||
import androidx.appcompat.app.ActionBar;
|
import androidx.appcompat.app.ActionBar;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
@ -22,6 +25,7 @@ import androidx.viewpager.widget.ViewPager;
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
import fr.free.nrw.commons.CommonsApplication;
|
||||||
import fr.free.nrw.commons.Media;
|
import fr.free.nrw.commons.Media;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.auth.SessionManager;
|
import fr.free.nrw.commons.auth.SessionManager;
|
||||||
|
|
@ -33,7 +37,6 @@ import fr.free.nrw.commons.contributions.MainActivity;
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||||
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
|
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
|
||||||
import fr.free.nrw.commons.profile.ProfileActivity;
|
import fr.free.nrw.commons.profile.ProfileActivity;
|
||||||
import fr.free.nrw.commons.theme.BaseActivity;
|
|
||||||
import fr.free.nrw.commons.utils.DownloadUtils;
|
import fr.free.nrw.commons.utils.DownloadUtils;
|
||||||
import fr.free.nrw.commons.utils.ImageUtils;
|
import fr.free.nrw.commons.utils.ImageUtils;
|
||||||
import fr.free.nrw.commons.utils.NetworkUtils;
|
import fr.free.nrw.commons.utils.NetworkUtils;
|
||||||
|
|
@ -211,11 +214,83 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
|
||||||
ProfileActivity.startYourself(getActivity(), m.getUser(),
|
ProfileActivity.startYourself(getActivity(), m.getUser(),
|
||||||
!Objects.equals(sessionManager.getUserName(), m.getUser()));
|
!Objects.equals(sessionManager.getUserName(), m.getUser()));
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
case R.id.menu_view_report:
|
||||||
|
showReportDialog(m);
|
||||||
default:
|
default:
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showReportDialog(final Media media) {
|
||||||
|
if (media == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
|
||||||
|
final String[] values = requireContext().getResources()
|
||||||
|
.getStringArray(R.array.report_violation_options);
|
||||||
|
builder.setTitle(R.string.report_violation);
|
||||||
|
builder.setItems(R.array.report_violation_options, (dialog, which) -> {
|
||||||
|
sendReportEmail(media, values[which]);
|
||||||
|
});
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendReportEmail(final Media media, final String type) {
|
||||||
|
final String technicalInfo = getTechInfo(media, type);
|
||||||
|
|
||||||
|
final Intent feedbackIntent = new Intent(Intent.ACTION_SENDTO);
|
||||||
|
feedbackIntent.setType("message/rfc822");
|
||||||
|
feedbackIntent.setData(Uri.parse("mailto:"));
|
||||||
|
feedbackIntent.putExtra(Intent.EXTRA_EMAIL,
|
||||||
|
new String[]{CommonsApplication.REPORT_EMAIL});
|
||||||
|
feedbackIntent.putExtra(Intent.EXTRA_SUBJECT,
|
||||||
|
CommonsApplication.REPORT_EMAIL_SUBJECT);
|
||||||
|
feedbackIntent.putExtra(Intent.EXTRA_TEXT, technicalInfo);
|
||||||
|
try {
|
||||||
|
startActivity(feedbackIntent);
|
||||||
|
} catch (final ActivityNotFoundException e) {
|
||||||
|
Toast.makeText(getActivity(), R.string.no_email_client, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTechInfo(final Media media, final String type) {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
builder.append("Report type: ")
|
||||||
|
.append(type)
|
||||||
|
.append("\n\n");
|
||||||
|
|
||||||
|
builder.append("Image that you want to report: ")
|
||||||
|
.append(media.getImageUrl())
|
||||||
|
.append("\n\n");
|
||||||
|
|
||||||
|
builder.append("User that you want to report: ")
|
||||||
|
.append(media.getAuthor())
|
||||||
|
.append("\n\n");
|
||||||
|
|
||||||
|
if (sessionManager.getUserName() != null) {
|
||||||
|
builder.append("Your username: ")
|
||||||
|
.append(sessionManager.getUserName())
|
||||||
|
.append("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append("Violation reason: ")
|
||||||
|
.append("\n");
|
||||||
|
|
||||||
|
builder.append("----------------------------------------------")
|
||||||
|
.append("\n")
|
||||||
|
.append("(please write reason here)")
|
||||||
|
.append("\n")
|
||||||
|
.append("----------------------------------------------")
|
||||||
|
.append("\n\n")
|
||||||
|
.append("Thank you for your report! Our team will investigate as soon as possible.")
|
||||||
|
.append("\n")
|
||||||
|
.append("Please note that images also have a `Nominate for deletion` button.");
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the media as the device's wallpaper if the imageUrl is not null
|
* Set the media as the device's wallpaper if the imageUrl is not null
|
||||||
* Fails silently if setting the wallpaper fails
|
* Fails silently if setting the wallpaper fails
|
||||||
|
|
|
||||||
|
|
@ -185,23 +185,17 @@ public class RecentLanguagesDao {
|
||||||
if (from == to) {
|
if (from == to) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (from < 6) {
|
if (from < 19) {
|
||||||
// doesn't exist yet
|
// doesn't exist yet
|
||||||
from++;
|
from++;
|
||||||
onUpdate(db, from, to);
|
onUpdate(db, from, to);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (from == 6) {
|
if (from == 19) {
|
||||||
// table added in version 7
|
// table added in version 20
|
||||||
onCreate(db);
|
onCreate(db);
|
||||||
from++;
|
from++;
|
||||||
onUpdate(db, from, to);
|
onUpdate(db, from, to);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (from == 7) {
|
|
||||||
from++;
|
|
||||||
onUpdate(db, from, to);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ class PageContentsCreator {
|
||||||
.append(media.getAuthor()).append("]]\n");
|
.append(media.getAuthor()).append("]]\n");
|
||||||
|
|
||||||
final String templatizedCreatedDate = getTemplatizedCreatedDate(
|
final String templatizedCreatedDate = getTemplatizedCreatedDate(
|
||||||
contribution.getDateCreated(), contribution.getDateCreatedSource());
|
contribution.getDateCreatedString(), contribution.getDateCreated(), contribution.getDateCreatedSource());
|
||||||
if (!StringUtils.isBlank(templatizedCreatedDate)) {
|
if (!StringUtils.isBlank(templatizedCreatedDate)) {
|
||||||
buffer.append("|date=").append(templatizedCreatedDate);
|
buffer.append("|date=").append(templatizedCreatedDate);
|
||||||
}
|
}
|
||||||
|
|
@ -90,12 +90,12 @@ class PageContentsCreator {
|
||||||
* @param dateCreatedSource
|
* @param dateCreatedSource
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String getTemplatizedCreatedDate(Date dateCreated, String dateCreatedSource) {
|
private String getTemplatizedCreatedDate(String dateCreatedString, Date dateCreated, String dateCreatedSource) {
|
||||||
if (dateCreated != null) {
|
if (dateCreated != null) {
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
return String.format(Locale.ENGLISH,
|
return String.format(Locale.ENGLISH,
|
||||||
isExif(dateCreatedSource) ? TEMPLATE_DATE_ACC_TO_EXIF : TEMPLATE_DATA_OTHER_SOURCE,
|
isExif(dateCreatedSource) ? TEMPLATE_DATE_ACC_TO_EXIF : TEMPLATE_DATA_OTHER_SOURCE,
|
||||||
dateFormat.format(dateCreated)
|
isExif(dateCreatedSource) ? dateCreatedString: dateFormat.format(dateCreated)
|
||||||
) + "\n";
|
) + "\n";
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ public class UploadItem {
|
||||||
private boolean hasInvalidLocation;
|
private boolean hasInvalidLocation;
|
||||||
private boolean isWLMUpload = false;
|
private boolean isWLMUpload = false;
|
||||||
private String countryCode;
|
private String countryCode;
|
||||||
|
private String fileCreatedDateString; //according to EXIF data
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uri of uploadItem
|
* Uri of uploadItem
|
||||||
|
|
@ -40,7 +41,8 @@ public class UploadItem {
|
||||||
final Place place,
|
final Place place,
|
||||||
final long createdTimestamp,
|
final long createdTimestamp,
|
||||||
final String createdTimestampSource,
|
final String createdTimestampSource,
|
||||||
final Uri contentUri) {
|
final Uri contentUri,
|
||||||
|
final String fileCreatedDateString) {
|
||||||
this.createdTimestampSource = createdTimestampSource;
|
this.createdTimestampSource = createdTimestampSource;
|
||||||
uploadMediaDetails = new ArrayList<>(Collections.singletonList(new UploadMediaDetail()));
|
uploadMediaDetails = new ArrayList<>(Collections.singletonList(new UploadMediaDetail()));
|
||||||
this.place = place;
|
this.place = place;
|
||||||
|
|
@ -50,6 +52,7 @@ public class UploadItem {
|
||||||
this.createdTimestamp = createdTimestamp;
|
this.createdTimestamp = createdTimestamp;
|
||||||
this.contentUri = contentUri;
|
this.contentUri = contentUri;
|
||||||
imageQuality = BehaviorSubject.createDefault(ImageUtils.IMAGE_WAIT);
|
imageQuality = BehaviorSubject.createDefault(ImageUtils.IMAGE_WAIT);
|
||||||
|
this.fileCreatedDateString = fileCreatedDateString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCreatedTimestampSource() {
|
public String getCreatedTimestampSource() {
|
||||||
|
|
@ -83,6 +86,8 @@ public class UploadItem {
|
||||||
*/
|
*/
|
||||||
public Uri getContentUri() { return contentUri; }
|
public Uri getContentUri() { return contentUri; }
|
||||||
|
|
||||||
|
public String getFileCreatedDateString() { return fileCreatedDateString; }
|
||||||
|
|
||||||
public void setImageQuality(final int imageQuality) {
|
public void setImageQuality(final int imageQuality) {
|
||||||
this.imageQuality.onNext(imageQuality);
|
this.imageQuality.onNext(imageQuality);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,8 +102,10 @@ public class UploadModel {
|
||||||
.getFileCreatedDate(context);
|
.getFileCreatedDate(context);
|
||||||
long fileCreatedDate = -1;
|
long fileCreatedDate = -1;
|
||||||
String createdTimestampSource = "";
|
String createdTimestampSource = "";
|
||||||
|
String fileCreatedDateString = "";
|
||||||
if (dateTimeWithSource != null) {
|
if (dateTimeWithSource != null) {
|
||||||
fileCreatedDate = dateTimeWithSource.getEpochDate();
|
fileCreatedDate = dateTimeWithSource.getEpochDate();
|
||||||
|
fileCreatedDateString = dateTimeWithSource.getDateString();
|
||||||
createdTimestampSource = dateTimeWithSource.getSource();
|
createdTimestampSource = dateTimeWithSource.getSource();
|
||||||
}
|
}
|
||||||
Timber.d("File created date is %d", fileCreatedDate);
|
Timber.d("File created date is %d", fileCreatedDate);
|
||||||
|
|
@ -113,7 +115,8 @@ public class UploadModel {
|
||||||
Uri.parse(uploadableFile.getFilePath()),
|
Uri.parse(uploadableFile.getFilePath()),
|
||||||
uploadableFile.getMimeType(context), imageCoordinates, place, fileCreatedDate,
|
uploadableFile.getMimeType(context), imageCoordinates, place, fileCreatedDate,
|
||||||
createdTimestampSource,
|
createdTimestampSource,
|
||||||
uploadableFile.getContentUri());
|
uploadableFile.getContentUri(),
|
||||||
|
fileCreatedDateString);
|
||||||
if (place != null) {
|
if (place != null) {
|
||||||
uploadItem.getUploadMediaDetails().set(0, new UploadMediaDetail(place));
|
uploadItem.getUploadMediaDetails().set(0, new UploadMediaDetail(place));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,18 +148,16 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
init();
|
if (callback != null) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
tvTitle.setText(getString(R.string.step_count, callback.getIndexInViewFlipper(this) + 1,
|
tvTitle.setText(getString(R.string.step_count, callback.getIndexInViewFlipper(this) + 1,
|
||||||
callback.getTotalNumberOfSteps(), getString(R.string.media_detail_step_title)));
|
callback.getTotalNumberOfSteps(), getString(R.string.media_detail_step_title)));
|
||||||
tooltip.setOnClickListener(new OnClickListener() {
|
tooltip.setOnClickListener(
|
||||||
@Override
|
v -> showInfoAlert(R.string.media_detail_step_title, R.string.media_details_tooltip));
|
||||||
public void onClick(View v) {
|
|
||||||
showInfoAlert(R.string.media_detail_step_title, R.string.media_details_tooltip);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
initPresenter();
|
initPresenter();
|
||||||
presenter.receiveImage(uploadableFile, place);
|
presenter.receiveImage(uploadableFile, place);
|
||||||
initRecyclerView();
|
initRecyclerView();
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,8 @@ public class NetworkUtils {
|
||||||
return NetworkConnectionType.WIFI;
|
return NetworkConnectionType.WIFI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO for Android 12+ request permission from user is mandatory
|
||||||
|
/*
|
||||||
int mobileNetwork = telephonyManager.getNetworkType();
|
int mobileNetwork = telephonyManager.getNetworkType();
|
||||||
switch (mobileNetwork) {
|
switch (mobileNetwork) {
|
||||||
case TelephonyManager.NETWORK_TYPE_GPRS:
|
case TelephonyManager.NETWORK_TYPE_GPRS:
|
||||||
|
|
@ -71,6 +73,8 @@ public class NetworkUtils {
|
||||||
default:
|
default:
|
||||||
return NetworkConnectionType.UNKNOWN;
|
return NetworkConnectionType.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
return NetworkConnectionType.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -34,5 +34,9 @@
|
||||||
android:id="@+id/menu_view_user_page"
|
android:id="@+id/menu_view_user_page"
|
||||||
android:title="@string/menu_view_user_page"
|
android:title="@string/menu_view_user_page"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_view_report"
|
||||||
|
android:title="@string/menu_view_report"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
|
@ -70,5 +70,10 @@
|
||||||
<item>yearly</item>
|
<item>yearly</item>
|
||||||
<item>all_time</item>
|
<item>all_time</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
<string-array name="report_violation_options" >
|
||||||
|
<item>@string/report_user</item>
|
||||||
|
<item>@string/report_content</item>
|
||||||
|
<item>@string/request_user_block</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -691,7 +691,7 @@ Upload your first media by tapping on the add button.</string>
|
||||||
<string name="done">Done</string>
|
<string name="done">Done</string>
|
||||||
<string name="back">Back</string>
|
<string name="back">Back</string>
|
||||||
<string name="welcome_custom_picture_selector_text">Welcome to Custom Picture Selector</string>
|
<string name="welcome_custom_picture_selector_text">Welcome to Custom Picture Selector</string>
|
||||||
<string name="custom_selector_info_text1">This picker shows differently pictures that are already to Commons.</string>
|
<string name="custom_selector_info_text1">This picker shows you which pictures you have already uploaded to Commons.</string>
|
||||||
<string name="custom_selector_info_text2">Unlike the picture on the left, the picture on the right has the Commons logo indicating it is already uploaded. \n Touch and hold for image preview.</string>
|
<string name="custom_selector_info_text2">Unlike the picture on the left, the picture on the right has the Commons logo indicating it is already uploaded. \n Touch and hold for image preview.</string>
|
||||||
<string name="welcome_custom_selector_ok">Awesome</string>
|
<string name="welcome_custom_selector_ok">Awesome</string>
|
||||||
<string name="custom_selector_already_uploaded_image_text">This image has already been uploaded to Commons.</string>
|
<string name="custom_selector_already_uploaded_image_text">This image has already been uploaded to Commons.</string>
|
||||||
|
|
@ -734,4 +734,9 @@ Upload your first media by tapping on the add button.</string>
|
||||||
<string name="error_feedback">Error while sending feedback</string>
|
<string name="error_feedback">Error while sending feedback</string>
|
||||||
<string name="enter_description">What is your feedback?</string>
|
<string name="enter_description">What is your feedback?</string>
|
||||||
<string name="your_feedback">Your feedback</string>
|
<string name="your_feedback">Your feedback</string>
|
||||||
|
<string name="menu_view_report">Report</string>
|
||||||
|
<string name="report_violation">Report violation</string>
|
||||||
|
<string name="report_user">Report this user</string>
|
||||||
|
<string name="report_content">Report this content</string>
|
||||||
|
<string name="request_user_block">Request to block this user</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -271,9 +271,84 @@ class BookmarkItemsDaoTest {
|
||||||
@Test
|
@Test
|
||||||
fun migrateTableVersionFrom_v7_to_v8() {
|
fun migrateTableVersionFrom_v7_to_v8() {
|
||||||
onUpdate(database, 7, 8)
|
onUpdate(database, 7, 8)
|
||||||
|
// Table didn't change in version 8
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v8_to_v9() {
|
||||||
|
onUpdate(database, 8, 9)
|
||||||
|
// Table didn't change in version 9
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v9_to_v10() {
|
||||||
|
onUpdate(database, 9, 10)
|
||||||
|
// Table didn't change in version 10
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v10_to_v11() {
|
||||||
|
onUpdate(database, 10, 11)
|
||||||
|
// Table didn't change in version 11
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v11_to_v12() {
|
||||||
|
onUpdate(database, 11, 12)
|
||||||
|
// Table didn't change in version 12
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v12_to_v13() {
|
||||||
|
onUpdate(database, 12, 13)
|
||||||
|
// Table didn't change in version 13
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v13_to_v14() {
|
||||||
|
onUpdate(database, 13, 14)
|
||||||
|
// Table didn't change in version 14
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v14_to_v15() {
|
||||||
|
onUpdate(database, 14, 15)
|
||||||
|
// Table didn't change in version 15
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v15_to_v16() {
|
||||||
|
onUpdate(database, 15, 16)
|
||||||
|
// Table didn't change in version 16
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v16_to_v17() {
|
||||||
|
onUpdate(database, 16, 17)
|
||||||
|
// Table didn't change in version 17
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v18_to_v19() {
|
||||||
|
onUpdate(database, 18, 19)
|
||||||
verify(database).execSQL(CREATE_TABLE_STATEMENT)
|
verify(database).execSQL(CREATE_TABLE_STATEMENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v19_to_v19() {
|
||||||
|
onUpdate(database, 19, 19)
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
private fun createCursor(rowCount: Int) = MatrixCursor(columns, rowCount).apply {
|
private fun createCursor(rowCount: Int) = MatrixCursor(columns, rowCount).apply {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import org.mockito.ArgumentMatchers.anyString
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.mock
|
import org.mockito.Mockito.mock
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
|
import java.lang.reflect.Method
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The unit test class for ContributionBoundaryCallbackTest
|
* The unit test class for ContributionBoundaryCallbackTest
|
||||||
|
|
@ -95,7 +96,11 @@ class ContributionBoundaryCallbackTest {
|
||||||
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(
|
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(
|
||||||
Single.just(listOf(media()))
|
Single.just(listOf(media()))
|
||||||
)
|
)
|
||||||
contributionBoundaryCallback.fetchContributions()
|
val method: Method = ContributionBoundaryCallback::class.java.getDeclaredMethod(
|
||||||
|
"fetchContributions"
|
||||||
|
)
|
||||||
|
method.isAccessible = true
|
||||||
|
method.invoke(contributionBoundaryCallback)
|
||||||
verify(repository).save(anyList());
|
verify(repository).save(anyList());
|
||||||
verify(mediaClient).getMediaListForUser(anyString());
|
verify(mediaClient).getMediaListForUser(anyString());
|
||||||
}
|
}
|
||||||
|
|
@ -104,7 +109,11 @@ class ContributionBoundaryCallbackTest {
|
||||||
fun testFetchContributionsFailed() {
|
fun testFetchContributionsFailed() {
|
||||||
whenever(sessionManager.userName).thenReturn("Test")
|
whenever(sessionManager.userName).thenReturn("Test")
|
||||||
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(Single.error(Exception("Error")))
|
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(Single.error(Exception("Error")))
|
||||||
contributionBoundaryCallback.fetchContributions()
|
val method: Method = ContributionBoundaryCallback::class.java.getDeclaredMethod(
|
||||||
|
"fetchContributions"
|
||||||
|
)
|
||||||
|
method.isAccessible = true
|
||||||
|
method.invoke(contributionBoundaryCallback)
|
||||||
verifyZeroInteractions(repository);
|
verifyZeroInteractions(repository);
|
||||||
verify(mediaClient).getMediaListForUser(anyString());
|
verify(mediaClient).getMediaListForUser(anyString());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -177,20 +177,103 @@ class RecentLanguagesDaoUnitTest {
|
||||||
@Test
|
@Test
|
||||||
fun migrateTableVersionFrom_v5_to_v6() {
|
fun migrateTableVersionFrom_v5_to_v6() {
|
||||||
onUpdate(database, 5, 6)
|
onUpdate(database, 5, 6)
|
||||||
// Table didnt exist before v7
|
// Table didnt exist in version 6
|
||||||
verifyZeroInteractions(database)
|
verifyZeroInteractions(database)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun migrateTableVersionFrom_v6_to_v7() {
|
fun migrateTableVersionFrom_v6_to_v7() {
|
||||||
onUpdate(database, 6, 7)
|
onUpdate(database, 6, 7)
|
||||||
verify(database).execSQL(CREATE_TABLE_STATEMENT)
|
// Table didnt exist in version 7
|
||||||
|
verifyZeroInteractions(database)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun migrateTableVersionFrom_v7_to_v8() {
|
fun migrateTableVersionFrom_v7_to_v8() {
|
||||||
onUpdate(database, 7, 8)
|
onUpdate(database, 7, 8)
|
||||||
// Table didnt change in version 8
|
// Table didnt exist in version 8
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v8_to_v9() {
|
||||||
|
onUpdate(database, 8, 9)
|
||||||
|
// Table didnt exist in version 9
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v9_to_v10() {
|
||||||
|
onUpdate(database, 9, 10)
|
||||||
|
// Table didnt exist in version 10
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v10_to_v11() {
|
||||||
|
onUpdate(database, 10, 11)
|
||||||
|
// Table didnt exist in version 11
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v11_to_v12() {
|
||||||
|
onUpdate(database, 11, 12)
|
||||||
|
// Table didnt exist in version 12
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v12_to_v13() {
|
||||||
|
onUpdate(database, 12, 13)
|
||||||
|
// Table didnt exist in version 13
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v13_to_v14() {
|
||||||
|
onUpdate(database, 13, 14)
|
||||||
|
// Table didnt exist in version 14
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v14_to_v15() {
|
||||||
|
onUpdate(database, 14, 15)
|
||||||
|
// Table didnt exist in version 15
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v15_to_v16() {
|
||||||
|
onUpdate(database, 15, 16)
|
||||||
|
// Table didnt exist in version 16
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v16_to_v17() {
|
||||||
|
onUpdate(database, 16, 17)
|
||||||
|
// Table didnt exist in version 17
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v18_to_v19() {
|
||||||
|
onUpdate(database, 18, 19)
|
||||||
|
// Table didnt exist in version 18
|
||||||
|
verifyZeroInteractions(database)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v19_to_v20() {
|
||||||
|
onUpdate(database, 19, 20)
|
||||||
|
verify(database).execSQL(CREATE_TABLE_STATEMENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun migrateTableVersionFrom_v20_to_v20() {
|
||||||
|
onUpdate(database, 20, 20)
|
||||||
verifyZeroInteractions(database)
|
verifyZeroInteractions(database)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import fr.free.nrw.commons.utils.model.NetworkConnectionType;
|
import fr.free.nrw.commons.utils.model.NetworkConnectionType;
|
||||||
|
|
@ -97,6 +98,7 @@ public class NetworkUtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore("Fix these test with telemetry permission")
|
||||||
public void testCellular2GNetwork() {
|
public void testCellular2GNetwork() {
|
||||||
Context mockContext = mock(Context.class);
|
Context mockContext = mock(Context.class);
|
||||||
Application mockApplication = mock(Application.class);
|
Application mockApplication = mock(Application.class);
|
||||||
|
|
@ -123,6 +125,7 @@ public class NetworkUtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore("Fix these test with telemetry permission")
|
||||||
public void testCellular3GNetwork() {
|
public void testCellular3GNetwork() {
|
||||||
Context mockContext = mock(Context.class);
|
Context mockContext = mock(Context.class);
|
||||||
Application mockApplication = mock(Application.class);
|
Application mockApplication = mock(Application.class);
|
||||||
|
|
@ -149,6 +152,7 @@ public class NetworkUtilsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore("Fix these test with telemetry permission")
|
||||||
public void testCellular4GNetwork() {
|
public void testCellular4GNetwork() {
|
||||||
Context mockContext = mock(Context.class);
|
Context mockContext = mock(Context.class);
|
||||||
Application mockApplication = mock(Application.class);
|
Application mockApplication = mock(Application.class);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue