Skip to content

Commit 6eaac1d

Browse files
author
Vivek Maskara
authored
Merge branch 'master' into notificationFixes
2 parents 365bbc4 + 24641b5 commit 6eaac1d

File tree

80 files changed

+2620
-550
lines changed

Some content is hidden

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

80 files changed

+2620
-550
lines changed

app/build.gradle

+10-23
Original file line numberDiff line numberDiff line change
@@ -39,29 +39,10 @@ dependencies {
3939
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
4040
// Because RxAndroid releases are few and far between, it is recommended you also
4141
// explicitly depend on RxJava's latest version for bug fixes and new features.
42-
compile 'io.reactivex.rxjava2:rxjava:2.1.2'
43-
compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
44-
compile 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0'
45-
compile 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.0.0'
46-
compile 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0'
42+
implementation 'com.android.support:multidex:1.0.3'
4743

48-
compile 'com.facebook.fresco:fresco:1.3.0'
49-
compile 'com.facebook.stetho:stetho:1.5.0'
44+
testImplementation "org.robolectric:multidex:3.4.2"
5045

51-
compile 'com.android.support:multidex:1.0.3'
52-
53-
testCompile 'junit:junit:4.12'
54-
testCompile 'org.robolectric:robolectric:3.7.1'
55-
testCompile "org.robolectric:multidex:3.4.2"
56-
57-
testCompile 'com.squareup.okhttp3:mockwebserver:3.8.1'
58-
androidTestCompile 'com.squareup.okhttp3:mockwebserver:3.8.1'
59-
androidTestCompile "com.android.support:support-annotations:${project.SUPPORT_LIB_VERSION}"
60-
androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.1'
61-
62-
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'
63-
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
64-
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
6546
implementation 'io.reactivex.rxjava2:rxjava:2.1.2'
6647
implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
6748
implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0'
@@ -98,8 +79,8 @@ dependencies {
9879
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
9980
kapt "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"
10081

101-
compile 'com.borjabravo:readmoretextview:2.1.0'
102-
compile 'com.android.support.constraint:constraint-layout:1.0.2'
82+
implementation 'com.borjabravo:readmoretextview:2.1.0'
83+
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
10384
}
10485

10586
android {
@@ -122,6 +103,12 @@ android {
122103
multiDexEnabled true
123104
}
124105

106+
testOptions {
107+
unitTests.all {
108+
jvmArgs '-noverify'
109+
}
110+
}
111+
125112
sourceSets {
126113
// use kotlin only in tests (for now)
127114
test.java.srcDirs += 'src/test/kotlin'

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

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

33
import android.annotation.SuppressLint;
4+
import android.app.AlertDialog;
5+
import android.content.DialogInterface;
46
import android.content.Intent;
57
import android.net.Uri;
68
import android.os.Bundle;
@@ -10,6 +12,9 @@
1012
import android.support.customtabs.CustomTabsIntent;
1113
import android.support.v4.content.ContextCompat;
1214
import android.view.View;
15+
import android.widget.ArrayAdapter;
16+
import android.widget.LinearLayout;
17+
import android.widget.Spinner;
1318
import android.widget.TextView;
1419
import android.widget.Toast;
1520

@@ -29,6 +34,16 @@ public class AboutActivity extends NavigationBaseActivity {
2934
@BindView(R.id.about_license) HtmlTextView aboutLicenseText;
3035
@BindView(R.id.about_faq) TextView faqText;
3136

37+
String language[] = { "Kazakh", "Afrikaans", "Arabic", "Bengali", "Asturianu", "azərbaycanca", "Bikol Central",
38+
"Bulgarain", "বাংলা", "Bosanski", "Brezhoneg","català","کوردی", " čeština", " kaszëbsczi", "Cymraeg", "dansk", "Deutsch"
39+
,"Zazaki", "डोटेली","Ελληνικά","euskara","español","فارسی","suomi", "français" ,"Nordfriisk", "galego", "Hawaiʻi"
40+
,"हिन्दी","Hunsrik","עברית","hornjoserbsce","magyar","interlingua","Bahasa Indonesia", "íslenska","Italian","japanese",
41+
"Basa Jawa", "ქართული", " ភាសាខ្មែរ","ಕನ್ನಡ", "한국어","къарачай-малкъар","Кыргызча", "latina", "Lëtzebuergesch", "lietuvių",
42+
"latviešu", "Malagasy", "македонски"," മലയാളം","монгол","मराठी","Bahasa Melayu","Malti", "नेपाली", "norsk bokmål",
43+
" Nederlands","occitan","ଓଡ଼ିଆ","ਪੰਜਾਬੀ","polsk","Piemontèis","پښتو","português","română","русский"," سنڌي", " සිංහල",
44+
"slovenčina"," سرائیکی", "svenska", "தமிழ்", "ತುಳು"," తెలుగు"," ไทย", "Türkçe","українська", "اردو", "Tiếng Việt",
45+
" მარგალური","ייִדיש",};
46+
3247
/**
3348
* This method helps in the creation About screen
3449
*
@@ -87,8 +102,43 @@ public void launchPrivacyPolicy(View view) {
87102
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\\"));
88103
}
89104

105+
90106
@OnClick(R.id.about_faq)
91107
public void launchFrequentlyAskedQuesions(View view) {
92108
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons/wiki/Frequently-Asked-Questions\\"));
93109
}
110+
111+
@OnClick(R.id.about_translate)
112+
public void launchTranslate(View view) {
113+
final ArrayAdapter<String> languageAdapter = new ArrayAdapter<String>(AboutActivity.this,
114+
android.R.layout.simple_spinner_item, language);
115+
final Spinner spinner = new Spinner(AboutActivity.this);
116+
spinner.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
117+
spinner.setAdapter(languageAdapter);
118+
spinner.setGravity(17);
119+
120+
AlertDialog.Builder builder = new AlertDialog.Builder(AboutActivity.this);
121+
builder.setView(spinner);
122+
builder.setTitle(R.string.about_translate_title)
123+
.setMessage(R.string.about_translate_message)
124+
.setPositiveButton(R.string.about_translate_proceed, new DialogInterface.OnClickListener() {
125+
@Override
126+
public void onClick(DialogInterface dialog, int which) {
127+
String languageSelected = spinner.getSelectedItem().toString();
128+
TokensTranslations tokensTranslations = new TokensTranslations();
129+
tokensTranslations.initailize();
130+
String token = tokensTranslations.getTranslationToken(languageSelected);
131+
Utils.handleWebUrl(AboutActivity.this,Uri.parse("https://translatewiki.net/w/i.php?title=Special:Translate&language="+token+"&group=commons-android-strings&filter=%21translated&action=translate ?"));
132+
}
133+
});
134+
builder.setNegativeButton(R.string.about_translate_cancel, new DialogInterface.OnClickListener() {
135+
@Override
136+
public void onClick(DialogInterface dialog, int which) {
137+
finish();
138+
}
139+
});
140+
builder.create().show();
141+
142+
}
143+
94144
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package fr.free.nrw.commons;
2+
3+
import java.util.HashMap;
4+
5+
/**
6+
* Created by Dell on 3/16/2018.
7+
*/
8+
9+
public class TokensTranslations {
10+
HashMap<String,String> translationToken = new HashMap<String,String>();
11+
12+
public void initailize() {
13+
translationToken.put("Kazakh", "ab");
14+
translationToken.put("Afrikaans", "af");
15+
translationToken.put("Arabic", "ar");
16+
translationToken.put("Bengali", "as");
17+
translationToken.put("Asturianu", "ast");
18+
translationToken.put("azərbaycanca", "az");
19+
translationToken.put("Bikol Central", "bcl");
20+
translationToken.put("Bulgarain","bg");
21+
translationToken.put("বাংলা", "bn");
22+
translationToken.put("Brezhoneg", "br");
23+
translationToken.put("Bosanski", "bs");
24+
translationToken.put("català", "ca");
25+
translationToken.put("کوردی","ckb");
26+
translationToken.put("čeština", "cs");
27+
translationToken.put("kaszëbsczi", "csb");
28+
translationToken.put("Cymraeg", "cy");
29+
translationToken.put("dansk", "da");
30+
translationToken.put("Deutsch", "de");
31+
translationToken.put("Zazaki", "diq");
32+
translationToken.put("डोटेली","diq");
33+
translationToken.put("Ελληνικά","el");
34+
translationToken.put("euskara","eu");
35+
translationToken.put("español", "es");
36+
translationToken.put("فارسی","fa");
37+
translationToken.put("suomi", "fi");
38+
translationToken.put("føroyskt", "fo");
39+
translationToken.put("français", "fr");
40+
translationToken.put("Nordfriisk", "frr");
41+
translationToken.put("galego", "gr");
42+
translationToken.put("Hawaiʻi", "haw");
43+
translationToken.put("עברית","he");
44+
translationToken.put("हिन्दी","hi");
45+
translationToken.put("Hunsrik", "hrx");
46+
translationToken.put("hornjoserbsce", "hsb");
47+
translationToken.put("magyar","hu");
48+
translationToken.put("interlingua","ia");
49+
translationToken.put("Bahasa Indonesia", "id");
50+
translationToken.put("íslenska","is");
51+
translationToken.put("Italian","it");
52+
translationToken.put("japanese","ja");
53+
translationToken.put("Basa Jawa","jv");
54+
translationToken.put("ქართული", "ka");
55+
translationToken.put("Taqbaylit","kab");
56+
translationToken.put(" ភាសាខ្មែរ","km");
57+
translationToken.put("ಕನ್ನಡ", "kn");
58+
translationToken.put("한국어", "ko");
59+
translationToken.put("къарачай-малкъар","krc");
60+
translationToken.put("Кыргызча","ky");
61+
translationToken.put("latina","la");
62+
translationToken.put("Lëtzebuergesch","lb");
63+
translationToken.put("lietuvių", "lt");
64+
translationToken.put("latviešu","lv");
65+
translationToken.put("Malagasy","mg");
66+
translationToken.put("македонски", "mk");
67+
translationToken.put("മലയാളം","ml");
68+
translationToken.put("монгол","mn");
69+
translationToken.put("मराठी","mr");
70+
translationToken.put("Bahasa Melayu","ms");
71+
translationToken.put("Malti","mt");
72+
translationToken.put("norsk bokmål", "nb");
73+
translationToken.put("नेपाली","ne");
74+
translationToken.put("Nederlands","nl");
75+
translationToken.put("occitan","oc");
76+
translationToken.put("ଓଡ଼ିଆ","or");
77+
translationToken.put("ਪੰਜਾਬੀ","pa");
78+
translationToken.put("polsk", "pl");
79+
translationToken.put("Piemontèis","pms");
80+
translationToken.put("پښتو","ps");
81+
translationToken.put("português","pt");
82+
translationToken.put("română","ro");
83+
translationToken.put("русский","ru");
84+
translationToken.put(" سنڌي","sd");
85+
translationToken.put(" සිංහල","si");
86+
translationToken.put("slovenčina","sk");
87+
translationToken.put(" سرائیکی","skr");
88+
translationToken.put("Basa Sunda","su");
89+
translationToken.put("svenska","sv");
90+
translationToken.put("தமிழ்", "ta");
91+
translationToken.put("ತುಳು", "tcy");
92+
translationToken.put(" తెలుగు","te");
93+
translationToken.put(" ไทย","th");
94+
translationToken.put("Türkçe","tr");
95+
translationToken.put("українська","uk");
96+
translationToken.put("اردو","ur");
97+
translationToken.put("Tiếng Việt","vi");
98+
translationToken.put(" მარგალური", "xmf");
99+
translationToken.put("ייִדיש","yi");
100+
}
101+
102+
public String getTranslationToken ( String language){
103+
return translationToken.get(language);
104+
}
105+
}

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

+33-5
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,16 @@ public class CategorizationFragment extends CommonsDaggerSupportFragment {
7373

7474
@Inject MediaWikiApi mwApi;
7575
@Inject @Named("default_preferences") SharedPreferences prefs;
76+
@Inject @Named("prefs") SharedPreferences prefsPrefs;
77+
@Inject @Named("direct_nearby_upload_prefs") SharedPreferences directPrefs;
7678
@Inject CategoryDao categoryDao;
7779

7880
private RVRendererAdapter<CategoryItem> categoriesAdapter;
7981
private OnCategoriesSaveHandler onCategoriesSaveHandler;
8082
private HashMap<String, ArrayList<String>> categoriesCache;
8183
private List<CategoryItem> selectedCategories = new ArrayList<>();
8284
private TitleTextWatcher textWatcher = new TitleTextWatcher();
85+
private boolean hasDirectCategories = false;
8386

8487
private final CategoriesAdapterFactory adapterFactory = new CategoriesAdapterFactory(item -> {
8588
if (item.isSelected()) {
@@ -128,7 +131,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
128131
}
129132

130133
public void hideKeyboard(View view) {
131-
InputMethodManager inputMethodManager =(InputMethodManager)getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
134+
InputMethodManager inputMethodManager = (InputMethodManager) getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
132135
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
133136
}
134137

@@ -223,7 +226,7 @@ private void updateCategoryList(String filter) {
223226
.observeOn(AndroidSchedulers.mainThread())
224227
.subscribe(
225228
s -> categoriesAdapter.add(s),
226-
Timber::e,
229+
Timber::e,
227230
() -> {
228231
categoriesAdapter.notifyDataSetChanged();
229232
categoriesSearchInProgress.setVisibility(View.GONE);
@@ -258,9 +261,34 @@ private List<String> getStringList(List<CategoryItem> input) {
258261
}
259262

260263
private Observable<CategoryItem> defaultCategories() {
261-
return gpsCategories()
262-
.concatWith(titleCategories())
263-
.concatWith(recentCategories());
264+
265+
Observable<CategoryItem> directCat = directCategories();
266+
if (hasDirectCategories) {
267+
Timber.d("Image has direct Cat");
268+
return directCat
269+
.concatWith(gpsCategories())
270+
.concatWith(titleCategories())
271+
.concatWith(recentCategories());
272+
}
273+
else {
274+
Timber.d("Image has no direct Cat");
275+
return gpsCategories()
276+
.concatWith(titleCategories())
277+
.concatWith(recentCategories());
278+
}
279+
}
280+
281+
private Observable<CategoryItem> directCategories() {
282+
String directCategory = directPrefs.getString("Category", "");
283+
List<String> categoryList = new ArrayList<>();
284+
Timber.d("Direct category found: " + directCategory);
285+
286+
if (!directCategory.equals("")) {
287+
hasDirectCategories = true;
288+
categoryList.add(directCategory);
289+
Timber.d("DirectCat does not equal emptyString. Direct Cat list has " + categoryList);
290+
}
291+
return Observable.fromIterable(categoryList).map(name -> new CategoryItem(name, false));
264292
}
265293

266294
private Observable<CategoryItem> gpsCategories() {

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

+22-5
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@
2525
import static fr.free.nrw.commons.contributions.Contribution.SOURCE_GALLERY;
2626
import static fr.free.nrw.commons.upload.UploadService.EXTRA_SOURCE;
2727

28-
class ContributionController {
28+
public class ContributionController {
2929

3030
private static final int SELECT_FROM_GALLERY = 1;
3131
private static final int SELECT_FROM_CAMERA = 2;
3232

3333
private Fragment fragment;
3434

35-
ContributionController(Fragment fragment) {
35+
public ContributionController(Fragment fragment) {
3636
this.fragment = fragment;
3737
}
3838

@@ -61,7 +61,7 @@ private static void requestWritePermission(Context context, Intent intent, Uri u
6161
}
6262
}
6363

64-
void startCameraCapture() {
64+
public void startCameraCapture() {
6565

6666
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
6767
lastGeneratedCaptureUri = reGenerateImageCaptureUriInCache();
@@ -70,18 +70,29 @@ void startCameraCapture() {
7070
requestWritePermission(fragment.getContext(), takePictureIntent, lastGeneratedCaptureUri);
7171

7272
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, lastGeneratedCaptureUri);
73+
if (!fragment.isAdded()) {
74+
return;
75+
}
7376
fragment.startActivityForResult(takePictureIntent, SELECT_FROM_CAMERA);
7477
}
7578

7679
public void startGalleryPick() {
7780
//FIXME: Starts gallery (opens Google Photos)
7881
Intent pickImageIntent = new Intent(ACTION_GET_CONTENT);
7982
pickImageIntent.setType("image/*");
83+
// See https://stackoverflow.com/questions/22366596/android-illegalstateexception-fragment-not-attached-to-activity-webview
84+
if (!fragment.isAdded()) {
85+
Timber.d("Fragment is not added, startActivityForResult cannot be called");
86+
return;
87+
}
88+
Timber.d("startGalleryPick() called with pickImageIntent");
89+
8090
fragment.startActivityForResult(pickImageIntent, SELECT_FROM_GALLERY);
8191
}
8292

83-
void handleImagePicked(int requestCode, Intent data) {
93+
public void handleImagePicked(int requestCode, Intent data, boolean isDirectUpload) {
8494
FragmentActivity activity = fragment.getActivity();
95+
Timber.d("handleImagePicked() called with onActivityResult()");
8596
Intent shareIntent = new Intent(activity, ShareActivity.class);
8697
shareIntent.setAction(ACTION_SEND);
8798
switch (requestCode) {
@@ -91,6 +102,9 @@ void handleImagePicked(int requestCode, Intent data) {
91102
shareIntent.setType(activity.getContentResolver().getType(imageData));
92103
shareIntent.putExtra(EXTRA_STREAM, imageData);
93104
shareIntent.putExtra(EXTRA_SOURCE, SOURCE_GALLERY);
105+
if (isDirectUpload) {
106+
shareIntent.putExtra("isDirectUpload", true);
107+
}
94108
break;
95109
case SELECT_FROM_CAMERA:
96110
//FIXME: Find out appropriate mime type
@@ -99,6 +113,10 @@ void handleImagePicked(int requestCode, Intent data) {
99113
shareIntent.setType("image/jpeg");
100114
shareIntent.putExtra(EXTRA_STREAM, lastGeneratedCaptureUri);
101115
shareIntent.putExtra(EXTRA_SOURCE, SOURCE_CAMERA);
116+
if (isDirectUpload) {
117+
shareIntent.putExtra("isDirectUpload", true);
118+
}
119+
102120
break;
103121
default:
104122
break;
@@ -122,5 +140,4 @@ void loadState(Bundle savedInstanceState) {
122140
lastGeneratedCaptureUri = savedInstanceState.getParcelable("lastGeneratedCaptureURI");
123141
}
124142
}
125-
126143
}

0 commit comments

Comments
 (0)