mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Sync master with release (#3922)
* #3624 DateTimeFormat wrong - match pattern returned from servers (#3625)
* Revert "Fixes: #3179 Make category search non case-sensitive (#3326)" (#3636)
Simply lower casing the name of the category sent to the server
doesn't result in the server doing a case insensitive category
search. In fact, it reduces the category search space as only
categories that has a lower case character is searched even
if the search text contains upper case characters.
The test case did not catch this issue as the first character
of the title is case insensitive[1].
So, revert the changes done in commit afdeaae075.
See further disucssion in the issue thread of #3179 starting
from [2].
[1]: https://www.mediawiki.org/wiki/Manual:Page_title
[2]: https://github.com/commons-app/apps-android-commons/issues/3179#issuecomment-605462140
* Bugfix/security exception (#3627)
* Fixes #3626
* Check is file is actually created before writing to file, file picker android
* Handle Security exception
* Fixes #3436 and #2881: Media Detail design Overhaul (#3505)
* ic_map_dark_24dp: map icon for white background
* ic_info_outline_dark_24dp: info icon for dark background
* MediaDetailFragment: update the spacer as per image aspect ratio
* fragment_media_detail: design overhaul
* fragment_media_detail: remove redundant background color statements
* make requested changes
* add dark mode support
* minor ui tweak
* white map icon in dark mode
* make rquested changes
* make requested changes to layout
* fix misalignment of category list
* subtle amendments
* convert comments to javadocs
* minor amendments
* minor changes
* add styles for media detail
* Media detail fragment refactored
* make suggested changes
* minor name fix
* fix the delete button border
* Fixes #3639 (Fix Save State implementation of CheckBoxTriState ) (#3686)
* Add #3723 and #3721 to 2.13 release, fix conflicts
Conflicts were caused by merging #3723 before #3721 , so I just rolled both into one commit.
* Fix NullPointer when clicking on image in MediaDetailFragment (#3730)… (#3739)
* Update changelog.md
* Versioning for v2.13
* Fixes #3705 (Crash when viewing pic I just uploaded) (#3782)
* Fixes #3705
* Let the MediaDetailPager fragment know when the contributions have been updated
* Handle NPE, null check on adapter in MediaDetailPagerFragment
* Fixed BookmarkLocationsDao DB migration (#3793)
* Fixes #3725 (#3795)
* Downgraded okhttp version to support Api 19 devices
* Handled null CompoundDrawable[2] in etTitle-> UploadMediaDetailsFragment (#3828)
* DownSample Upload image to be shown in UploadMediaDetailFragment to handle OOM, Bitmap Too large exception (#3830)
* Fixes #3829
* DownSample Upload image to be shown in UploadMediaDetailFragment to handle OOM, Bitmap Too large exception
* removed unused imports, handled possible exceptions
* Let Fresco handle the downsampling of image
* invalidate in onTransformEnd
* Expose an interface TransformationListener in ZoomableDraweeView to listen to transformation change end
* removed photoView dependency
* removed unused imports in ZoomableActivity
* Bugfix, expand/collapse
* changed functio name
* Bugfix/p18 uploads (#3869)
* updated gradle plugin version
* BugFix #3856
* Do not use preference for deciding acceptable lat long for nearby uploads, instead save the corresponding location in the Contribution via UploadItem
* Marshall contribution's hasInvalidLocation
* reset un-related changes
* Fixed test cases
* Minor code formatting and docs
* Fixes #3882 (#3883)
* Make hasInvalidLocation non-null integer with default value 0
Co-authored-by: Ashish Kumar <ashish@Ashishs-MacBook-Air.local>
* Fixes #3766, Added OPENSTREET attribution (#3889)
* Fixes #3766
* Added OPENSTREET attribution in nearby
* Added custom text attribution in Nearby
* Deleted unused class CustomBorderTextView
* review suggested changes
* modified telemetry summary string
* Versioning and changelog for v2.13.1 (#3908)
* Update changelog.md
* Versioning for v2.13.1
* Fixes #3914 (#3915)
* Verify user login before setting upload count
* fixed compile-time error
* fix erros
* delete emptied files
* remove empty file CategoriesModel.java
Co-authored-by: Seán Mac Gillicuddy <seantheappdev@gmail.com>
Co-authored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
Co-authored-by: Kshitij Bhardwaj <44129798+kbhardwaj123@users.noreply.github.com>
Co-authored-by: Vitaly V. Pinchuk <vetal.978@gmail.com>
Co-authored-by: Josephine Lim <josephinelim86@gmail.com>
Co-authored-by: Ashish Kumar <ashish@Ashishs-MacBook-Air.local>
This commit is contained in:
parent
abdd16c063
commit
ddd3e1212a
31 changed files with 604 additions and 512 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -1,5 +1,17 @@
|
||||||
# Wikimedia Commons for Android
|
# Wikimedia Commons for Android
|
||||||
|
|
||||||
|
## v2.13.1
|
||||||
|
- Added OpenStreetMap attribution
|
||||||
|
- Fixed various crashes
|
||||||
|
- Fixed SQLite error in Nearby map
|
||||||
|
- Fixed issue with Nearby uploads not being associated with Wikidata p18
|
||||||
|
|
||||||
|
## v2.13.0
|
||||||
|
- New media details UI, ability to zoom and pan around image
|
||||||
|
- Added suggestions for a place that needs photos if user uploads a photo that is near one of them
|
||||||
|
- Modifications and fixes to Nearby filters based on user feedback
|
||||||
|
- Multiple crash and bug fixes
|
||||||
|
|
||||||
## v2.12.3
|
## v2.12.3
|
||||||
- Fixed issue with EXIF data, including coords, being removed from uploads
|
- Fixed issue with EXIF data, including coords, being removed from uploads
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,9 @@ dependencies {
|
||||||
// Utils
|
// Utils
|
||||||
implementation 'in.yuvi:http.fluent:1.3'
|
implementation 'in.yuvi:http.fluent:1.3'
|
||||||
implementation 'com.google.code.gson:gson:2.8.5'
|
implementation 'com.google.code.gson:gson:2.8.5'
|
||||||
implementation 'com.squareup.okhttp3:okhttp:4.8.0'
|
implementation ("com.squareup.okhttp3:okhttp:$OKHTTP_VERSION"){
|
||||||
|
force = true //API 19 support
|
||||||
|
}
|
||||||
implementation 'com.squareup.okio:okio:2.2.2'
|
implementation 'com.squareup.okio:okio:2.2.2'
|
||||||
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
|
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
|
||||||
implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
|
implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
|
||||||
|
|
@ -35,6 +37,7 @@ dependencies {
|
||||||
// UI
|
// UI
|
||||||
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.mapbox.mapboxsdk:mapbox-android-sdk:8.6.2'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:8.6.2'
|
||||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v8:0.11.0'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v8:0.11.0'
|
||||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.4.0'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.4.0'
|
||||||
|
|
@ -51,7 +54,7 @@ dependencies {
|
||||||
testImplementation "androidx.paging:paging-common-ktx:$PAGING_VERSION"
|
testImplementation "androidx.paging:paging-common-ktx:$PAGING_VERSION"
|
||||||
implementation "androidx.paging:paging-rxjava2-ktx:$PAGING_VERSION"
|
implementation "androidx.paging:paging-rxjava2-ktx:$PAGING_VERSION"
|
||||||
implementation "androidx.recyclerview:recyclerview:1.2.0-alpha02"
|
implementation "androidx.recyclerview:recyclerview:1.2.0-alpha02"
|
||||||
implementation 'com.squareup.okhttp3:okhttp-ws:3.4.1'
|
implementation "com.squareup.okhttp3:okhttp-ws:$OKHTTP_VERSION"
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
implementation 'ch.acra:acra-dialog:5.3.0'
|
implementation 'ch.acra:acra-dialog:5.3.0'
|
||||||
|
|
@ -60,7 +63,7 @@ dependencies {
|
||||||
api('com.github.tony19:logback-android-classic:1.1.1-6') {
|
api('com.github.tony19:logback-android-classic:1.1.1-6') {
|
||||||
exclude group: 'com.google.android', module: 'android'
|
exclude group: 'com.google.android', module: 'android'
|
||||||
}
|
}
|
||||||
implementation "com.squareup.okhttp3:logging-interceptor:4.5.0"
|
implementation "com.squareup.okhttp3:logging-interceptor:$OKHTTP_VERSION"
|
||||||
|
|
||||||
// Dependency injector
|
// Dependency injector
|
||||||
implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION"
|
implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION"
|
||||||
|
|
@ -81,7 +84,7 @@ dependencies {
|
||||||
testImplementation 'junit:junit:4.13'
|
testImplementation 'junit:junit:4.13'
|
||||||
testImplementation 'org.robolectric:robolectric:4.3'
|
testImplementation 'org.robolectric:robolectric:4.3'
|
||||||
testImplementation 'androidx.test:core:1.2.0'
|
testImplementation 'androidx.test:core:1.2.0'
|
||||||
testImplementation "com.squareup.okhttp3:mockwebserver:4.8.0"
|
testImplementation "com.squareup.okhttp3:mockwebserver:$OKHTTP_VERSION"
|
||||||
testImplementation "org.powermock:powermock-module-junit4:2.0.0-beta.5"
|
testImplementation "org.powermock:powermock-module-junit4:2.0.0-beta.5"
|
||||||
testImplementation "org.powermock:powermock-api-mockito2:2.0.0-beta.5"
|
testImplementation "org.powermock:powermock-api-mockito2:2.0.0-beta.5"
|
||||||
testImplementation 'org.mockito:mockito-core:2.23.0'
|
testImplementation 'org.mockito:mockito-core:2.23.0'
|
||||||
|
|
@ -139,8 +142,8 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
//applicationId 'fr.free.nrw.commons'
|
//applicationId 'fr.free.nrw.commons'
|
||||||
versionCode 561
|
versionCode 775
|
||||||
versionName '2.12.3'
|
versionName '2.13.1'
|
||||||
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
|
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
|
||||||
|
|
||||||
minSdkVersion 19
|
minSdkVersion 19
|
||||||
|
|
|
||||||
|
|
@ -248,24 +248,44 @@ public class BookmarkLocationsDao {
|
||||||
|
|
||||||
public static void onUpdate(SQLiteDatabase db, int from, int to) {
|
public static void onUpdate(SQLiteDatabase db, int from, int to) {
|
||||||
Timber.d("bookmarksLocations db is updated from:"+from+", to:"+to);
|
Timber.d("bookmarksLocations db is updated from:"+from+", to:"+to);
|
||||||
switch (from) {
|
if (from == to) {
|
||||||
case 7: onCreate(db);
|
return;
|
||||||
case 8: // No change
|
}
|
||||||
case 9: // No change
|
if (from < 7) {
|
||||||
case 10:
|
// doesn't exist yet
|
||||||
try {
|
from++;
|
||||||
db.execSQL("ALTER TABLE bookmarksLocations ADD COLUMN location_pic STRING;");
|
onUpdate(db, from, to);
|
||||||
} catch (SQLiteException exception){
|
return;
|
||||||
Timber.e(exception);
|
}
|
||||||
}
|
if (from == 7) {
|
||||||
case 11: // No change
|
// table added in version 8
|
||||||
case 12:
|
onCreate(db);
|
||||||
try {
|
from++;
|
||||||
db.execSQL("ALTER TABLE bookmarksLocations ADD COLUMN location_destroyed STRING;");
|
onUpdate(db, from, to);
|
||||||
}catch (SQLiteException exception){
|
return;
|
||||||
Timber.e(exception);
|
}
|
||||||
}
|
if (from == 8) {
|
||||||
break;
|
from++;
|
||||||
|
onUpdate(db, from, to);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (from == 10) {
|
||||||
|
//This is safe, and can be called clean, as we/I do not remember the appropriate version for this
|
||||||
|
//We are anyways switching to room, these things won't be necessary then
|
||||||
|
try {
|
||||||
|
db.execSQL("ALTER TABLE bookmarksLocations ADD COLUMN location_pic STRING;");
|
||||||
|
}catch (SQLiteException exception){
|
||||||
|
Timber.e(exception);//
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (from == 12) {
|
||||||
|
try {
|
||||||
|
db.execSQL(
|
||||||
|
"ALTER TABLE bookmarksLocations ADD COLUMN location_destroyed STRING;");
|
||||||
|
} catch (SQLiteException exception) {
|
||||||
|
Timber.e(exception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ 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 dateModified: Date? = null
|
var dateModified: Date? = null,
|
||||||
|
var hasInvalidLocation : Int = 0
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
|
|
||||||
fun completeWith(media: Media): Contribution {
|
fun completeWith(media: Media): Contribution {
|
||||||
|
|
@ -65,6 +66,18 @@ data class Contribution constructor(
|
||||||
wikidataPlace = from(item.place)
|
wikidataPlace = from(item.place)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this true when ImageProcessor has said that the location is invalid
|
||||||
|
* @param hasInvalidLocation
|
||||||
|
*/
|
||||||
|
fun setHasInvalidLocation(hasInvalidLocation: Boolean) {
|
||||||
|
this.hasInvalidLocation = if (hasInvalidLocation) 1 else 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hasInvalidLocation(): Boolean {
|
||||||
|
return hasInvalidLocation == 1
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val STATE_COMPLETED = -1
|
const val STATE_COMPLETED = -1
|
||||||
const val STATE_FAILED = 1
|
const val STATE_FAILED = 1
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,15 @@ import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager.OnBackStackChangedListener;
|
import androidx.fragment.app.FragmentManager.OnBackStackChangedListener;
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.MediaDataExtractor;
|
||||||
|
import fr.free.nrw.commons.auth.SessionManager;
|
||||||
|
import io.reactivex.disposables.Disposable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import fr.free.nrw.commons.Media;
|
import fr.free.nrw.commons.Media;
|
||||||
|
|
@ -83,6 +92,9 @@ public class ContributionsFragment
|
||||||
|
|
||||||
@Inject ContributionsPresenter contributionsPresenter;
|
@Inject ContributionsPresenter contributionsPresenter;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
SessionManager sessionManager;
|
||||||
|
|
||||||
private LatLng curLatLng;
|
private LatLng curLatLng;
|
||||||
|
|
||||||
private boolean firstLocationUpdate = true;
|
private boolean firstLocationUpdate = true;
|
||||||
|
|
@ -143,7 +155,14 @@ public class ContributionsFragment
|
||||||
|
|
||||||
initFragments();
|
initFragments();
|
||||||
|
|
||||||
if (!ConfigUtils.isBetaFlavour()) {
|
if(shouldShowMediaDetailsFragment){
|
||||||
|
showMediaDetailPagerFragment();
|
||||||
|
}else{
|
||||||
|
showContributionsListFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ConfigUtils.isBetaFlavour() && sessionManager.isUserLoggedIn()
|
||||||
|
&& sessionManager.getCurrentAccount() != null) {
|
||||||
setUploadCount();
|
setUploadCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
getSpanCount(getResources().getConfiguration().orientation));
|
getSpanCount(getResources().getConfiguration().orientation));
|
||||||
rvContributionsList.setLayoutManager(layoutManager);
|
rvContributionsList.setLayoutManager(layoutManager);
|
||||||
contributionsListPresenter.setup();
|
contributionsListPresenter.setup();
|
||||||
contributionsListPresenter.contributionList.observe(this, adapter::submitList);
|
contributionsListPresenter.contributionList.observe(this.getViewLifecycleOwner(), adapter::submitList);
|
||||||
rvContributionsList.setAdapter(adapter);
|
rvContributionsList.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import android.content.Context;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import androidx.collection.LruCache;
|
import androidx.collection.LruCache;
|
||||||
import androidx.room.Room;
|
import androidx.room.Room;
|
||||||
|
import androidx.room.migration.Migration;
|
||||||
|
import androidx.sqlite.db.SupportSQLiteDatabase;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
|
|
@ -49,6 +51,15 @@ public class CommonsApplicationModule {
|
||||||
private Context applicationContext;
|
private Context applicationContext;
|
||||||
public static final String IO_THREAD="io_thread";
|
public static final String IO_THREAD="io_thread";
|
||||||
public static final String MAIN_THREAD="main_thread";
|
public static final String MAIN_THREAD="main_thread";
|
||||||
|
private AppDatabase appDatabase;
|
||||||
|
|
||||||
|
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
|
||||||
|
@Override
|
||||||
|
public void migrate(SupportSQLiteDatabase database) {
|
||||||
|
database.execSQL("ALTER TABLE contribution "
|
||||||
|
+ " ADD COLUMN hasInvalidLocation INTEGER NOT NULL DEFAULT 0");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public CommonsApplicationModule(Context applicationContext) {
|
public CommonsApplicationModule(Context applicationContext) {
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
|
|
@ -103,11 +114,6 @@ public class CommonsApplicationModule {
|
||||||
return context.getContentResolver().acquireContentProviderClient(BuildConfig.CATEGORY_AUTHORITY);
|
return context.getContentResolver().acquireContentProviderClient(BuildConfig.CATEGORY_AUTHORITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is used to provide instance of DepictsContentProviderClient
|
|
||||||
* @param context context
|
|
||||||
* @return DepictsContentProviderClient*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is used to provide instance of RecentSearchContentProviderClient
|
* This method is used to provide instance of RecentSearchContentProviderClient
|
||||||
* which provides content of Recent Searches from database
|
* which provides content of Recent Searches from database
|
||||||
|
|
@ -224,9 +230,11 @@ public class CommonsApplicationModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
public AppDatabase provideAppDataBase() {
|
public AppDatabase provideAppDataBase() {
|
||||||
return Room.databaseBuilder(applicationContext, AppDatabase.class, "commons_room.db")
|
appDatabase = Room.databaseBuilder(applicationContext, AppDatabase.class, "commons_room.db")
|
||||||
|
.addMigrations(MIGRATION_1_2)
|
||||||
.fallbackToDestructiveMigration()
|
.fallbackToDestructiveMigration()
|
||||||
.build();
|
.build();
|
||||||
|
return appDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ public class NetworkingModule {
|
||||||
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(message -> {
|
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(message -> {
|
||||||
Timber.tag("OkHttp").v(message);
|
Timber.tag("OkHttp").v(message);
|
||||||
});
|
});
|
||||||
httpLoggingInterceptor.level(BuildConfig.DEBUG ? Level.BODY: Level.BASIC);
|
httpLoggingInterceptor.setLevel(BuildConfig.DEBUG ? Level.BODY: Level.BASIC);
|
||||||
return httpLoggingInterceptor;
|
return httpLoggingInterceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ public class FilePicker implements Constants {
|
||||||
public static List<UploadableFile> handleExternalImagesPicked(Intent data, Activity activity) {
|
public static List<UploadableFile> handleExternalImagesPicked(Intent data, Activity activity) {
|
||||||
try {
|
try {
|
||||||
return getFilesFromGalleryPictures(data, activity);
|
return getFilesFromGalleryPictures(data, activity);
|
||||||
} catch (IOException e) {
|
} catch (IOException | SecurityException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
|
|
@ -207,7 +207,7 @@ public class FilePicker implements Constants {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<UploadableFile> getFilesFromGalleryPictures(Intent data, Activity activity) throws IOException {
|
private static List<UploadableFile> getFilesFromGalleryPictures(Intent data, Activity activity) throws IOException, SecurityException {
|
||||||
List<UploadableFile> files = new ArrayList<>();
|
List<UploadableFile> files = new ArrayList<>();
|
||||||
ClipData clipData = data.getClipData();
|
ClipData clipData = data.getClipData();
|
||||||
if (clipData == null) {
|
if (clipData == null) {
|
||||||
|
|
|
||||||
|
|
@ -104,12 +104,15 @@ class PickedFiles implements Constants {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static UploadableFile pickedExistingPicture(@NonNull Context context, Uri photoUri) throws IOException {
|
static UploadableFile pickedExistingPicture(@NonNull Context context, Uri photoUri) throws IOException, SecurityException {// SecurityException for those file providers who share URI but forget to grant necessary permissions
|
||||||
InputStream pictureInputStream = context.getContentResolver().openInputStream(photoUri);
|
InputStream pictureInputStream = context.getContentResolver().openInputStream(photoUri);
|
||||||
File directory = tempImageDirectory(context);
|
File directory = tempImageDirectory(context);
|
||||||
File photoFile = new File(directory, UUID.randomUUID().toString() + "." + getMimeType(context, photoUri));
|
File photoFile = new File(directory, UUID.randomUUID().toString() + "." + getMimeType(context, photoUri));
|
||||||
photoFile.createNewFile();
|
if (photoFile.createNewFile()) {
|
||||||
writeToFile(pictureInputStream, photoFile);
|
writeToFile(pictureInputStream, photoFile);
|
||||||
|
} else {
|
||||||
|
throw new IOException("could not create photoFile to write upon");
|
||||||
|
}
|
||||||
return new UploadableFile(photoUri, photoFile);
|
return new UploadableFile(photoUri, photoFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -295,7 +295,9 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
|
||||||
* The method notify the viewpager that number of items have changed.
|
* The method notify the viewpager that number of items have changed.
|
||||||
*/
|
*/
|
||||||
public void notifyDataSetChanged(){
|
public void notifyDataSetChanged(){
|
||||||
adapter.notifyDataSetChanged();
|
if (null != adapter) {
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -23,18 +23,11 @@ import com.facebook.drawee.drawable.ScalingUtils;
|
||||||
import com.facebook.drawee.generic.GenericDraweeHierarchy;
|
import com.facebook.drawee.generic.GenericDraweeHierarchy;
|
||||||
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
|
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
|
||||||
import com.facebook.drawee.interfaces.DraweeController;
|
import com.facebook.drawee.interfaces.DraweeController;
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
import com.facebook.drawee.view.SimpleDraweeView;
|
|
||||||
import com.facebook.imagepipeline.image.ImageInfo;
|
import com.facebook.imagepipeline.image.ImageInfo;
|
||||||
import com.github.chrisbanes.photoview.PhotoView;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
public class ZoomableActivity extends AppCompatActivity {
|
public class ZoomableActivity extends AppCompatActivity {
|
||||||
private Uri imageUri;
|
private Uri imageUri;
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ public class ZoomableDraweeView extends DraweeView<GenericDraweeHierarchy>
|
||||||
|
|
||||||
private boolean mIsDialtoneEnabled = false;
|
private boolean mIsDialtoneEnabled = false;
|
||||||
private boolean mZoomingEnabled = true;
|
private boolean mZoomingEnabled = true;
|
||||||
|
private TransformationListener transformationListener;
|
||||||
|
|
||||||
private final ControllerListener mControllerListener =
|
private final ControllerListener mControllerListener =
|
||||||
new BaseControllerListener<Object>() {
|
new BaseControllerListener<Object>() {
|
||||||
|
|
@ -73,9 +74,18 @@ public class ZoomableDraweeView extends DraweeView<GenericDraweeHierarchy>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransformEnd(Matrix transform) {}
|
public void onTransformEnd(Matrix transform) {
|
||||||
|
if (null != transformationListener) {
|
||||||
|
transformationListener.onTransformationEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public void setTransformationListener(
|
||||||
|
TransformationListener transformationListener) {
|
||||||
|
this.transformationListener = transformationListener;
|
||||||
|
}
|
||||||
|
|
||||||
private final GestureListenerWrapper mTapListenerWrapper = new GestureListenerWrapper();
|
private final GestureListenerWrapper mTapListenerWrapper = new GestureListenerWrapper();
|
||||||
|
|
||||||
public ZoomableDraweeView(Context context, GenericDraweeHierarchy hierarchy) {
|
public ZoomableDraweeView(Context context, GenericDraweeHierarchy hierarchy) {
|
||||||
|
|
@ -397,4 +407,11 @@ public class ZoomableDraweeView extends DraweeView<GenericDraweeHierarchy>
|
||||||
protected ZoomableController createZoomableController() {
|
protected ZoomableController createZoomableController() {
|
||||||
return AnimatedZoomableController.newInstance();
|
return AnimatedZoomableController.newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this, If someone is willing to listen to scale change
|
||||||
|
*/
|
||||||
|
public interface TransformationListener{
|
||||||
|
void onTransformationEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
package fr.free.nrw.commons.nearby;
|
package fr.free.nrw.commons.nearby;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Parcel;
|
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
|
|
||||||
|
|
@ -12,7 +10,6 @@ import androidx.appcompat.widget.AppCompatCheckBox;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base on https://stackoverflow.com/a/40939367/3950497 answer.
|
* Base on https://stackoverflow.com/a/40939367/3950497 answer.
|
||||||
|
|
@ -25,7 +22,7 @@ public class CheckBoxTriStates extends AppCompatCheckBox {
|
||||||
|
|
||||||
static public final int CHECKED = 1;
|
static public final int CHECKED = 1;
|
||||||
|
|
||||||
private int state;
|
private int state=UNKNOWN;
|
||||||
|
|
||||||
private Callback callback;
|
private Callback callback;
|
||||||
|
|
||||||
|
|
@ -64,12 +61,6 @@ public class CheckBoxTriStates extends AppCompatCheckBox {
|
||||||
*/
|
*/
|
||||||
private OnCheckedChangeListener clientListener;
|
private OnCheckedChangeListener clientListener;
|
||||||
|
|
||||||
/**
|
|
||||||
* This flag is needed to avoid accidentally changing the current {@link #state} when
|
|
||||||
* {@link #onRestoreInstanceState(Parcelable)} calls {@link #setChecked(boolean)}
|
|
||||||
* evoking our {@link #privateListener} and therefore changing the real state.
|
|
||||||
*/
|
|
||||||
private boolean restoring;
|
|
||||||
|
|
||||||
public CheckBoxTriStates(Context context) {
|
public CheckBoxTriStates(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
@ -91,7 +82,7 @@ public class CheckBoxTriStates extends AppCompatCheckBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setState(int state) {
|
public void setState(int state) {
|
||||||
if(!this.restoring && this.state != state) {
|
if(this.state != state) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
|
||||||
if(this.clientListener != null) {
|
if(this.clientListener != null) {
|
||||||
|
|
@ -118,27 +109,6 @@ public class CheckBoxTriStates extends AppCompatCheckBox {
|
||||||
super.setOnCheckedChangeListener(privateListener);
|
super.setOnCheckedChangeListener(privateListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Parcelable onSaveInstanceState() {
|
|
||||||
Parcelable superState = super.onSaveInstanceState();
|
|
||||||
|
|
||||||
SavedState ss = new SavedState(superState);
|
|
||||||
|
|
||||||
ss.state = state;
|
|
||||||
|
|
||||||
return ss;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRestoreInstanceState(Parcelable state) {
|
|
||||||
this.restoring = true; // indicates that the ui is restoring its state
|
|
||||||
SavedState ss = (SavedState) state;
|
|
||||||
super.onRestoreInstanceState(ss.getSuperState());
|
|
||||||
setState(ss.state);
|
|
||||||
requestLayout();
|
|
||||||
this.restoring = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
state = UNKNOWN;
|
state = UNKNOWN;
|
||||||
updateBtn();
|
updateBtn();
|
||||||
|
|
@ -164,44 +134,4 @@ public class CheckBoxTriStates extends AppCompatCheckBox {
|
||||||
setButtonDrawable(btnDrawable);
|
setButtonDrawable(btnDrawable);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class SavedState extends BaseSavedState {
|
|
||||||
int state;
|
|
||||||
|
|
||||||
SavedState(Parcelable superState) {
|
|
||||||
super(superState);
|
|
||||||
}
|
|
||||||
|
|
||||||
private SavedState(Parcel in) {
|
|
||||||
super(in);
|
|
||||||
state = in.readInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeToParcel(Parcel out, int flags) {
|
|
||||||
super.writeToParcel(out, flags);
|
|
||||||
out.writeValue(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "CheckboxTriState.SavedState{"
|
|
||||||
+ Integer.toHexString(System.identityHashCode(this))
|
|
||||||
+ " state=" + state + "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("hiding")
|
|
||||||
public static final Parcelable.Creator<SavedState> CREATOR =
|
|
||||||
new Parcelable.Creator<SavedState>() {
|
|
||||||
@Override
|
|
||||||
public SavedState createFromParcel(Parcel in) {
|
|
||||||
return new SavedState(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SavedState[] newArray(int size) {
|
|
||||||
return new SavedState[size];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -19,6 +19,8 @@ import android.graphics.Bitmap;
|
||||||
import android.graphics.drawable.VectorDrawable;
|
import android.graphics.drawable.VectorDrawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
|
@ -39,6 +41,7 @@ import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.appcompat.widget.AppCompatTextView;
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
@ -75,7 +78,6 @@ import fr.free.nrw.commons.auth.LoginActivity;
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
||||||
import fr.free.nrw.commons.contributions.ContributionController;
|
import fr.free.nrw.commons.contributions.ContributionController;
|
||||||
import fr.free.nrw.commons.contributions.MainActivity;
|
import fr.free.nrw.commons.contributions.MainActivity;
|
||||||
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||||
|
|
@ -154,6 +156,8 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
@BindView(R.id.rv_nearby_list)
|
@BindView(R.id.rv_nearby_list)
|
||||||
RecyclerView rvNearbyList;
|
RecyclerView rvNearbyList;
|
||||||
@BindView(R.id.no_results_message) TextView noResultsView;
|
@BindView(R.id.no_results_message) TextView noResultsView;
|
||||||
|
@BindView(R.id.tv_attribution)
|
||||||
|
AppCompatTextView tvAttribution;
|
||||||
|
|
||||||
@Inject LocationServiceManager locationManager;
|
@Inject LocationServiceManager locationManager;
|
||||||
@Inject NearbyController nearbyController;
|
@Inject NearbyController nearbyController;
|
||||||
|
|
@ -235,8 +239,8 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
final UiSettings uiSettings = mapBoxMap.getUiSettings();
|
final UiSettings uiSettings = mapBoxMap.getUiSettings();
|
||||||
uiSettings.setCompassGravity(Gravity.BOTTOM | Gravity.LEFT);
|
uiSettings.setCompassGravity(Gravity.BOTTOM | Gravity.LEFT);
|
||||||
uiSettings.setCompassMargins(12, 0, 0, 24);
|
uiSettings.setCompassMargins(12, 0, 0, 24);
|
||||||
uiSettings.setLogoEnabled(true);
|
uiSettings.setLogoEnabled(false);
|
||||||
uiSettings.setAttributionEnabled(true);
|
uiSettings.setAttributionEnabled(false);
|
||||||
uiSettings.setRotateGesturesEnabled(false);
|
uiSettings.setRotateGesturesEnabled(false);
|
||||||
isMapBoxReady =true;
|
isMapBoxReady =true;
|
||||||
performMapReadyActions();
|
performMapReadyActions();
|
||||||
|
|
@ -259,6 +263,9 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
scaleBarPlugin.create(scaleBarOptions);
|
scaleBarPlugin.create(scaleBarOptions);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tvAttribution.setText(Html.fromHtml(getString(R.string.map_attribution)));
|
||||||
|
tvAttribution.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -659,7 +666,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCurrentLocationMarkerVisible() {
|
public boolean isCurrentLocationMarkerVisible() {
|
||||||
if (latLngBounds == null) {
|
if (latLngBounds == null || currentLocationMarker==null) {
|
||||||
Timber.d("Map projection bounds are null");
|
Timber.d("Map projection bounds are null");
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ public class Prefs {
|
||||||
public static final String MANAGED_EXIF_TAGS = "managed_exif_tags";
|
public static final String MANAGED_EXIF_TAGS = "managed_exif_tags";
|
||||||
public static final String KEY_LANGUAGE_VALUE = "languageDescription";
|
public static final String KEY_LANGUAGE_VALUE = "languageDescription";
|
||||||
public static final String KEY_THEME_VALUE = "appThemePref";
|
public static final String KEY_THEME_VALUE = "appThemePref";
|
||||||
|
public static final String TELEMETRY_PREFERENCE = "telemetryPref";
|
||||||
|
|
||||||
public static class Licenses {
|
public static class Licenses {
|
||||||
public static final String CC_BY_SA_3 = "CC BY-SA 3.0";
|
public static final String CC_BY_SA_3 = "CC BY-SA 3.0";
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.karumi.dexter.Dexter;
|
import com.karumi.dexter.Dexter;
|
||||||
import com.karumi.dexter.listener.PermissionGrantedResponse;
|
import com.karumi.dexter.listener.PermissionGrantedResponse;
|
||||||
import com.karumi.dexter.listener.single.BasePermissionListener;
|
import com.karumi.dexter.listener.single.BasePermissionListener;
|
||||||
|
import com.mapbox.mapboxsdk.Mapbox;
|
||||||
|
import com.mapbox.mapboxsdk.maps.TelemetryDefinition;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.Utils;
|
import fr.free.nrw.commons.Utils;
|
||||||
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||||
|
|
@ -85,6 +87,24 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
||||||
findPreference("displayLocationPermissionForCardView").setEnabled(false);
|
findPreference("displayLocationPermissionForCardView").setEnabled(false);
|
||||||
findPreference("displayCampaignsCardView").setEnabled(false);
|
findPreference("displayCampaignsCardView").setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findPreference("telemetryOptOut").setOnPreferenceChangeListener(
|
||||||
|
(preference, newValue) -> {
|
||||||
|
telemetryOptInOut((boolean)newValue);
|
||||||
|
defaultKvStore.putBoolean(Prefs.TELEMETRY_PREFERENCE,(boolean)newValue);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opt in or out of MapBox telemetry
|
||||||
|
* @param shouldOptIn
|
||||||
|
*/
|
||||||
|
private void telemetryOptInOut(boolean shouldOptIn){
|
||||||
|
TelemetryDefinition telemetry = Mapbox.getTelemetry();
|
||||||
|
if (telemetry != null) {
|
||||||
|
telemetry.setUserTelemetryRequestState(shouldOptIn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ public class UploadItem {
|
||||||
private final long createdTimestamp;
|
private final long createdTimestamp;
|
||||||
private final String createdTimestampSource;
|
private final String createdTimestampSource;
|
||||||
private final BehaviorSubject<Integer> imageQuality;
|
private final BehaviorSubject<Integer> imageQuality;
|
||||||
|
private boolean hasInvalidLocation;
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
UploadItem(final Uri mediaUri,
|
UploadItem(final Uri mediaUri,
|
||||||
|
|
@ -103,4 +105,11 @@ public class UploadItem {
|
||||||
this.gpsCoords = gpsCoords;
|
this.gpsCoords = gpsCoords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHasInvalidLocation(boolean hasInvalidLocation) {
|
||||||
|
this.hasInvalidLocation=hasInvalidLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasInvalidLocation() {
|
||||||
|
return hasInvalidLocation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,13 @@ public class UploadModel {
|
||||||
{
|
{
|
||||||
final Contribution contribution = new Contribution(
|
final Contribution contribution = new Contribution(
|
||||||
item, sessionManager, newListOf(selectedDepictions), newListOf(selectedCategories));
|
item, sessionManager, newListOf(selectedDepictions), newListOf(selectedCategories));
|
||||||
|
|
||||||
|
contribution.setHasInvalidLocation(item.hasInvalidLocation());
|
||||||
|
|
||||||
|
Timber.d("Created timestamp while building contribution is %s, %s",
|
||||||
|
item.getCreatedTimestamp(),
|
||||||
|
new Date(item.getCreatedTimestamp()));
|
||||||
|
|
||||||
if (item.getCreatedTimestamp() != -1L) {
|
if (item.getCreatedTimestamp() != -1L) {
|
||||||
contribution.setDateCreated(new Date(item.getCreatedTimestamp()));
|
contribution.setDateCreated(new Date(item.getCreatedTimestamp()));
|
||||||
contribution.setDateCreatedSource(item.getCreatedTimestampSource());
|
contribution.setDateCreatedSource(item.getCreatedTimestampSource());
|
||||||
|
|
@ -188,4 +195,5 @@ public class UploadModel {
|
||||||
public List<DepictedItem> getSelectedDepictions() {
|
public List<DepictedItem> getSelectedDepictions() {
|
||||||
return selectedDepictions;
|
return selectedDepictions;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import fr.free.nrw.commons.contributions.MainActivity;
|
||||||
import fr.free.nrw.commons.di.CommonsApplicationModule;
|
import fr.free.nrw.commons.di.CommonsApplicationModule;
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerService;
|
import fr.free.nrw.commons.di.CommonsDaggerService;
|
||||||
import fr.free.nrw.commons.media.MediaClient;
|
import fr.free.nrw.commons.media.MediaClient;
|
||||||
|
import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
import fr.free.nrw.commons.wikidata.WikidataEditService;
|
import fr.free.nrw.commons.wikidata.WikidataEditService;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.Scheduler;
|
import io.reactivex.Scheduler;
|
||||||
|
|
@ -350,8 +351,14 @@ public class UploadService extends CommonsDaggerService {
|
||||||
.add(wikidataEditService.addDepictionsAndCaptions(uploadResult, contribution));
|
.add(wikidataEditService.addDepictionsAndCaptions(uploadResult, contribution));
|
||||||
WikidataPlace wikidataPlace = contribution.getWikidataPlace();
|
WikidataPlace wikidataPlace = contribution.getWikidataPlace();
|
||||||
if (wikidataPlace != null && wikidataPlace.getImageValue() == null) {
|
if (wikidataPlace != null && wikidataPlace.getImageValue() == null) {
|
||||||
wikidataEditService.createClaim(wikidataPlace, uploadResult.getFilename(),
|
if (!contribution.hasInvalidLocation()) {
|
||||||
contribution.getMedia().getCaptions());
|
wikidataEditService.createClaim(wikidataPlace, uploadResult.getFilename(),
|
||||||
|
contribution.getMedia().getCaptions());
|
||||||
|
} else {
|
||||||
|
ViewUtil.showShortToast(this, getString(R.string.wikidata_edit_failure));
|
||||||
|
Timber
|
||||||
|
.d("Image location and nearby place location mismatched, so Wikidata item won't be edited");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
saveCompletedContribution(contribution, uploadResult);
|
saveCompletedContribution(contribution, uploadResult);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class UploadMediaDetailFragment extends UploadBaseFragment implements
|
public class UploadMediaDetailFragment extends UploadBaseFragment implements
|
||||||
UploadMediaDetailsContract.View, UploadMediaDetailAdapter.EventListener {
|
UploadMediaDetailsContract.View, UploadMediaDetailAdapter.EventListener {
|
||||||
|
|
||||||
@BindView(R.id.tv_title)
|
@BindView(R.id.tv_title)
|
||||||
TextView tvTitle;
|
TextView tvTitle;
|
||||||
|
|
@ -98,7 +98,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
@Nullable Bundle savedInstanceState) {
|
@Nullable Bundle savedInstanceState) {
|
||||||
return inflater.inflate(R.layout.fragment_upload_media_detail_fragment, container, false);
|
return inflater.inflate(R.layout.fragment_upload_media_detail_fragment, container, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +111,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
|
||||||
|
|
||||||
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()));
|
callback.getTotalNumberOfSteps()));
|
||||||
initRecyclerView();
|
initRecyclerView();
|
||||||
initPresenter();
|
initPresenter();
|
||||||
presenter.receiveImage(uploadableFile, place);
|
presenter.receiveImage(uploadableFile, place);
|
||||||
|
|
@ -140,10 +140,10 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
|
||||||
*/
|
*/
|
||||||
private void attachImageViewScaleChangeListener() {
|
private void attachImageViewScaleChangeListener() {
|
||||||
photoViewBackgroundImage.setOnScaleChangeListener(
|
photoViewBackgroundImage.setOnScaleChangeListener(
|
||||||
(scaleFactor, focusX, focusY) -> {
|
(scaleFactor, focusX, focusY) -> {
|
||||||
//Whenever the uses plays with the image, lets collapse the media detail container
|
//Whenever the uses plays with the image, lets collapse the media detail container
|
||||||
expandCollapseLlMediaDetail(false);
|
expandCollapseLlMediaDetail(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -228,16 +228,16 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
|
||||||
@Override
|
@Override
|
||||||
public void onNearbyPlaceFound(UploadItem uploadItem, Place place) {
|
public void onNearbyPlaceFound(UploadItem uploadItem, Place place) {
|
||||||
DialogUtil.showAlertDialog(getActivity(),
|
DialogUtil.showAlertDialog(getActivity(),
|
||||||
getString(R.string.upload_nearby_place_found_title),
|
getString(R.string.upload_nearby_place_found_title),
|
||||||
String.format(Locale.getDefault(),
|
String.format(Locale.getDefault(),
|
||||||
getString(R.string.upload_nearby_place_found_description),
|
getString(R.string.upload_nearby_place_found_description),
|
||||||
place.getName()),
|
place.getName()),
|
||||||
() -> {
|
() -> {
|
||||||
presenter.onUserConfirmedUploadIsOfPlace(place, callback.getIndexInViewFlipper(this));
|
presenter.onUserConfirmedUploadIsOfPlace(place, callback.getIndexInViewFlipper(this));
|
||||||
},
|
},
|
||||||
() -> {
|
() -> {
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -264,16 +264,16 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
|
||||||
public void showDuplicatePicturePopup(UploadItem uploadItem) {
|
public void showDuplicatePicturePopup(UploadItem uploadItem) {
|
||||||
String uploadTitleFormat = getString(R.string.upload_title_duplicate);
|
String uploadTitleFormat = getString(R.string.upload_title_duplicate);
|
||||||
DialogUtil.showAlertDialog(getActivity(),
|
DialogUtil.showAlertDialog(getActivity(),
|
||||||
getString(R.string.duplicate_image_found),
|
getString(R.string.duplicate_image_found),
|
||||||
String.format(Locale.getDefault(),
|
String.format(Locale.getDefault(),
|
||||||
uploadTitleFormat,
|
uploadTitleFormat,
|
||||||
uploadItem.getFileName()),
|
uploadItem.getFileName()),
|
||||||
getString(R.string.upload),
|
getString(R.string.upload),
|
||||||
getString(R.string.cancel),
|
getString(R.string.cancel),
|
||||||
() -> {
|
() -> {
|
||||||
uploadItem.setImageQuality(ImageUtils.IMAGE_KEEP);
|
uploadItem.setImageQuality(ImageUtils.IMAGE_KEEP);
|
||||||
onNextButtonClicked();
|
onNextButtonClicked();
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -283,16 +283,16 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
|
||||||
String errorMessageForResult = getErrorMessageForResult(getContext(), errorCode);
|
String errorMessageForResult = getErrorMessageForResult(getContext(), errorCode);
|
||||||
if (!StringUtils.isBlank(errorMessageForResult)) {
|
if (!StringUtils.isBlank(errorMessageForResult)) {
|
||||||
DialogUtil.showAlertDialog(getActivity(),
|
DialogUtil.showAlertDialog(getActivity(),
|
||||||
getString(R.string.upload_problem_image),
|
getString(R.string.upload_problem_image),
|
||||||
errorMessageForResult,
|
errorMessageForResult,
|
||||||
getString(R.string.upload),
|
getString(R.string.upload),
|
||||||
getString(R.string.cancel),
|
getString(R.string.cancel),
|
||||||
() -> {
|
() -> {
|
||||||
uploadItem.setImageQuality(ImageUtils.IMAGE_KEEP);
|
uploadItem.setImageQuality(ImageUtils.IMAGE_KEEP);
|
||||||
onNextButtonClicked();
|
onNextButtonClicked();
|
||||||
},
|
},
|
||||||
() -> deleteThisPicture()
|
() -> deleteThisPicture()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
//If the error message is null, we will probably not show anything
|
//If the error message is null, we will probably not show anything
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ public class UploadMediaPresenter implements UserActionListener, SimilarImageInt
|
||||||
.observeOn(mainThreadScheduler)
|
.observeOn(mainThreadScheduler)
|
||||||
.subscribe(imageResult -> {
|
.subscribe(imageResult -> {
|
||||||
view.showProgress(false);
|
view.showProgress(false);
|
||||||
handleImageResult(imageResult, uploadItem);
|
handleImageResult(imageResult, uploadItem);
|
||||||
},
|
},
|
||||||
throwable -> {
|
throwable -> {
|
||||||
view.showProgress(false);
|
view.showProgress(false);
|
||||||
|
|
@ -201,6 +201,7 @@ public class UploadMediaPresenter implements UserActionListener, SimilarImageInt
|
||||||
UploadItem uploadItem) {
|
UploadItem uploadItem) {
|
||||||
if (imageResult == IMAGE_KEEP || imageResult == IMAGE_OK) {
|
if (imageResult == IMAGE_KEEP || imageResult == IMAGE_OK) {
|
||||||
view.onImageValidationSuccess();
|
view.onImageValidationSuccess();
|
||||||
|
uploadItem.setHasInvalidLocation(false);
|
||||||
} else {
|
} else {
|
||||||
handleBadImage(imageResult, uploadItem);
|
handleBadImage(imageResult, uploadItem);
|
||||||
}
|
}
|
||||||
|
|
@ -212,11 +213,12 @@ public class UploadMediaPresenter implements UserActionListener, SimilarImageInt
|
||||||
* @param errorCode
|
* @param errorCode
|
||||||
* @param uploadItem
|
* @param uploadItem
|
||||||
*/
|
*/
|
||||||
public void handleBadImage(Integer errorCode, UploadItem uploadItem) {
|
public void handleBadImage(Integer errorCode,
|
||||||
|
UploadItem uploadItem) {
|
||||||
Timber.d("Handle bad picture with error code %d", errorCode);
|
Timber.d("Handle bad picture with error code %d", errorCode);
|
||||||
// If location of image and nearby does not match, then set shared preferences to disable wikidata edits
|
if (errorCode
|
||||||
if (errorCode >= 8) {
|
>= 8) { // If location of image and nearby does not match
|
||||||
defaultKVStore.putBoolean("Picture_Has_Correct_Location", false);
|
uploadItem.setHasInvalidLocation(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (errorCode) {
|
switch (errorCode) {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="?attr/mainBackground"
|
android:background="?attr/mainBackground"
|
||||||
>
|
>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/dummy_category_edit_container"
|
android:id="@+id/dummy_category_edit_container"
|
||||||
|
|
@ -23,53 +23,53 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/mediaDetailImageFailed"
|
android:id="@+id/mediaDetailImageFailed"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:src="@android:drawable/ic_menu_close_clear_cancel"
|
android:src="@android:drawable/ic_menu_close_clear_cancel"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:contentDescription="@string/mediaimage_failed"
|
android:contentDescription="@string/mediaimage_failed"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<com.facebook.drawee.view.SimpleDraweeView
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/mediaDetailImageView"
|
android:id="@+id/mediaDetailImageView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/dimen_250"
|
android:layout_height="@dimen/dimen_250"
|
||||||
app:actualImageScaleType="none" />
|
app:actualImageScaleType="none" />
|
||||||
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
android:id="@+id/mediaDetailScrollView"
|
android:id="@+id/mediaDetailScrollView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:cacheColorHint="@android:color/transparent"
|
android:cacheColorHint="@android:color/transparent"
|
||||||
android:fillViewport="true">
|
android:fillViewport="true">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<!-- Placeholder. Height gets set at runtime based on container size; the initial value is a hack to keep
|
<!-- Placeholder. Height gets set at runtime based on container size; the initial value is a hack to keep
|
||||||
the detail info offscreen until it's placed properly. May be a better way to do this. -->
|
the detail info offscreen until it's placed properly. May be a better way to do this. -->
|
||||||
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" >
|
android:layout_height="wrap_content" >
|
||||||
|
|
||||||
<com.facebook.drawee.view.SimpleDraweeView
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
android:id="@+id/mediaDetailImageViewLandscape"
|
android:id="@+id/mediaDetailImageViewLandscape"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/dimen_250"
|
android:layout_height="@dimen/dimen_250"
|
||||||
app:actualImageScaleType="none"
|
app:actualImageScaleType="none"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:id="@+id/mediaDetailImageViewSpacer"
|
android:id="@+id/mediaDetailImageViewSpacer"
|
||||||
>
|
>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
@ -77,32 +77,32 @@
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?attr/mainBackground"
|
android:background="?attr/mainBackground"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@color/primaryDarkColor"
|
android:background="@color/primaryDarkColor"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="@dimen/quarter_standard_height">
|
android:padding="@dimen/quarter_standard_height">
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextLabelTitle"
|
style="@style/MediaDetailTextLabelTitle"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="@string/media_detail_title" />
|
android:text="@string/media_detail_title" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextBody"
|
style="@style/MediaDetailTextBody"
|
||||||
android:id="@+id/mediaDetailTitle"
|
android:id="@+id/mediaDetailTitle"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:text="Title of the media" />
|
tools:text="Title of the media" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
@ -130,24 +130,24 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
style="@style/MediaDetailContainer"
|
style="@style/MediaDetailContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/authorLinearLayout"
|
android:id="@+id/authorLinearLayout"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextLabelGeneric"
|
style="@style/MediaDetailTextLabelGeneric"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="@string/media_detail_author" />
|
android:text="@string/media_detail_author" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextBody"
|
style="@style/MediaDetailTextBody"
|
||||||
android:id="@+id/mediaDetailAuthor"
|
android:id="@+id/mediaDetailAuthor"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:text="Media author user name goes here." />
|
tools:text="Media author user name goes here." />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
@ -172,88 +172,88 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
style="@style/MediaDetailContainer"
|
style="@style/MediaDetailContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextLabelGeneric"
|
style="@style/MediaDetailTextLabelGeneric"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="@string/media_detail_description" />
|
android:text="@string/media_detail_description" />
|
||||||
|
|
||||||
<fr.free.nrw.commons.ui.widget.HtmlTextView
|
<fr.free.nrw.commons.ui.widget.HtmlTextView
|
||||||
android:id="@+id/mediaDetailDesc"
|
android:id="@+id/mediaDetailDesc"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="70"
|
android:layout_weight="70"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
android:padding="@dimen/small_gap"
|
android:padding="@dimen/small_gap"
|
||||||
android:textColor="?attr/mediaDetailsText"
|
android:textColor="?attr/mediaDetailsText"
|
||||||
android:textSize="@dimen/description_text_size"
|
android:textSize="@dimen/description_text_size"
|
||||||
tools:text="Description of the media goes here. This can potentially be fairly long, and will need to wrap across multiple lines. We hope it looks nice though." />
|
tools:text="Description of the media goes here. This can potentially be fairly long, and will need to wrap across multiple lines. We hope it looks nice though." />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:background="?attr/mediaDetailSpacerColor"
|
android:background="?attr/mediaDetailSpacerColor"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/tiny_gap"/>
|
android:layout_height="@dimen/tiny_gap"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
style="@style/MediaDetailContainer"
|
style="@style/MediaDetailContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextLabelGeneric"
|
style="@style/MediaDetailTextLabelGeneric"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="@string/media_detail_license" />
|
android:text="@string/media_detail_license" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/mediaDetailLicense"
|
android:id="@+id/mediaDetailLicense"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="70"
|
android:layout_weight="70"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
android:foreground="?attr/selectableItemBackground"
|
android:foreground="?attr/selectableItemBackground"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:padding="@dimen/small_gap"
|
android:padding="@dimen/small_gap"
|
||||||
android:textColor="?attr/mediaDetailsText"
|
android:textColor="?attr/mediaDetailsText"
|
||||||
android:textSize="@dimen/description_text_size"
|
android:textSize="@dimen/description_text_size"
|
||||||
android:drawablePadding="@dimen/tiny_gap"
|
android:drawablePadding="@dimen/tiny_gap"
|
||||||
android:drawableStart="?attr/iconInfo24"
|
android:drawableStart="?attr/iconInfo24"
|
||||||
tools:text="License link" />
|
tools:text="License link" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
style="@style/MediaDetailContainer"
|
style="@style/MediaDetailContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextLabelGeneric"
|
style="@style/MediaDetailTextLabelGeneric"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="@string/media_detail_coordinates" />
|
android:text="@string/media_detail_coordinates" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/mediaDetailCoordinates"
|
android:id="@+id/mediaDetailCoordinates"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="70"
|
android:layout_weight="70"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
android:foreground="?attr/selectableItemBackground"
|
android:foreground="?attr/selectableItemBackground"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:padding="@dimen/small_gap"
|
android:padding="@dimen/small_gap"
|
||||||
android:textColor="?attr/mediaDetailsText"
|
android:textColor="?attr/mediaDetailsText"
|
||||||
android:textSize="@dimen/description_text_size"
|
android:textSize="@dimen/description_text_size"
|
||||||
android:drawablePadding="@dimen/tiny_gap"
|
android:drawablePadding="@dimen/tiny_gap"
|
||||||
android:drawableStart="?attr/iconMap24"
|
android:drawableStart="?attr/iconMap24"
|
||||||
tools:text="Coordinates link" />
|
tools:text="Coordinates link" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
@ -264,39 +264,39 @@
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:textStyle="bold">
|
android:textStyle="bold">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextLabelGeneric"
|
style="@style/MediaDetailTextLabelGeneric"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="@string/media_detail_depiction" />
|
android:text="@string/media_detail_depiction" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/media_detail_depiction_container"
|
android:id="@+id/media_detail_depiction_container"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="70"
|
android:layout_weight="70"
|
||||||
android:orientation="vertical" />
|
android:orientation="vertical" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
style="@style/MediaDetailContainer"
|
style="@style/MediaDetailContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:textStyle="bold">
|
android:textStyle="bold">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextLabelGeneric"
|
style="@style/MediaDetailTextLabelGeneric"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="@string/detail_panel_cats_label" />
|
android:text="@string/detail_panel_cats_label" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/mediaDetailCategoryContainer"
|
android:id="@+id/mediaDetailCategoryContainer"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="70"
|
android:layout_weight="70"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
@ -310,90 +310,90 @@
|
||||||
android:background="@drawable/ic_baseline_edit_24" />
|
android:background="@drawable/ic_baseline_edit_24" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
style="@style/MediaDetailContainer"
|
style="@style/MediaDetailContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextLabelGeneric"
|
style="@style/MediaDetailTextLabelGeneric"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="@string/media_detail_uploaded_date" />
|
android:text="@string/media_detail_uploaded_date" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextBody"
|
style="@style/MediaDetailTextBody"
|
||||||
android:id="@+id/mediaDetailuploadeddate"
|
android:id="@+id/mediaDetailuploadeddate"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:text="Uploaded date" />
|
tools:text="Uploaded date" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/nominatedDeletionBanner"
|
android:id="@+id/nominatedDeletionBanner"
|
||||||
android:background="?attr/mediaDetailNominationBackground"
|
android:background="?attr/mediaDetailNominationBackground"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="@dimen/quarter_standard_height"
|
android:padding="@dimen/quarter_standard_height"
|
||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/nominated_for_deletion"
|
android:text="@string/nominated_for_deletion"
|
||||||
android:textColor="@color/primaryTextColor"
|
android:textColor="@color/primaryTextColor"
|
||||||
android:textSize="@dimen/normal_text"
|
android:textSize="@dimen/normal_text"
|
||||||
android:textStyle="bold"/>
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/seeMore"
|
android:id="@+id/seeMore"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:paddingTop="@dimen/standard_gap"
|
android:paddingTop="@dimen/standard_gap"
|
||||||
android:textColor="@color/primaryTextColor"
|
android:textColor="@color/primaryTextColor"
|
||||||
android:textSize="@dimen/normal_text"
|
android:textSize="@dimen/normal_text"
|
||||||
android:textStyle="bold"/>
|
android:textStyle="bold"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
style="@style/MediaDetailContainer"
|
style="@style/MediaDetailContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextLabelGeneric"
|
style="@style/MediaDetailTextLabelGeneric"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="@string/media_detail_discussion" />
|
android:text="@string/media_detail_discussion" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/MediaDetailTextBody"
|
style="@style/MediaDetailTextBody"
|
||||||
android:id="@+id/mediaDetailDisc"
|
android:id="@+id/mediaDetailDisc"
|
||||||
android:layout_width="@dimen/widget_margin"
|
android:layout_width="@dimen/widget_margin"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/copyWikicode"
|
android:id="@+id/copyWikicode"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/standard_gap"
|
android:layout_margin="@dimen/standard_gap"
|
||||||
android:background="@drawable/bg_copy_wikitext_button"
|
android:background="@drawable/bg_copy_wikitext_button"
|
||||||
android:text="@string/copy_wikicode"
|
android:text="@string/copy_wikicode"
|
||||||
android:textColor="@color/primaryTextColor" />
|
android:textColor="@color/primaryTextColor" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/nominateDeletion"
|
android:id="@+id/nominateDeletion"
|
||||||
android:background="@drawable/bg_delete_button"
|
android:background="@drawable/bg_delete_button"
|
||||||
android:textColor="@color/primaryTextColor"
|
android:textColor="@color/primaryTextColor"
|
||||||
android:layout_margin="@dimen/standard_gap"
|
android:layout_margin="@dimen/standard_gap"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/nominate_deletion"/>
|
android:text="@string/nominate_deletion"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
<!-- I have done this intentionally, the mapview because of some elevation or something,
|
<!-- I have done this intentionally, the mapview because of some elevation or something,
|
||||||
sometimes hangs over the drawer layout and sometimes draws its onPaused state over the contributions, this seems to be the probable fix -->
|
sometimes hangs over the drawer layout and sometimes draws its onPaused state over the contributions, this seems to be the probable fix -->
|
||||||
<FrameLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_below="@id/nearby_filter">
|
android:layout_below="@id/nearby_filter">
|
||||||
|
|
@ -40,7 +40,19 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@android:color/transparent" />
|
android:background="@android:color/transparent" />
|
||||||
|
|
||||||
</FrameLayout>
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/tv_attribution"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:text="@string/map_attribution"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="10sp" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|
|
||||||
|
|
@ -1,139 +1,139 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.github.chrisbanes.photoview.PhotoView
|
<com.github.chrisbanes.photoview.PhotoView
|
||||||
android:id="@+id/backgroundImage"
|
android:id="@+id/backgroundImage"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:actualImageScaleType="fitXY" />
|
app:actualImageScaleType="fitXY" />
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<androidx.cardview.widget.CardView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_margin="@dimen/dimen_10"
|
android:layout_margin="@dimen/dimen_10"
|
||||||
android:elevation="@dimen/cardview_default_elevation">
|
android:elevation="@dimen/cardview_default_elevation">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_margin="@dimen/dimen_10"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/rl_container_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/half_standard_height"
|
||||||
|
android:layout_marginEnd="@dimen/standard_gap"
|
||||||
|
android:layout_marginRight="@dimen/standard_gap"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textSize="@dimen/normal_text"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="Step 1 of 15" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/ib_map"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginEnd="@dimen/standard_gap"
|
||||||
|
android:layout_marginRight="@dimen/standard_gap"
|
||||||
|
android:layout_toLeftOf="@id/ib_expand_collapse"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:srcCompat="@drawable/ic_map_white_24dp"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/ib_expand_collapse"
|
||||||
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
|
android:layout_width="@dimen/half_standard_height"
|
||||||
|
android:layout_height="@dimen/half_standard_height"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_marginStart="@dimen/small_gap"
|
||||||
|
android:layout_marginEnd="@dimen/small_gap"
|
||||||
|
android:layout_marginBottom="@dimen/small_gap"
|
||||||
|
android:clickable="false"
|
||||||
|
android:focusable="false"
|
||||||
|
android:padding="@dimen/medium_height"
|
||||||
|
app:srcCompat="@drawable/ic_expand_less_black_24dp" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/ll_container_media_detail"
|
||||||
android:layout_height="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_margin="@dimen/dimen_10"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:layout_marginTop="@dimen/standard_gap"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<fr.free.nrw.commons.widget.HeightLimitedRecyclerView
|
||||||
|
android:id="@+id/rv_descriptions"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
||||||
|
android:layout_marginBottom="@dimen/activity_margin_horizontal"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/btn_copy_prev_title_desc"
|
||||||
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/previous_image_caption_description"
|
||||||
|
android:padding="@dimen/miniscule_margin"
|
||||||
|
android:textAlignment="textEnd"
|
||||||
|
android:textColor="@color/button_blue"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/rl_container_title"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="wrap_content">
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tv_title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="@dimen/half_standard_height"
|
|
||||||
android:layout_marginEnd="@dimen/standard_gap"
|
|
||||||
android:layout_marginRight="@dimen/standard_gap"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:textSize="@dimen/normal_text"
|
|
||||||
android:textStyle="bold"
|
|
||||||
tools:text="Step 1 of 15" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageButton
|
|
||||||
android:id="@+id/ib_map"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginEnd="@dimen/standard_gap"
|
|
||||||
android:layout_marginRight="@dimen/standard_gap"
|
|
||||||
android:layout_toLeftOf="@id/ib_expand_collapse"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:srcCompat="@drawable/ic_map_white_24dp"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageButton
|
|
||||||
android:id="@+id/ib_expand_collapse"
|
|
||||||
style="@style/Widget.AppCompat.Button.Borderless"
|
|
||||||
android:layout_width="@dimen/half_standard_height"
|
|
||||||
android:layout_height="@dimen/half_standard_height"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_marginStart="@dimen/small_gap"
|
|
||||||
android:layout_marginEnd="@dimen/small_gap"
|
|
||||||
android:layout_marginBottom="@dimen/small_gap"
|
|
||||||
android:clickable="false"
|
|
||||||
android:focusable="false"
|
|
||||||
android:padding="@dimen/medium_height"
|
|
||||||
app:srcCompat="@drawable/ic_expand_less_black_24dp" />
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/ll_container_media_detail"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="@dimen/standard_gap"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<fr.free.nrw.commons.widget.HeightLimitedRecyclerView
|
|
||||||
android:id="@+id/rv_descriptions"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginBottom="@dimen/activity_margin_horizontal"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatButton
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:id="@+id/btn_copy_prev_title_desc"
|
android:id="@+id/btn_add_description"
|
||||||
style="@style/Widget.AppCompat.Button.Borderless"
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/previous_image_caption_description"
|
android:minWidth="@dimen/fragment_height"
|
||||||
android:padding="@dimen/miniscule_margin"
|
android:text="+" />
|
||||||
android:textAlignment="textEnd"
|
|
||||||
android:textColor="@color/button_blue"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<RelativeLayout
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/btn_next"
|
||||||
android:layout_height="wrap_content">
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:enabled="false"
|
||||||
|
android:alpha=".5"
|
||||||
|
android:text="@string/next"
|
||||||
|
android:textColor="@android:color/white" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatButton
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:id="@+id/btn_add_description"
|
android:id="@+id/btn_previous"
|
||||||
style="@style/Widget.AppCompat.Button.Borderless"
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minWidth="@dimen/fragment_height"
|
android:layout_marginEnd="@dimen/standard_gap"
|
||||||
android:text="+" />
|
android:layout_marginRight="@dimen/standard_gap"
|
||||||
|
android:layout_toLeftOf="@+id/btn_next"
|
||||||
|
android:text="@string/previous" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatButton
|
</RelativeLayout>
|
||||||
android:id="@+id/btn_next"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:enabled="false"
|
|
||||||
android:alpha=".5"
|
|
||||||
android:text="@string/next"
|
|
||||||
android:textColor="@android:color/white" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatButton
|
|
||||||
android:id="@+id/btn_previous"
|
|
||||||
style="@style/Widget.AppCompat.Button.Borderless"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="@dimen/standard_gap"
|
|
||||||
android:layout_marginRight="@dimen/standard_gap"
|
|
||||||
android:layout_toLeftOf="@+id/btn_next"
|
|
||||||
android:text="@string/previous" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
|
||||||
|
|
@ -689,4 +689,7 @@ Upload your first media by tapping on the add button.</string>
|
||||||
<string name="leaderboard_nearby">Nearby</string>
|
<string name="leaderboard_nearby">Nearby</string>
|
||||||
<string name="leaderboard_used">Used</string>
|
<string name="leaderboard_used">Used</string>
|
||||||
<string name="leaderboard_my_rank_button_text">My Rank</string>
|
<string name="leaderboard_my_rank_button_text">My Rank</string>
|
||||||
|
<string name="mapbox_telemetry">Telemetry Opt Out</string>
|
||||||
|
<string name="telemetry_opt_out_summary">Send anonymized location and usage data to Mapbox when using Nearby feature</string>
|
||||||
|
<string name="map_attribution" translatable="false"><![CDATA[© <a href="https://www.mapbox.com/about/maps/">Mapbox</a> © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> <a href="https://www.mapbox.com/map-feedback/">Improve this map</a>]]></string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,13 @@
|
||||||
android:summary="@string/manage_exif_tags_summary"
|
android:summary="@string/manage_exif_tags_summary"
|
||||||
android:title="@string/manage_exif_tags" />
|
android:title="@string/manage_exif_tags" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:key="telemetryOptOut"
|
||||||
|
app:singleLineTitle="false"
|
||||||
|
android:summary="@string/telemetry_opt_out_summary"
|
||||||
|
android:title="@string/mapbox_telemetry" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<!-- The key 'allowGps' was used before and has since been removed based on the discussion at #1599.
|
<!-- The key 'allowGps' was used before and has since been removed based on the discussion at #1599.
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ class CategoryClientTest {
|
||||||
.test()
|
.test()
|
||||||
.assertValues(emptyList())
|
.assertValues(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun searchCategoriesForPrefixFound() {
|
fun searchCategoriesForPrefixFound() {
|
||||||
val mockResponse = withMockResponse("Category:Test")
|
val mockResponse = withMockResponse("Category:Test")
|
||||||
|
|
@ -78,7 +77,6 @@ class CategoryClientTest {
|
||||||
.test()
|
.test()
|
||||||
.assertValues(emptyList())
|
.assertValues(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getParentCategoryListFound() {
|
fun getParentCategoryListFound() {
|
||||||
val mockResponse = withMockResponse("Category:Test")
|
val mockResponse = withMockResponse("Category:Test")
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,6 @@ class UploadMediaPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun handleBadImageBaseTestInvalidLocation() {
|
fun handleBadImageBaseTestInvalidLocation() {
|
||||||
uploadMediaPresenter.handleBadImage(8, uploadItem)
|
uploadMediaPresenter.handleBadImage(8, uploadItem)
|
||||||
verify(jsonKvStore).putBoolean(ArgumentMatchers.anyString(), eq(false))
|
|
||||||
verify(view).showBadImagePopup(8, uploadItem)
|
verify(view).showBadImagePopup(8, uploadItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,7 @@ class WikidataEditServiceTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun noClaimsWhenLocationIsNotCorrect() {
|
fun noClaimsWhenEntityIdIsNull() {
|
||||||
whenever(directKvStore.getBoolean("Picture_Has_Correct_Location", true))
|
|
||||||
.thenReturn(false)
|
|
||||||
wikidataEditService.createClaim(mock(), "Test.jpg", hashMapOf())
|
wikidataEditService.createClaim(mock(), "Test.jpg", hashMapOf())
|
||||||
verifyZeroInteractions(wikidataClient)
|
verifyZeroInteractions(wikidataClient)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ CORE_KTX_VERSION=1.2.0
|
||||||
ADAPTER_DELEGATES_VERSION=4.3.0
|
ADAPTER_DELEGATES_VERSION=4.3.0
|
||||||
PAGING_VERSION=2.1.2
|
PAGING_VERSION=2.1.2
|
||||||
MULTIDEX_VERSION=2.0.1
|
MULTIDEX_VERSION=2.0.1
|
||||||
|
OKHTTP_VERSION=3.12.1
|
||||||
|
|
||||||
systemProp.http.proxyPort=0
|
systemProp.http.proxyPort=0
|
||||||
systemProp.http.proxyHost=
|
systemProp.http.proxyHost=
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue