Skip to content

Commit 2704c9e

Browse files
maskaravivekmisaochan
authored andcommitted
Multiple uploads with over haul (#1968)
* Added new upload activity that receives shared files from the gallery. Cards show and hide, plus titles are correct. Displayed thumbnails for the shared images * Better handling of the view paging plus error handling for required fields. * Code cleanup to make things more readable. * Extracted a model from the category search fragment that can possibly be shared with the new upload activity. * Added category selection to the combined upload screen. * Cleanup before the home-stretch on the GUI. * Adding license selection. * Fixed build warnings + cleanup * Start to support the dark theme. * Work in progress to add quality checking. * Fixing merge. * GPSExtractor: optimized away the EXifInterface object * Implemented submit functionality, temporarily fixed jacoco crash by disabling DUMMY UploadView object. * Implemented uploading of categories along with the picture. The category screen now displays GPS and recent categories when nothing is searched. * Implemented caching of files. Did some work on picture quality detection. * Implemented too dark picture detection. * Added a side card for zoom and map buttons along with pretty animations for stuff. * Added duplicate image on commons checking and fixed files not getting proper file extensions in several places. * Added support for map button and switched in-app upload buttons to UploadActivity * Pretty pretty animations! * Implemented zoom functionality for th background image. Just pinching on the image works instead of requiring buttons. * Added multi-language descriptions with categories by region. * Reimplemented the duplicate title checker and implemented a check against putting the same language twice in the description. * Javadocs for Description and UploadPresenter, plus some general cleanup. * Small code changes. * Implemented login checks for the Upload screen. * Implement receiving data from Nearby. * Feature/permissions library (#1855) * Added permission for Dexter, the runtime permission handling library * [Preparing fir issue #1773] Added a utility function which would take the user to app settings screen where he could manually give us the required permission * Added an alert dialog with positive and negative callback [Preparing fir issue #1773] * Improvements in the way External Storage Permission is handled in MultipleShareActivity[Bug fix #1697] 1. Used dexter to handle the external storage permission 2. Behaviour changes : When user tries to share(uppload) images to commons via MultipleShareActivity, following decision tree is followed a. If the app has permission for external storage, normal upload operation is followed b. If the app does not has the permission for external storage, dexter is used to ask for the same c. If the user gives us the required permission, normal upload flow is proceeded d. If the doesnot gives us the required permission a rationale dialog is shown with the appropriate message to let him know why we need the permission e. If he presses okay, steps a-c are followed and if he presses cancel, we close the app. f. If while asking for permission, the user chooses never ask again, then next time he tries to upload an image via MSA, the rational dialog follows the app setting screen where he could manually give us the required permission and the onActivityResult of same is handled * Added a Constants class to handle request and result codes from one place and other related constants common to the all app elements * replaced hardcoded strings ok and cancel in DialogUtil to string resources * init permission rationale dialog in activities onCreate * Code formatting, updated access modifiers wherever required, added javadocs for new methods created * *shifted constants to app class *Added JavaDocs in PermissionUtils * removed class REQUEST_CODES from CommonsApplication and instead put the enclosing constants in the App class itself * Made Codacy happy. * Abstarcted permission acquisition into new class DexterPermissionObtainer * Fixed Nearby upload detection * Migrated bad picture detection from AsyncTask to RxJava. * Removed ShareActivity and related dead code * Removed dead or duplicate code from FileProcessor * Added info button to title EditText * Fixed the add description button not disappearing. Added "Starting Upload" toast. Added link to the license on final screen. Made it so that the map button is hidden when image lacks gps coords. * Support in app multiple uploads * Minor changes to fix build * Changes to fix pending issues with upload flow * Fix display of similar image fragment * When uploading several files at once the date is missing #1854 (#2) * Bug fix issue #1854 * updated ContributionsDao to save create date, which it was not doing currently [it was instead saving current date] * UploadItem accepts are dateCreated param * Added a function in UploadModel, getFileCreatedDate which tries to fetched the file creaction date from all possible content providers. * Fix pending issues in upload flow * Make multiple uploads work for Google Photos * Fix default state for upload activity * Fix keyboard state for license screen * Fix descriptions for uploads * wip * Fix language spinner
1 parent ab401fd commit 2704c9e

File tree

139 files changed

+3996
-3196
lines changed

Some content is hidden

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

139 files changed

+3996
-3196
lines changed

app/build.gradle

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dependencies {
3232
transitive = true
3333
}
3434
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
35+
3536
//noinspection GradleCompatible
3637
implementation "com.android.support:support-v4:$SUPPORT_LIB_VERSION"
3738
implementation "com.android.support:appcompat-v7:$SUPPORT_LIB_VERSION"
@@ -44,6 +45,7 @@ dependencies {
4445
implementation 'com.squareup.okio:okio:1.14.0'
4546
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
4647
// Because RxAndroid releases are few and far between, it is recommended you also
48+
4749
// explicitly depend on RxJava's latest version for bug fixes and new features.
4850
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
4951
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
@@ -131,7 +133,7 @@ android {
131133
flavorDimensions 'tier'
132134
productFlavors {
133135
prod {
134-
136+
135137
applicationId 'fr.free.nrw.commons'
136138

137139
buildConfigField "String", "WIKIMEDIA_API_POTD", "\"https://commons.wikimedia.org/w/api.php?action=featuredfeed&feed=potd&feedformat=rss&language=en\""

app/src/androidTest/java/fr/free/nrw/commons/upload/FileUtilsTest.java

-30
This file was deleted.

app/src/main/AndroidManifest.xml

+9-19
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
1616
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
1717
<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS" />
18-
<uses-permission android:name="android.permission.READ_LOGS"/>
18+
<uses-permission android:name="android.permission.READ_LOGS" />
1919
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
2020

2121

@@ -41,42 +41,35 @@
4141
<action android:name="android.intent.action.MAIN" />
4242
</intent-filter>
4343
</activity>
44-
4544
<activity android:name=".WelcomeActivity" />
4645

47-
<activity
48-
android:name=".upload.ShareActivity"
46+
<activity android:name=".upload.UploadActivity"
4947
android:icon="@drawable/ic_launcher"
5048
android:label="@string/app_name">
5149
<intent-filter android:label="@string/intent_share_upload_label">
5250
<action android:name="android.intent.action.SEND" />
51+
5352
<category android:name="android.intent.category.DEFAULT" />
53+
5454
<data android:mimeType="image/*" />
5555
<data android:mimeType="audio/ogg" />
5656
</intent-filter>
57-
</activity>
58-
59-
<activity
60-
android:name=".upload.MultipleShareActivity"
61-
android:icon="@drawable/ic_launcher"
62-
android:label="@string/app_name">
63-
<intent-filter android:label="@string/intent_share_upload_label">
57+
<intent-filter>
6458
<action android:name="android.intent.action.SEND_MULTIPLE" />
59+
6560
<category android:name="android.intent.category.DEFAULT" />
61+
6662
<data android:mimeType="image/*" />
6763
<data android:mimeType="audio/ogg" />
6864
</intent-filter>
6965
</activity>
70-
7166
<activity
7267
android:name=".contributions.MainActivity"
7368
android:icon="@drawable/ic_launcher"
7469
android:label="@string/app_name" />
75-
7670
<activity
7771
android:name=".settings.SettingsActivity"
7872
android:label="@string/title_activity_settings" />
79-
8073
<activity
8174
android:name=".AboutActivity"
8275
android:label="@string/title_activity_about"
@@ -135,24 +128,24 @@
135128
android:name="android.accounts.AccountAuthenticator"
136129
android:resource="@xml/authenticator" />
137130
</service>
138-
139131
<service
140132
android:name=".contributions.ContributionsSyncService"
141133
android:exported="true">
142134
<intent-filter>
143135
<action android:name="android.content.SyncAdapter" />
144136
</intent-filter>
137+
145138
<meta-data
146139
android:name="android.content.SyncAdapter"
147140
android:resource="@xml/contributions_sync_adapter" />
148141
</service>
149-
150142
<service
151143
android:name=".modifications.ModificationsSyncService"
152144
android:exported="true">
153145
<intent-filter>
154146
<action android:name="android.content.SyncAdapter" />
155147
</intent-filter>
148+
156149
<meta-data
157150
android:name="android.content.SyncAdapter"
158151
android:resource="@xml/modifications_sync_adapter" />
@@ -172,21 +165,18 @@
172165
android:name="android.support.FILE_PROVIDER_PATHS"
173166
android:resource="@xml/provider_paths" />
174167
</provider>
175-
176168
<provider
177169
android:name=".contributions.ContributionsContentProvider"
178170
android:authorities="${applicationId}.contributions.contentprovider"
179171
android:exported="false"
180172
android:label="@string/provider_contributions"
181173
android:syncable="true" />
182-
183174
<provider
184175
android:name=".modifications.ModificationsContentProvider"
185176
android:authorities="${applicationId}.modifications.contentprovider"
186177
android:exported="false"
187178
android:label="@string/provider_modifications"
188179
android:syncable="true" />
189-
190180
<provider
191181
android:name=".category.CategoryContentProvider"
192182
android:authorities="${applicationId}.categories.contentprovider"

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

+50-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package fr.free.nrw.commons;
22

3+
import android.content.ActivityNotFoundException;
34
import android.content.Context;
45
import android.content.Intent;
56
import android.graphics.Bitmap;
@@ -14,12 +15,11 @@
1415
import org.apache.commons.codec.binary.Hex;
1516
import org.apache.commons.codec.digest.DigestUtils;
1617

17-
import java.io.BufferedReader;
18-
import java.io.IOException;
19-
import java.io.InputStreamReader;
2018
import java.io.UnsupportedEncodingException;
2119
import java.net.URLEncoder;
20+
import java.util.LinkedHashMap;
2221
import java.util.Locale;
22+
import java.util.Map;
2323
import java.util.regex.Matcher;
2424
import java.util.regex.Pattern;
2525

@@ -110,6 +110,31 @@ public static int licenseNameFor(String license) {
110110
throw new RuntimeException("Unrecognized license value: " + license);
111111
}
112112

113+
/**
114+
* Generates license url with given ID
115+
* @param license License ID
116+
* @return Url of license
117+
*/
118+
119+
120+
@NonNull
121+
public static String licenseUrlFor(String license) {
122+
switch (license) {
123+
case Prefs.Licenses.CC_BY_3:
124+
return "https://creativecommons.org/licenses/by/3.0/";
125+
case Prefs.Licenses.CC_BY_4:
126+
return "https://creativecommons.org/licenses/by/4.0/";
127+
case Prefs.Licenses.CC_BY_SA_3:
128+
return "https://creativecommons.org/licenses/by-sa/3.0/";
129+
case Prefs.Licenses.CC_BY_SA_4:
130+
return "https://creativecommons.org/licenses/by-sa/4.0/";
131+
case Prefs.Licenses.CC0:
132+
return "https://creativecommons.org/publicdomain/zero/1.0/";
133+
default:
134+
throw new RuntimeException("Unrecognized license value: " + license);
135+
}
136+
}
137+
113138
/**
114139
* Adds extension to filename. Converts to .jpg if system provides .jpeg, adds .jpg if no extension detected
115140
* @param title File name
@@ -176,6 +201,18 @@ public static void handleWebUrl(Context context, Uri url) {
176201
customTabsIntent.launchUrl(context, url);
177202
}
178203

204+
public static void handleGeoCoordinates(Context context, String coords) {
205+
try {
206+
Uri gmmIntentUri = Uri.parse("google.streetview:cbll=" + coords);
207+
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
208+
mapIntent.setPackage("com.google.android.apps.maps");
209+
context.startActivity(mapIntent);
210+
} catch (ActivityNotFoundException ex) {
211+
Toast toast = Toast.makeText(context, context.getString(R.string.map_application_missing), LENGTH_SHORT);
212+
toast.show();
213+
}
214+
}
215+
179216
/**
180217
* To take screenshot of the screen and return it in Bitmap format
181218
*
@@ -190,4 +227,14 @@ public static Bitmap getScreenShot(View view) {
190227
return bitmap;
191228
}
192229

230+
public static <K,V> Map<K,V> arraysToMap(K[] kArray, V[] vArray){
231+
if(kArray.length!=vArray.length)
232+
throw new RuntimeException("arraysToMap array sizes don't match");
233+
Map<K,V> map=new LinkedHashMap<>();
234+
for (int i=0;i<vArray.length;i++){
235+
map.put(kArray[i], vArray[i]);
236+
}
237+
return map;
238+
}
239+
193240
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
public abstract class AuthenticatedActivity extends NavigationBaseActivity {
1818

19-
@Inject SessionManager sessionManager;
19+
@Inject
20+
protected SessionManager sessionManager;
2021
@Inject
2122
MediaWikiApi mediaWikiApi;
2223
private String authCookie;
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
package fr.free.nrw.commons.category;
22

33
import com.pedrogomez.renderers.ListAdapteeCollection;
4-
import com.pedrogomez.renderers.RVRendererAdapter;
54
import com.pedrogomez.renderers.RendererBuilder;
65

76
import java.util.Collections;
87
import java.util.List;
98

10-
class CategoriesAdapterFactory {
11-
private final CategoriesRenderer.CategoryClickedListener listener;
9+
public class CategoriesAdapterFactory {
10+
private final CategoryClickedListener listener;
1211

13-
CategoriesAdapterFactory(CategoriesRenderer.CategoryClickedListener listener) {
12+
public CategoriesAdapterFactory(CategoryClickedListener listener) {
1413
this.listener = listener;
1514
}
1615

17-
public RVRendererAdapter<CategoryItem> create(List<CategoryItem> placeList) {
16+
public CategoryRendererAdapter create(List<CategoryItem> placeList) {
1817
RendererBuilder<CategoryItem> builder = new RendererBuilder<CategoryItem>()
1918
.bind(CategoryItem.class, new CategoriesRenderer(listener));
2019
ListAdapteeCollection<CategoryItem> collection = new ListAdapteeCollection<>(
2120
placeList != null ? placeList : Collections.<CategoryItem>emptyList());
22-
return new RVRendererAdapter<>(builder, collection);
21+
return new CategoryRendererAdapter(builder, collection);
2322
}
2423
}

0 commit comments

Comments
 (0)