Merge branch 'master' into master

This commit is contained in:
Hassan 2018-02-28 08:44:03 -06:00 committed by GitHub
commit e49f13ff74
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 1108 additions and 275 deletions

View file

@ -5,6 +5,8 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.support.customtabs.CustomTabsIntent;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
@ -57,23 +59,20 @@ public class AboutActivity extends NavigationBaseActivity {
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.facebook.com/" + "1921335171459985\\"));
//check if web browser available
if(intent.resolveActivity(this.getPackageManager()) != null){
startActivity(intent);
Utils.handleWebUrl(this,Uri.parse("https://www.facebook.com/" + "1921335171459985"));
} else {
Toast toast = Toast.makeText(this, getString(R.string.no_web_browser), LENGTH_SHORT);
toast.show();
}
}
}
@OnClick(R.id.github_launch_icon)
public void launchGithub(View view) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/commons-app/apps-android-commons\\"));
//check if web browser available
if (browserIntent.resolveActivity(this.getPackageManager()) != null) {
startActivity(browserIntent);
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons\\"));
} else {
Toast toast = Toast.makeText(this, getString(R.string.no_web_browser), LENGTH_SHORT);
toast.show();
@ -82,14 +81,40 @@ public class AboutActivity extends NavigationBaseActivity {
@OnClick(R.id.website_launch_icon)
public void launchWebsite(View view) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://commons-app.github.io/\\"));
//check if web browser available
if (browserIntent.resolveActivity(this.getPackageManager()) != null) {
startActivity(browserIntent);
Utils.handleWebUrl(this,Uri.parse("https://commons-app.github.io/\\"));
} else {
Toast toast = Toast.makeText(this, getString(R.string.no_web_browser), LENGTH_SHORT);
toast.show();
}
}
@OnClick(R.id.about_credits)
public void launchCredits(View view) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/commons-app/apps-android-commons/blob/master/CREDITS/\\"));
//check if web browser available
if (browserIntent.resolveActivity(this.getPackageManager()) != null) {
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons/blob/master/CREDITS/\\"));
} else {
Toast toast = Toast.makeText(this, getString(R.string.no_web_browser), LENGTH_SHORT);
toast.show();
}
}
@OnClick(R.id.about_privacy_policy)
public void launchPrivacyPolicy(View view) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\\"));
//check if web browser available
if (browserIntent.resolveActivity(this.getPackageManager()) != null) {
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\\"));
} else {
Toast toast = Toast.makeText(this, getString(R.string.no_web_browser), LENGTH_SHORT);
toast.show();
}
}
}

View file

@ -1,8 +1,12 @@
package fr.free.nrw.commons;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.customtabs.CustomTabsIntent;
import android.support.v4.content.ContextCompat;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
@ -11,6 +15,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Locale;
import java.util.regex.Matcher;
@ -159,4 +164,26 @@ public class Utils {
return stringBuilder.toString();
}
public static void rateApp(Context context) {
final String appPackageName = context.getPackageName();
try {
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
}
catch (android.content.ActivityNotFoundException anfe) {
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
return ;
}
public static void handleWebUrl(Context context,Uri url){
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
builder.setToolbarColor(ContextCompat.getColor(context, R.color.primaryColor));
builder.setSecondaryToolbarColor(ContextCompat.getColor(context, R.color.primaryDarkColor));
builder.setExitAnimations(context, android.R.anim.slide_in_left, android.R.anim.slide_out_right);
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
customTabsIntent.launchUrl(context, url);
}
}

View file

@ -4,6 +4,7 @@ import android.accounts.Account;
import android.accounts.AccountAuthenticatorActivity;
import android.accounts.AccountAuthenticatorResponse;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
@ -17,10 +18,12 @@ import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatDelegate;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
@ -69,6 +72,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
@BindView(R.id.loginTwoFactor) EditText twoFactorEdit;
@BindView(R.id.error_message_container) ViewGroup errorMessageContainer;
@BindView(R.id.error_message) TextView errorMessage;
@BindView(R.id.login_credentials) TextView loginCredentials;
@BindView(R.id.two_factor_container)TextInputLayout twoFactorContainer;
ProgressDialog progressDialog;
private AppCompatDelegate delegate;
@ -91,14 +95,39 @@ public class LoginActivity extends AccountAuthenticatorActivity {
ButterKnife.bind(this);
usernameEdit.addTextChangedListener(textWatcher);
usernameEdit.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
hideKeyboard(v);
}
});
passwordEdit.addTextChangedListener(textWatcher);
passwordEdit.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
hideKeyboard(v);
}
});
twoFactorEdit.addTextChangedListener(textWatcher);
passwordEdit.setOnEditorActionListener(newLoginInputActionListener());
loginButton.setOnClickListener(view -> performLogin());
signupButton.setOnClickListener(view -> signUp());
if(BuildConfig.FLAVOR == "beta"){
loginCredentials.setText(getString(R.string.login_credential));
} else {
loginCredentials.setVisibility(View.GONE);
}
}
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager =(InputMethodManager)this.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);

View file

@ -1,17 +1,23 @@
package fr.free.nrw.commons.category;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
@ -37,6 +43,7 @@ import fr.free.nrw.commons.R;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.upload.MwVolleyApi;
import fr.free.nrw.commons.upload.SingleUploadFragment;
import fr.free.nrw.commons.utils.StringSortingUtils;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -72,6 +79,7 @@ public class CategorizationFragment extends CommonsDaggerSupportFragment {
private OnCategoriesSaveHandler onCategoriesSaveHandler;
private HashMap<String, ArrayList<String>> categoriesCache;
private List<CategoryItem> selectedCategories = new ArrayList<>();
private TitleTextWatcher textWatcher = new TitleTextWatcher();
private final CategoriesAdapterFactory adapterFactory = new CategoriesAdapterFactory(item -> {
if (item.isSelected()) {
@ -102,6 +110,15 @@ public class CategorizationFragment extends CommonsDaggerSupportFragment {
categoriesAdapter = adapterFactory.create(items);
categoriesList.setAdapter(categoriesAdapter);
categoriesFilter.addTextChangedListener(textWatcher);
categoriesFilter.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
hideKeyboard(v);
}
});
RxTextView.textChanges(categoriesFilter)
.takeUntil(RxView.detaches(categoriesFilter))
.debounce(500, TimeUnit.MILLISECONDS)
@ -110,6 +127,18 @@ public class CategorizationFragment extends CommonsDaggerSupportFragment {
return rootView;
}
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager =(InputMethodManager)getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
@Override
public void onDestroyView() {
categoriesFilter.removeTextChangedListener(textWatcher);
super.onDestroyView();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
@ -351,4 +380,21 @@ public class CategorizationFragment extends CommonsDaggerSupportFragment {
.create()
.show();
}
private class TitleTextWatcher implements TextWatcher {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void afterTextChanged(Editable editable) {
if (getActivity() != null) {
getActivity().invalidateOptionsMenu();
}
}
}
}

View file

@ -276,7 +276,12 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
}
private void setOnClickListeners(final Media media) {
license.setOnClickListener(v -> openWebBrowser(licenseLink(media)));
if (licenseLink(media) != null) {
license.setOnClickListener(v -> openWebBrowser(licenseLink(media)));
} else {
Toast toast = Toast.makeText(getContext(), getString(R.string.null_url), Toast.LENGTH_SHORT);
toast.show();
}
if (media.getCoordinates() != null) {
coordinates.setOnClickListener(v -> openMap(media.getCoordinates()));
}

View file

@ -10,6 +10,7 @@ import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AlertDialog;
import android.view.Menu;
import android.view.MenuInflater;
@ -60,7 +61,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
private NearbyActivityMode viewMode;
private Disposable placesDisposable;
private boolean lockNearbyView; //Determines if the nearby places needs to be refreshed
@BindView(R.id.swipe_container) SwipeRefreshLayout swipeLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -70,6 +71,13 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
bundle = new Bundle();
initDrawer();
initViewState();
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
lockNearbyView(false);
refreshView(true);
}
});
}
private void initViewState() {
@ -309,7 +317,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
} else {
setListFragment();
}
swipeLayout.setRefreshing(false);
hideProgressBar();
}

View file

@ -3,7 +3,9 @@ package fr.free.nrw.commons.nearby;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.customtabs.CustomTabsIntent;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.PopupMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
@ -17,6 +19,7 @@ import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.ui.widget.OverlayDialog;
import fr.free.nrw.commons.utils.DialogUtil;
@ -141,8 +144,7 @@ public class NearbyInfoDialog extends OverlayDialog {
}
private void openWebView(Uri link) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, link);
startActivity(browserIntent);
Utils.handleWebUrl(getContext(),link);
}
@OnClick(R.id.emptyLayout)

View file

@ -5,12 +5,14 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;
import com.pedrogomez.renderers.RVRendererAdapter;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
@ -48,8 +50,9 @@ public class NotificationActivity extends NavigationBaseActivity {
}
private void initListView() {
recyclerView = findViewById(R.id.listView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
DividerItemDecoration itemDecor = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
recyclerView.addItemDecoration(itemDecor);
addNotifications();
}
@ -61,6 +64,7 @@ public class NotificationActivity extends NavigationBaseActivity {
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(notificationList -> {
Collections.reverse(notificationList);
Timber.d("Number of notifications is %d", notificationList.size());
setAdapter(notificationList);
}, throwable -> Timber.e(throwable, "Error occurred while loading notifications"));

View file

@ -5,6 +5,7 @@ import android.accounts.AccountManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
@ -22,6 +23,7 @@ import fr.free.nrw.commons.AboutActivity;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.WelcomeActivity;
import fr.free.nrw.commons.auth.AccountUtil;
import fr.free.nrw.commons.auth.LoginActivity;
@ -119,8 +121,9 @@ public abstract class NavigationBaseActivity extends BaseActivity
return true;
case R.id.action_feedback:
drawerLayout.closeDrawer(navigationView);
Intent feedbackIntent = new Intent(Intent.ACTION_SEND);
Intent feedbackIntent = new Intent(Intent.ACTION_SENDTO);
feedbackIntent.setType("message/rfc822");
feedbackIntent.setData(Uri.parse("mailto:"));
feedbackIntent.putExtra(Intent.EXTRA_EMAIL,
new String[]{CommonsApplication.FEEDBACK_EMAIL});
feedbackIntent.putExtra(Intent.EXTRA_SUBJECT,

View file

@ -1,5 +1,6 @@
package fr.free.nrw.commons.upload;
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.net.Uri;
@ -10,6 +11,7 @@ import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -177,9 +179,21 @@ public class MultipleUploadListFragment extends Fragment {
photosGrid.setColumnWidth(photoSize.x);
baseTitle.addTextChangedListener(textWatcher);
baseTitle.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
hideKeyboard(v);
}
});
return view;
}
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager =(InputMethodManager)getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
@Override
public void onDestroyView() {
baseTitle.removeTextChangedListener(textWatcher);

View file

@ -9,6 +9,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
@ -228,35 +229,40 @@ public class SingleUploadFragment extends CommonsDaggerSupportFragment {
*/
@OnTouch(R.id.titleEdit)
boolean titleInfo(View view, MotionEvent motionEvent) {
//Should replace right with end to support different right-to-left languages as well
final int value = titleEdit.getRight() - titleEdit.getCompoundDrawables()[2].getBounds().width();
if (motionEvent.getAction() == ACTION_UP && motionEvent.getRawX() >= value) {
new AlertDialog.Builder(getContext())
.setTitle(R.string.media_detail_title)
.setMessage(R.string.title_info)
.setCancelable(true)
.setNeutralButton(android.R.string.ok, (dialog, id) -> dialog.cancel())
.create()
.show();
return true;
final int value;
if (ViewCompat.getLayoutDirection(getView()) == ViewCompat.LAYOUT_DIRECTION_LTR) {
value = titleEdit.getRight() - titleEdit.getCompoundDrawables()[2].getBounds().width();
if (motionEvent.getAction() == ACTION_UP && motionEvent.getRawX() >= value) {
showInfoAlert(R.string.media_detail_title, R.string.title_info);
return true;
}
}
else {
value = titleEdit.getLeft() + titleEdit.getCompoundDrawables()[0].getBounds().width();
if (motionEvent.getAction() == ACTION_UP && motionEvent.getRawX() <= value) {
showInfoAlert(R.string.media_detail_title, R.string.title_info);
return true;
}
}
return false;
}
@OnTouch(R.id.descEdit)
boolean descriptionInfo(View view, MotionEvent motionEvent) {
final int value = descEdit.getRight() - descEdit.getCompoundDrawables()[2].getBounds().width();
if (motionEvent.getAction() == ACTION_UP && motionEvent.getRawX() >= value) {
new AlertDialog.Builder(getContext())
.setTitle(R.string.media_detail_description)
.setMessage(R.string.description_info)
.setCancelable(true)
.setNeutralButton(android.R.string.ok, (dialog, id) -> dialog.cancel())
.create()
.show();
return true;
final int value;
if (ViewCompat.getLayoutDirection(getView()) == ViewCompat.LAYOUT_DIRECTION_LTR) {
value = descEdit.getRight() - descEdit.getCompoundDrawables()[2].getBounds().width();
if (motionEvent.getAction() == ACTION_UP && motionEvent.getRawX() >= value) {
showInfoAlert(R.string.media_detail_description,R.string.description_info);
return true;
}
}
else{
value = descEdit.getLeft() + descEdit.getCompoundDrawables()[0].getBounds().width();
if (motionEvent.getAction() == ACTION_UP && motionEvent.getRawX() <= value) {
showInfoAlert(R.string.media_detail_description,R.string.description_info);
return true;
}
}
return false;
}
@ -321,4 +327,14 @@ public class SingleUploadFragment extends CommonsDaggerSupportFragment {
}
}
}
private void showInfoAlert (int titleStringID, int messageStringID){
new AlertDialog.Builder(getContext())
.setTitle(titleStringID)
.setMessage(messageStringID)
.setCancelable(true)
.setNeutralButton(android.R.string.ok, (dialog, id) -> dialog.cancel())
.create()
.show();
}
}