mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-28 05:13:53 +01:00
Merge branch 'master' into directNearbyUploadsNew
This commit is contained in:
commit
50d9cff8c6
152 changed files with 2687 additions and 945 deletions
|
|
@ -1,12 +1,17 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.UnderlineSpan;
|
||||
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;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
|
@ -14,12 +19,15 @@ import butterknife.OnClick;
|
|||
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
||||
import fr.free.nrw.commons.ui.widget.HtmlTextView;
|
||||
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
|
||||
/**
|
||||
* Represents about screen of this app
|
||||
*/
|
||||
public class AboutActivity extends NavigationBaseActivity {
|
||||
@BindView(R.id.about_version) TextView versionText;
|
||||
@BindView(R.id.about_license) HtmlTextView aboutLicenseText;
|
||||
@BindView(R.id.about_faq) TextView faqText;
|
||||
|
||||
/**
|
||||
* This method helps in the creation About screen
|
||||
|
|
@ -27,22 +35,23 @@ public class AboutActivity extends NavigationBaseActivity {
|
|||
* @param savedInstanceState Data bundle
|
||||
*/
|
||||
@Override
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_about);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
String aboutText = getString(R.string.about_license);
|
||||
aboutLicenseText.setHtmlText(aboutText);
|
||||
|
||||
SpannableString content = new SpannableString(getString(R.string.about_faq));
|
||||
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
|
||||
faqText.setText(content);
|
||||
versionText.setText(BuildConfig.VERSION_NAME);
|
||||
initDrawer();
|
||||
}
|
||||
|
||||
@OnClick(R.id.facebook_launch_icon)
|
||||
public void launchFacebook(View view) {
|
||||
|
||||
Intent intent;
|
||||
try {
|
||||
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("fb://page/" + "1921335171459985"));
|
||||
|
|
@ -55,7 +64,7 @@ public class AboutActivity extends NavigationBaseActivity {
|
|||
|
||||
@OnClick(R.id.github_launch_icon)
|
||||
public void launchGithub(View view) {
|
||||
Utils.handleWebUrl(this,Uri.parse("https://commons-app.github.io/\\"));
|
||||
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons\\"));
|
||||
}
|
||||
|
||||
@OnClick(R.id.website_launch_icon)
|
||||
|
|
@ -63,6 +72,11 @@ public class AboutActivity extends NavigationBaseActivity {
|
|||
Utils.handleWebUrl(this,Uri.parse("https://commons-app.github.io/\\"));
|
||||
}
|
||||
|
||||
@OnClick(R.id.about_rate_us)
|
||||
public void launchRatings(View view){
|
||||
Utils.rateApp(this);
|
||||
}
|
||||
|
||||
@OnClick(R.id.about_credits)
|
||||
public void launchCredits(View view) {
|
||||
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons/blob/master/CREDITS/\\"));
|
||||
|
|
@ -73,5 +87,8 @@ public class AboutActivity extends NavigationBaseActivity {
|
|||
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\\"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@OnClick(R.id.about_faq)
|
||||
public void launchFrequentlyAskedQuesions(View view) {
|
||||
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons/wiki/Frequently-Asked-Questions\\"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@ import android.app.Application;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.support.multidex.MultiDexApplication;
|
||||
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.facebook.imagepipeline.core.ImagePipelineConfig;
|
||||
import com.facebook.stetho.Stetho;
|
||||
import com.squareup.leakcanary.LeakCanary;
|
||||
import com.squareup.leakcanary.RefWatcher;
|
||||
|
|
@ -24,7 +26,6 @@ import fr.free.nrw.commons.category.CategoryDao;
|
|||
import fr.free.nrw.commons.contributions.ContributionDao;
|
||||
import fr.free.nrw.commons.data.DBOpenHelper;
|
||||
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||
import fr.free.nrw.commons.di.CommonsApplicationComponent;
|
||||
import fr.free.nrw.commons.modifications.ModifierSequenceDao;
|
||||
import fr.free.nrw.commons.utils.FileUtils;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
|
|
@ -40,7 +41,7 @@ import timber.log.Timber;
|
|||
resDialogCommentPrompt = R.string.crash_dialog_comment_prompt,
|
||||
resDialogOkToast = R.string.crash_dialog_ok_toast
|
||||
)
|
||||
public class CommonsApplication extends Application {
|
||||
public class CommonsApplication extends MultiDexApplication {
|
||||
|
||||
@Inject SessionManager sessionManager;
|
||||
@Inject DBOpenHelper dbOpenHelper;
|
||||
|
|
@ -49,7 +50,7 @@ public class CommonsApplication extends Application {
|
|||
@Inject @Named("application_preferences") SharedPreferences applicationPrefs;
|
||||
@Inject @Named("prefs") SharedPreferences otherPrefs;
|
||||
|
||||
public static final String DEFAULT_EDIT_SUMMARY = "Uploaded using Android Commons app";
|
||||
public static final String DEFAULT_EDIT_SUMMARY = "Uploaded using [[COM:MOA|Commons Mobile App]]";
|
||||
|
||||
public static final String FEEDBACK_EMAIL = "commons-app-android@googlegroups.com";
|
||||
|
||||
|
|
@ -71,8 +72,11 @@ public class CommonsApplication extends Application {
|
|||
.getInstance(this)
|
||||
.getCommonsApplicationComponent()
|
||||
.inject(this);
|
||||
|
||||
Fresco.initialize(this);
|
||||
// Set DownsampleEnabled to True to downsample the image in case it's heavy
|
||||
ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
|
||||
.setDownsampleEnabled(true)
|
||||
.build();
|
||||
Fresco.initialize(this,config);
|
||||
if (setupLeakCanary() == RefWatcher.DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import android.preference.PreferenceManager;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.customtabs.CustomTabsIntent;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
|
@ -15,7 +16,6 @@ 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;
|
||||
|
|
@ -24,6 +24,8 @@ import java.util.regex.Pattern;
|
|||
import fr.free.nrw.commons.settings.Prefs;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
|
||||
public class Utils {
|
||||
|
||||
/**
|
||||
|
|
@ -165,7 +167,24 @@ public class Utils {
|
|||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public static void rateApp(Context context) {
|
||||
final String appPackageName = BuildConfig.class.getPackage().getName();
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleWebUrl(Context context,Uri url){
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, url);
|
||||
if (browserIntent.resolveActivity(context.getPackageManager()) == null) {
|
||||
Toast toast = Toast.makeText(context, context.getString(R.string.no_web_browser), LENGTH_SHORT);
|
||||
toast.show();
|
||||
return;
|
||||
}
|
||||
|
||||
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
|
||||
builder.setToolbarColor(ContextCompat.getColor(context, R.color.primaryColor));
|
||||
builder.setSecondaryToolbarColor(ContextCompat.getColor(context, R.color.primaryDarkColor));
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import android.support.v4.view.PagerAdapter;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
|
@ -54,10 +55,18 @@ public class WelcomePagerAdapter extends PagerAdapter {
|
|||
public Object instantiateItem(ViewGroup container, int position) {
|
||||
LayoutInflater inflater = LayoutInflater.from(container.getContext());
|
||||
ViewGroup layout = (ViewGroup) inflater.inflate(PAGE_LAYOUTS[position], container, false);
|
||||
|
||||
if (position == PAGE_FINAL) {
|
||||
if( BuildConfig.FLAVOR == "beta"){
|
||||
TextView textView = (TextView) layout.findViewById(R.id.welcomeYesButton);
|
||||
if( textView.getVisibility() != View.VISIBLE){
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
ViewHolder holder = new ViewHolder(layout);
|
||||
layout.setTag(holder);
|
||||
} else {
|
||||
if (position == PAGE_FINAL) {
|
||||
ViewHolder holder = new ViewHolder(layout);
|
||||
layout.setTag(holder);
|
||||
}
|
||||
}
|
||||
container.addView(layout);
|
||||
return layout;
|
||||
|
|
@ -92,5 +101,6 @@ public class WelcomePagerAdapter extends PagerAdapter {
|
|||
callback.onYesClicked();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import android.app.Activity;
|
|||
import android.app.ProgressDialog;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.ColorRes;
|
||||
import android.support.annotation.NonNull;
|
||||
|
|
@ -27,6 +28,7 @@ import android.view.inputmethod.InputMethodManager;
|
|||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
|
@ -35,6 +37,7 @@ import javax.inject.Named;
|
|||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.PageTitle;
|
||||
import fr.free.nrw.commons.R;
|
||||
|
|
@ -44,6 +47,7 @@ import fr.free.nrw.commons.contributions.ContributionsActivity;
|
|||
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
||||
import fr.free.nrw.commons.ui.widget.HtmlTextView;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
|
@ -73,11 +77,16 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
|||
@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;
|
||||
@BindView(R.id.two_factor_container) TextInputLayout twoFactorContainer;
|
||||
@BindView(R.id.forgotPassword) HtmlTextView forgotPasswordText;
|
||||
|
||||
ProgressDialog progressDialog;
|
||||
private AppCompatDelegate delegate;
|
||||
private LoginTextWatcher textWatcher = new LoginTextWatcher();
|
||||
|
||||
private Boolean loginCurrentlyInProgress = false;
|
||||
private static final String LOGING_IN = "logingIn";
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(Utils.isDarkTheme(this) ? R.style.DarkAppTheme : R.style.LightAppTheme);
|
||||
|
|
@ -114,6 +123,8 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
|||
loginButton.setOnClickListener(view -> performLogin());
|
||||
signupButton.setOnClickListener(view -> signUp());
|
||||
|
||||
forgotPasswordText.setOnClickListener(view -> forgotPassword());
|
||||
|
||||
if(BuildConfig.FLAVOR == "beta"){
|
||||
loginCredentials.setText(getString(R.string.login_credential));
|
||||
} else {
|
||||
|
|
@ -121,6 +132,14 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
|||
}
|
||||
}
|
||||
|
||||
private void forgotPassword() {
|
||||
Utils.handleWebUrl(this, Uri.parse(BuildConfig.FORGOT_PASSWORD_URL));
|
||||
}
|
||||
|
||||
@OnClick(R.id.about_privacy_policy)
|
||||
void onPrivacyPolicyClicked() {
|
||||
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\\"));
|
||||
}
|
||||
|
||||
public void hideKeyboard(View view) {
|
||||
InputMethodManager inputMethodManager =(InputMethodManager)this.getSystemService(Activity.INPUT_METHOD_SERVICE);
|
||||
|
|
@ -164,6 +183,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
|||
}
|
||||
|
||||
private void performLogin() {
|
||||
loginCurrentlyInProgress = true;
|
||||
Timber.d("Login to start!");
|
||||
final String username = canonicializeUsername(usernameEdit.getText().toString());
|
||||
final String password = passwordEdit.getText().toString();
|
||||
|
|
@ -194,6 +214,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
|||
if (result.equals("PASS")) {
|
||||
handlePassResult(username, password);
|
||||
} else {
|
||||
loginCurrentlyInProgress = false;
|
||||
handleOtherResults(result);
|
||||
}
|
||||
}
|
||||
|
|
@ -316,6 +337,21 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
|||
return getDelegate().getMenuInflater();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putBoolean(LOGING_IN, loginCurrentlyInProgress);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
loginCurrentlyInProgress = savedInstanceState.getBoolean(LOGING_IN, false);
|
||||
if(loginCurrentlyInProgress){
|
||||
performLogin();
|
||||
}
|
||||
}
|
||||
|
||||
public void askUserForTwoFactorAuth() {
|
||||
progressDialog.dismiss();
|
||||
twoFactorContainer.setVisibility(VISIBLE);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package fr.free.nrw.commons.category;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
|
|
|
|||
|
|
@ -108,10 +108,10 @@ public class CategoryDao {
|
|||
Category fromCursor(Cursor cursor) {
|
||||
// Hardcoding column positions!
|
||||
return new Category(
|
||||
CategoryContentProvider.uriForId(cursor.getInt(0)),
|
||||
cursor.getString(1),
|
||||
new Date(cursor.getLong(2)),
|
||||
cursor.getInt(3)
|
||||
CategoryContentProvider.uriForId(cursor.getInt(cursor.getColumnIndex(Table.COLUMN_ID))),
|
||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_NAME)),
|
||||
new Date(cursor.getLong(cursor.getColumnIndex(Table.COLUMN_LAST_USED))),
|
||||
cursor.getInt(cursor.getColumnIndex(Table.COLUMN_TIMES_USED))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import android.net.Uri;
|
|||
import android.os.RemoteException;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
|
@ -115,23 +116,30 @@ public class ContributionDao {
|
|||
// Hardcoding column positions!
|
||||
//Check that cursor has a value to avoid CursorIndexOutOfBoundsException
|
||||
if (cursor.getCount() > 0) {
|
||||
int index;
|
||||
if (cursor.getColumnIndex(Table.COLUMN_LICENSE) == -1){
|
||||
index = 15;
|
||||
} else {
|
||||
index = cursor.getColumnIndex(Table.COLUMN_LICENSE);
|
||||
}
|
||||
return new Contribution(
|
||||
uriForId(cursor.getInt(0)),
|
||||
cursor.getString(1),
|
||||
parseUri(cursor.getString(2)),
|
||||
cursor.getString(3),
|
||||
parseTimestamp(cursor.getLong(4)),
|
||||
cursor.getInt(5),
|
||||
cursor.getLong(6),
|
||||
parseTimestamp(cursor.getLong(7)),
|
||||
cursor.getLong(8),
|
||||
cursor.getString(9),
|
||||
cursor.getString(10),
|
||||
cursor.getString(11),
|
||||
cursor.getInt(12) == 1,
|
||||
cursor.getInt(13),
|
||||
cursor.getInt(14),
|
||||
cursor.getString(15));
|
||||
uriForId(cursor.getInt(cursor.getColumnIndex(Table.COLUMN_ID))),
|
||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_FILENAME)),
|
||||
parseUri(cursor.getString(cursor.getColumnIndex(Table.COLUMN_LOCAL_URI))),
|
||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_IMAGE_URL)),
|
||||
parseTimestamp(cursor.getLong(cursor.getColumnIndex(Table.COLUMN_TIMESTAMP))),
|
||||
cursor.getInt(cursor.getColumnIndex(Table.COLUMN_STATE)),
|
||||
cursor.getLong(cursor.getColumnIndex(Table.COLUMN_LENGTH)),
|
||||
parseTimestamp(cursor.getLong(cursor.getColumnIndex(Table.COLUMN_UPLOADED))),
|
||||
cursor.getLong(cursor.getColumnIndex(Table.COLUMN_TRANSFERRED)),
|
||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_SOURCE)),
|
||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_DESCRIPTION)),
|
||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_CREATOR)),
|
||||
cursor.getInt(cursor.getColumnIndex(Table.COLUMN_MULTIPLE)) == 1,
|
||||
cursor.getInt(cursor.getColumnIndex(Table.COLUMN_WIDTH)),
|
||||
cursor.getInt(cursor.getColumnIndex(Table.COLUMN_HEIGHT)),
|
||||
cursor.getString(index)
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.HandlerService;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.R;
|
||||
|
|
@ -139,7 +140,11 @@ public class ContributionsActivity
|
|||
requestAuthToken();
|
||||
initDrawer();
|
||||
setTitle(getString(R.string.title_activity_contributions));
|
||||
setUploadCount();
|
||||
|
||||
if(!BuildConfig.FLAVOR.equalsIgnoreCase("beta")){
|
||||
setUploadCount();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -279,6 +284,12 @@ public class ContributionsActivity
|
|||
));
|
||||
}
|
||||
|
||||
public void betaSetUploadCount(int betaUploadCount){
|
||||
getSupportActionBar().setSubtitle(getResources()
|
||||
.getQuantityString(R.plurals.contributions_subtitle, betaUploadCount, betaUploadCount));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void notifyDatasetChanged() {
|
||||
// Do nothing for now
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import javax.inject.Named;
|
|||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||
import fr.free.nrw.commons.nearby.NearbyActivity;
|
||||
|
|
@ -56,6 +57,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment {
|
|||
|
||||
private ContributionController controller;
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.fragment_contributions, container, false);
|
||||
|
|
@ -87,6 +89,10 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment {
|
|||
|
||||
public void setAdapter(ListAdapter adapter) {
|
||||
this.contributionsList.setAdapter(adapter);
|
||||
|
||||
if(BuildConfig.FLAVOR.equalsIgnoreCase("beta")){
|
||||
((ContributionsActivity) getActivity()).betaSetUploadCount(adapter.getCount());
|
||||
}
|
||||
}
|
||||
|
||||
public void changeProgressBarVisibility(boolean isVisible) {
|
||||
|
|
|
|||
174
app/src/main/java/fr/free/nrw/commons/delete/DeleteTask.java
Normal file
174
app/src/main/java/fr/free/nrw/commons/delete/DeleteTask.java
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
package fr.free.nrw.commons.delete;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static android.support.v4.content.ContextCompat.startActivity;
|
||||
|
||||
public class DeleteTask extends AsyncTask<Void, Void, Integer> {
|
||||
|
||||
private static final int SUCCESS = 0;
|
||||
private static final int FAILED = -1;
|
||||
private static final int ALREADY_DELETED = -2;
|
||||
|
||||
@Inject MediaWikiApi mwApi;
|
||||
@Inject SessionManager sessionManager;
|
||||
|
||||
private Context context;
|
||||
private Media media;
|
||||
private String reason;
|
||||
|
||||
public DeleteTask (Context context, Media media, String reason){
|
||||
this.context = context;
|
||||
this.media = media;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute(){
|
||||
ApplicationlessInjection
|
||||
.getInstance(context.getApplicationContext())
|
||||
.getCommonsApplicationComponent()
|
||||
.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground(Void ...voids) {
|
||||
String editToken;
|
||||
String authCookie;
|
||||
String summary = "Nominating " + media.getFilename() +" for deletion.";
|
||||
|
||||
authCookie = sessionManager.getAuthCookie();
|
||||
mwApi.setAuthCookie(authCookie);
|
||||
|
||||
try{
|
||||
if (mwApi.pageExists("Commons:Deletion_requests/"+media.getFilename())){
|
||||
return ALREADY_DELETED;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
Timber.d(e.getMessage());
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
try {
|
||||
editToken = mwApi.getEditToken();
|
||||
}
|
||||
catch (Exception e){
|
||||
Timber.d(e.getMessage());
|
||||
return FAILED;
|
||||
}
|
||||
if (editToken.equals("+\\")) {
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
String fileDeleteString = "{{delete|reason=" + reason +
|
||||
"|subpage=" +media.getFilename() +
|
||||
"|day=" + calendar.get(Calendar.DAY_OF_MONTH) +
|
||||
"|month=" + calendar.getDisplayName(Calendar.MONTH,Calendar.LONG, Locale.getDefault()) +
|
||||
"|year=" + calendar.get(Calendar.YEAR) +
|
||||
"}}";
|
||||
try{
|
||||
mwApi.prependEdit(editToken,fileDeleteString+"\n",
|
||||
media.getFilename(),summary);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Timber.d(e.getMessage());
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
String subpageString = "=== [[:" + media.getFilename() + "]] ===\n" +
|
||||
reason +
|
||||
" ~~~~";
|
||||
try{
|
||||
mwApi.edit(editToken,subpageString+"\n",
|
||||
"Commons:Deletion_requests/"+media.getFilename(),summary);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Timber.d(e.getMessage());
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
String logPageString = "\n{{Commons:Deletion requests/" + media.getFilename() +
|
||||
"}}\n";
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
|
||||
String date = sdf.format(calendar.getTime());
|
||||
try{
|
||||
mwApi.appendEdit(editToken,logPageString+"\n",
|
||||
"Commons:Deletion_requests/"+date,summary);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Timber.d(e.getMessage());
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
String userPageString = "\n{{subst:idw|" + media.getFilename() +
|
||||
"}} ~~~~";
|
||||
try{
|
||||
mwApi.appendEdit(editToken,userPageString+"\n",
|
||||
"User_Talk:"+sessionManager.getCurrentAccount().name,summary);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Timber.d(e.getMessage());
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Integer result) {
|
||||
String message = "";
|
||||
String title = "";
|
||||
switch (result){
|
||||
case SUCCESS:
|
||||
title = "Success";
|
||||
message = "Successfully nominated " + media.getDisplayTitle() + " deletion.\n" +
|
||||
"Check the webpage for more details";
|
||||
break;
|
||||
case FAILED:
|
||||
title = "Failed";
|
||||
message = "Could not request deletion. Something went wrong.";
|
||||
break;
|
||||
case ALREADY_DELETED:
|
||||
title = "Already Nominated";
|
||||
message = media.getDisplayTitle() + " has already been nominated for deletion.\n" +
|
||||
"Check the webpage for more details";
|
||||
break;
|
||||
}
|
||||
AlertDialog alert;
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(title);
|
||||
builder.setMessage(message);
|
||||
builder.setCancelable(true);
|
||||
builder.setPositiveButton(
|
||||
R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {}
|
||||
});
|
||||
builder.setNeutralButton(R.string.view_browser,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, media.getFilePageTitle().getMobileUri());
|
||||
startActivity(context,browserIntent,null);
|
||||
}
|
||||
});
|
||||
alert = builder.create();
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,10 @@ import dagger.android.support.AndroidSupportInjectionModule;
|
|||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.MediaWikiImageView;
|
||||
import fr.free.nrw.commons.auth.LoginActivity;
|
||||
import fr.free.nrw.commons.contributions.Contribution;
|
||||
import fr.free.nrw.commons.contributions.ContributionsActivity;
|
||||
import fr.free.nrw.commons.contributions.ContributionsSyncAdapter;
|
||||
import fr.free.nrw.commons.delete.DeleteTask;
|
||||
import fr.free.nrw.commons.modifications.ModificationsSyncAdapter;
|
||||
import fr.free.nrw.commons.settings.SettingsFragment;
|
||||
import fr.free.nrw.commons.nearby.PlaceRenderer;
|
||||
|
|
@ -35,6 +38,8 @@ public interface CommonsApplicationComponent extends AndroidInjector<Application
|
|||
|
||||
void inject(LoginActivity activity);
|
||||
|
||||
void inject(DeleteTask deleteTask);
|
||||
|
||||
void inject(SettingsFragment fragment);
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,19 +1,27 @@
|
|||
package fr.free.nrw.commons.media;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.database.DataSetObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
|
@ -31,11 +39,14 @@ import fr.free.nrw.commons.MediaDataExtractor;
|
|||
import fr.free.nrw.commons.MediaWikiImageView;
|
||||
import fr.free.nrw.commons.PageTitle;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.delete.DeleteTask;
|
||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.ui.widget.CompatTextView;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
|
||||
public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||
|
||||
private boolean editable;
|
||||
|
|
@ -69,6 +80,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
private TextView coordinates;
|
||||
private TextView uploadedDate;
|
||||
private LinearLayout categoryContainer;
|
||||
private Button delete;
|
||||
private ScrollView scrollView;
|
||||
private ArrayList<String> categoryNames;
|
||||
private boolean categoriesLoaded = false;
|
||||
|
|
@ -121,6 +133,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
license = (TextView) view.findViewById(R.id.mediaDetailLicense);
|
||||
coordinates = (TextView) view.findViewById(R.id.mediaDetailCoordinates);
|
||||
uploadedDate = (TextView) view.findViewById(R.id.mediaDetailuploadeddate);
|
||||
delete = (Button) view.findViewById(R.id.nominateDeletion);
|
||||
categoryContainer = (LinearLayout) view.findViewById(R.id.mediaDetailCategoryContainer);
|
||||
|
||||
licenseList = new LicenseList(getActivity());
|
||||
|
|
@ -270,13 +283,66 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
categoryNames.add(getString(R.string.detail_panel_cats_none));
|
||||
}
|
||||
rebuildCatList();
|
||||
|
||||
delete.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
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()));
|
||||
}
|
||||
if (delete.getVisibility()==View.VISIBLE){
|
||||
delete.setOnClickListener(v -> {
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
|
||||
alert.setMessage("Why should this file be deleted?");
|
||||
final EditText input = new EditText(getActivity());
|
||||
alert.setView(input);
|
||||
input.requestFocus();
|
||||
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
String reason = input.getText().toString();
|
||||
DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
|
||||
deleteTask.execute();
|
||||
}
|
||||
});
|
||||
alert.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
}
|
||||
});
|
||||
AlertDialog d = alert.create();
|
||||
input.addTextChangedListener(new TextWatcher() {
|
||||
private void handleText() {
|
||||
final Button okButton = d.getButton(AlertDialog.BUTTON_POSITIVE);
|
||||
if (input.getText().length() == 0) {
|
||||
okButton.setEnabled(false);
|
||||
} else {
|
||||
okButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable arg0) {
|
||||
handleText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
});
|
||||
d.show();
|
||||
d.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void rebuildCatList() {
|
||||
|
|
@ -299,7 +365,13 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
Intent viewIntent = new Intent();
|
||||
viewIntent.setAction(Intent.ACTION_VIEW);
|
||||
viewIntent.setData(new PageTitle(selectedCategoryTitle).getCanonicalUri());
|
||||
startActivity(viewIntent);
|
||||
//check if web browser available
|
||||
if(viewIntent.resolveActivity(getActivity().getPackageManager()) != null){
|
||||
startActivity(viewIntent);
|
||||
} else {
|
||||
Toast toast = Toast.makeText(getContext(), getString(R.string.no_web_browser), LENGTH_SHORT);
|
||||
toast.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
return item;
|
||||
|
|
@ -379,7 +451,14 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
|
||||
private void openWebBrowser(String url) {
|
||||
Intent browser = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
startActivity(browser);
|
||||
//check if web browser available
|
||||
if (browser.resolveActivity(getActivity().getPackageManager()) != null) {
|
||||
startActivity(browser);
|
||||
} else {
|
||||
Toast toast = Toast.makeText(getContext(), getString(R.string.no_web_browser), LENGTH_SHORT);
|
||||
toast.show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void openMap(LatLng coordinates) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import android.view.MenuInflater;
|
|||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
|
@ -40,6 +41,7 @@ import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
|||
import static android.content.Context.DOWNLOAD_SERVICE;
|
||||
import static android.content.Intent.ACTION_VIEW;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
|
||||
public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment implements ViewPager.OnPageChangeListener {
|
||||
|
||||
|
|
@ -118,7 +120,14 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
|
|||
Intent viewIntent = new Intent();
|
||||
viewIntent.setAction(ACTION_VIEW);
|
||||
viewIntent.setData(m.getFilePageTitle().getMobileUri());
|
||||
startActivity(viewIntent);
|
||||
//check if web browser available
|
||||
if(viewIntent.resolveActivity(getActivity().getPackageManager()) != null){
|
||||
startActivity(viewIntent);
|
||||
} else {
|
||||
Toast toast = Toast.makeText(getContext(), getString(R.string.no_web_browser), LENGTH_SHORT);
|
||||
toast.show();
|
||||
}
|
||||
|
||||
return true;
|
||||
case R.id.menu_download_current_image:
|
||||
// Download
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public class ModifierSequence {
|
|||
for (PageModifier modifier: modifiers) {
|
||||
editSummary.append(modifier.getEditSumary()).append(" ");
|
||||
}
|
||||
editSummary.append("Via Commons Mobile App");
|
||||
editSummary.append("Using [[COM:MOA|Commons Mobile App]]");
|
||||
return editSummary.toString();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,12 +54,12 @@ public class ModifierSequenceDao {
|
|||
// Hardcoding column positions!
|
||||
ModifierSequence ms;
|
||||
try {
|
||||
ms = new ModifierSequence(Uri.parse(cursor.getString(1)),
|
||||
new JSONObject(cursor.getString(2)));
|
||||
ms = new ModifierSequence(Uri.parse(cursor.getString(cursor.getColumnIndex(Table.COLUMN_MEDIA_URI))),
|
||||
new JSONObject(cursor.getString(cursor.getColumnIndex(Table.COLUMN_DATA))));
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ms.setContentUri( ModificationsContentProvider.uriForId(cursor.getInt(0)));
|
||||
ms.setContentUri( ModificationsContentProvider.uriForId(cursor.getInt(cursor.getColumnIndex(Table.COLUMN_ID))));
|
||||
|
||||
return ms;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,6 +205,14 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
|
|||
.getNodes("/api/query/pages/page/imageinfo").size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pageExists(String pageName) throws IOException {
|
||||
return Double.parseDouble( api.action("query")
|
||||
.param("titles", pageName)
|
||||
.get()
|
||||
.getString("/api/query/pages/page/@_idx")) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String edit(String editToken, String processedPageContent, String filename, String summary) throws IOException {
|
||||
|
|
@ -217,6 +225,31 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
|
|||
.getString("/api/edit/@result");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String appendEdit(String editToken, String processedPageContent, String filename, String summary) throws IOException {
|
||||
return api.action("edit")
|
||||
.param("title", filename)
|
||||
.param("token", editToken)
|
||||
.param("appendtext", processedPageContent)
|
||||
.param("summary", summary)
|
||||
.post()
|
||||
.getString("/api/edit/@result");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String prependEdit(String editToken, String processedPageContent, String filename, String summary) throws IOException {
|
||||
return api.action("edit")
|
||||
.param("title", filename)
|
||||
.param("token", editToken)
|
||||
.param("prependtext", processedPageContent)
|
||||
.param("summary", summary)
|
||||
.post()
|
||||
.getString("/api/edit/@result");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String findThumbnailByFilename(String filename) throws IOException {
|
||||
return api.action("query")
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ public interface MediaWikiApi {
|
|||
|
||||
boolean fileExistsWithName(String fileName) throws IOException;
|
||||
|
||||
boolean pageExists(String pageName) throws IOException;
|
||||
|
||||
String findThumbnailByFilename(String filename) throws IOException;
|
||||
|
||||
boolean logEvents(LogBuilder[] logBuilders);
|
||||
|
|
@ -38,6 +40,12 @@ public interface MediaWikiApi {
|
|||
@Nullable
|
||||
String edit(String editToken, String processedPageContent, String filename, String summary) throws IOException;
|
||||
|
||||
@Nullable
|
||||
String prependEdit(String editToken, String processedPageContent, String filename, String summary) throws IOException;
|
||||
|
||||
@Nullable
|
||||
String appendEdit(String editToken, String processedPageContent, String filename, String summary) throws IOException;
|
||||
|
||||
@NonNull
|
||||
MediaResult fetchMediaByFilename(String filename) throws IOException;
|
||||
|
||||
|
|
@ -58,8 +66,6 @@ public interface MediaWikiApi {
|
|||
|
||||
boolean existingFile(String fileSha1) throws IOException;
|
||||
|
||||
|
||||
|
||||
@NonNull
|
||||
LogEventResult logEvents(String user, String lastModified, String queryContinue, int limit) throws IOException;
|
||||
|
||||
|
|
|
|||
|
|
@ -300,7 +300,6 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
LatLng lastLocation = locationManager.getLastLocation();
|
||||
|
||||
if (curLatLang != null && curLatLang.equals(lastLocation)) { //refresh view only if location has changed
|
||||
|
||||
return;
|
||||
}
|
||||
curLatLang = lastLocation;
|
||||
|
|
@ -340,9 +339,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
String gsonBoundaryCoordinates = gson.toJson(boundaryCoordinates);
|
||||
|
||||
if (placeList.size() == 0) {
|
||||
int duration = Toast.LENGTH_SHORT;
|
||||
Toast toast = Toast.makeText(this, R.string.no_nearby, duration);
|
||||
toast.show();
|
||||
ViewUtil.showSnackbar(findViewById(R.id.container), R.string.no_nearby);
|
||||
}
|
||||
|
||||
bundle.clear();
|
||||
|
|
|
|||
|
|
@ -144,9 +144,9 @@ public class PlaceRenderer extends Renderer<Place> {
|
|||
place = getContent();
|
||||
tvName.setText(place.name);
|
||||
String descriptionText = place.getLongDescription();
|
||||
|
||||
if (descriptionText.equals("?")) {
|
||||
descriptionText = getContext().getString(R.string.no_description_found);
|
||||
tvDesc.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
tvDesc.setText(descriptionText);
|
||||
distance.setText(place.distance);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
|
@ -8,10 +9,10 @@ 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;
|
||||
|
|
@ -25,6 +26,8 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
|
|||
import io.reactivex.schedulers.Schedulers;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
|
||||
/**
|
||||
* Created by root on 18.12.2017.
|
||||
*/
|
||||
|
|
@ -36,12 +39,16 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
|
||||
@Inject NotificationController controller;
|
||||
|
||||
private static final String TAG_NOTIFICATION_WORKER_FRAGMENT = "NotificationWorkerFragment";
|
||||
private NotificationWorkerFragment mNotificationWorkerFragment;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_notification);
|
||||
ButterKnife.bind(this);
|
||||
mNotificationWorkerFragment = (NotificationWorkerFragment) getFragmentManager()
|
||||
.findFragmentByTag(TAG_NOTIFICATION_WORKER_FRAGMENT);
|
||||
initListView();
|
||||
initDrawer();
|
||||
}
|
||||
|
|
@ -57,21 +64,32 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
private void addNotifications() {
|
||||
Timber.d("Add notifications");
|
||||
|
||||
Observable.fromCallable(() -> controller.getNotifications())
|
||||
.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"));
|
||||
if(mNotificationWorkerFragment == null){
|
||||
Observable.fromCallable(() -> controller.getNotifications())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(notificationList -> {
|
||||
Timber.d("Number of notifications is %d", notificationList.size());
|
||||
initializeAndSetNotificationList(notificationList);
|
||||
setAdapter(notificationList);
|
||||
}, throwable -> Timber.e(throwable, "Error occurred while loading notifications"));
|
||||
} else {
|
||||
setAdapter(mNotificationWorkerFragment.getNotificationList());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleUrl(String url) {
|
||||
if (url == null || url.equals("")) {
|
||||
return;
|
||||
}
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
|
||||
Intent browser = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
//check if web browser available
|
||||
if(browser.resolveActivity(this.getPackageManager()) != null){
|
||||
startActivity(browser);
|
||||
} else {
|
||||
Toast toast = Toast.makeText(this, getString(R.string.no_web_browser), LENGTH_SHORT);
|
||||
toast.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void setAdapter(List<Notification> notificationList) {
|
||||
|
|
@ -85,6 +103,15 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
|
||||
public static void startYourself(Context context) {
|
||||
Intent intent = new Intent(context, NotificationActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeAndSetNotificationList(List<Notification> notificationList){
|
||||
FragmentManager fm = getFragmentManager();
|
||||
mNotificationWorkerFragment = new NotificationWorkerFragment();
|
||||
fm.beginTransaction().add(mNotificationWorkerFragment, TAG_NOTIFICATION_WORKER_FRAGMENT)
|
||||
.commit();
|
||||
mNotificationWorkerFragment.setNotificationList(notificationList);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.borjabravo.readmoretextview.ReadMoreTextView;
|
||||
import com.pedrogomez.renderers.Renderer;
|
||||
|
||||
import butterknife.BindView;
|
||||
|
|
@ -17,8 +19,8 @@ import fr.free.nrw.commons.R;
|
|||
*/
|
||||
|
||||
public class NotificationRenderer extends Renderer<Notification> {
|
||||
@BindView(R.id.title) TextView title;
|
||||
@BindView(R.id.description) TextView description;
|
||||
@BindView(R.id.title) ReadMoreTextView title;
|
||||
@BindView(R.id.description) ReadMoreTextView description;
|
||||
@BindView(R.id.time) TextView time;
|
||||
@BindView(R.id.icon) ImageView icon;
|
||||
private NotificationClicked listener;
|
||||
|
|
@ -46,9 +48,13 @@ public class NotificationRenderer extends Renderer<Notification> {
|
|||
@Override
|
||||
public void render() {
|
||||
Notification notification = getContent();
|
||||
title.setText(notification.notificationText);
|
||||
StringBuilder str = new StringBuilder(notification.notificationText);
|
||||
str.append(" " );
|
||||
title.setText(str);
|
||||
time.setText(notification.date);
|
||||
description.setText(notification.description);
|
||||
StringBuilder desc = new StringBuilder(notification.description);
|
||||
desc.append(" ");
|
||||
description.setText(desc);
|
||||
switch (notification.notificationType) {
|
||||
case THANK_YOU_EDIT:
|
||||
icon.setImageResource(R.drawable.ic_edit_black_24dp);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by knightshade on 25/2/18.
|
||||
*/
|
||||
|
||||
public class NotificationWorkerFragment extends Fragment {
|
||||
private List<Notification> notificationList;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
}
|
||||
|
||||
public void setNotificationList(List<Notification> notificationList){
|
||||
this.notificationList = notificationList;
|
||||
}
|
||||
|
||||
public List<Notification> getNotificationList(){
|
||||
return notificationList;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,14 +3,17 @@ package fr.free.nrw.commons.settings;
|
|||
import android.Manifest;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.SwitchPreference;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
|
|
@ -21,6 +24,8 @@ import android.support.v4.content.FileProvider;
|
|||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
|
@ -59,7 +64,7 @@ public class SettingsFragment extends PreferenceFragment {
|
|||
return true;
|
||||
});
|
||||
|
||||
CheckBoxPreference themePreference = (CheckBoxPreference) findPreference("theme");
|
||||
SwitchPreference themePreference = (SwitchPreference) findPreference("theme");
|
||||
themePreference.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
getActivity().recreate();
|
||||
return true;
|
||||
|
|
@ -141,19 +146,24 @@ public class SettingsFragment extends PreferenceFragment {
|
|||
appLogsFile
|
||||
);
|
||||
|
||||
Intent feedbackIntent = new Intent(Intent.ACTION_SEND);
|
||||
feedbackIntent.setType("message/rfc822");
|
||||
feedbackIntent.putExtra(Intent.EXTRA_EMAIL,
|
||||
new String[]{CommonsApplication.LOGS_PRIVATE_EMAIL});
|
||||
feedbackIntent.putExtra(Intent.EXTRA_SUBJECT,
|
||||
String.format(CommonsApplication.FEEDBACK_EMAIL_SUBJECT,
|
||||
BuildConfig.VERSION_NAME));
|
||||
feedbackIntent.putExtra(Intent.EXTRA_STREAM,appLogsFilePath);
|
||||
//initialize the emailSelectorIntent
|
||||
Intent emailSelectorIntent = new Intent(Intent.ACTION_SENDTO);
|
||||
emailSelectorIntent.setData(Uri.parse("mailto:"));
|
||||
//initialize the emailIntent
|
||||
final Intent emailIntent = new Intent(Intent.ACTION_SEND);
|
||||
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{CommonsApplication.FEEDBACK_EMAIL});
|
||||
emailIntent.putExtra(Intent.EXTRA_SUBJECT, String.format(CommonsApplication.FEEDBACK_EMAIL_SUBJECT, BuildConfig.VERSION_NAME));
|
||||
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
emailIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||
emailIntent.setSelector( emailSelectorIntent );
|
||||
//adding the attachment to the intent
|
||||
emailIntent.putExtra(Intent.EXTRA_STREAM, appLogsFilePath);
|
||||
|
||||
try {
|
||||
startActivity(feedbackIntent);
|
||||
startActivity(Intent.createChooser(emailIntent, "Send mail.."));
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Toast.makeText(getActivity(), R.string.no_email_client, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,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;
|
||||
|
|
@ -87,8 +88,11 @@ public abstract class NavigationBaseActivity extends BaseActivity
|
|||
|
||||
private void setDrawerPaneWidth() {
|
||||
ViewGroup.LayoutParams params = navigationView.getLayoutParams();
|
||||
// set width to lowerBound of 80% of the screen size
|
||||
params.width = (getResources().getDisplayMetrics().widthPixels * 70) / 100;
|
||||
// set width to lowerBound of 70% of the screen size in portrait mode
|
||||
// set width to lowerBound of 50% of the screen size in landscape mode
|
||||
int percentageWidth = getResources().getInteger(R.integer.drawer_width);
|
||||
|
||||
params.width = (getResources().getDisplayMetrics().widthPixels * percentageWidth) / 100;
|
||||
navigationView.setLayoutParams(params);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
package fr.free.nrw.commons.upload;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.contributions.ContributionsActivity;
|
||||
|
|
@ -28,12 +30,14 @@ public class ExistingFileAsync extends AsyncTask<Void, Void, Boolean> {
|
|||
DUPLICATE_CANCELLED
|
||||
}
|
||||
|
||||
private final WeakReference<Activity> activity;
|
||||
private final MediaWikiApi api;
|
||||
private final String fileSha1;
|
||||
private final Context context;
|
||||
private final WeakReference<Context> context;
|
||||
private final Callback callback;
|
||||
|
||||
public ExistingFileAsync(String fileSha1, Context context, Callback callback, MediaWikiApi mwApi) {
|
||||
public ExistingFileAsync(WeakReference<Activity> activity, String fileSha1, WeakReference<Context> context, Callback callback, MediaWikiApi mwApi) {
|
||||
this.activity = activity;
|
||||
this.fileSha1 = fileSha1;
|
||||
this.context = context;
|
||||
this.callback = callback;
|
||||
|
|
@ -69,19 +73,21 @@ public class ExistingFileAsync extends AsyncTask<Void, Void, Boolean> {
|
|||
// If file exists, display warning to user.
|
||||
// Use soft warning for now (user able to choose to proceed) until have determined that implementation works without bugs
|
||||
if (fileExists) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context.get());
|
||||
builder.setMessage(R.string.file_exists)
|
||||
.setTitle(R.string.warning);
|
||||
builder.setPositiveButton(R.string.no, (dialog, id) -> {
|
||||
//Go back to ContributionsActivity
|
||||
Intent intent = new Intent(context, ContributionsActivity.class);
|
||||
context.startActivity(intent);
|
||||
Intent intent = new Intent(context.get(), ContributionsActivity.class);
|
||||
context.get().startActivity(intent);
|
||||
callback.onResult(Result.DUPLICATE_CANCELLED);
|
||||
});
|
||||
builder.setNegativeButton(R.string.yes, (dialog, id) -> callback.onResult(Result.DUPLICATE_PROCEED));
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
if (!activity.get().isFinishing()) {
|
||||
dialog.show();
|
||||
}
|
||||
} else {
|
||||
callback.onResult(Result.NO_DUPLICATE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
package fr.free.nrw.commons.upload;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
|
|
@ -31,6 +34,7 @@ import java.io.File;
|
|||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
|
@ -381,7 +385,7 @@ public class ShareActivity
|
|||
Timber.d("File SHA1 is: %s", fileSHA1);
|
||||
|
||||
ExistingFileAsync fileAsyncTask =
|
||||
new ExistingFileAsync(fileSHA1, this, result -> {
|
||||
new ExistingFileAsync(new WeakReference<Activity>(this), fileSHA1, new WeakReference<Context>(this), result -> {
|
||||
Timber.d("%s duplicate check: %s", mediaUri.toString(), result);
|
||||
duplicateCheckPassed = (result == DUPLICATE_PROCEED
|
||||
|| result == NO_DUPLICATE);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,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;
|
||||
|
|
@ -29,6 +30,7 @@ import android.widget.Button;
|
|||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
|
@ -67,9 +69,6 @@ public class SingleUploadFragment extends CommonsDaggerSupportFragment {
|
|||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.activity_share, menu);
|
||||
if (titleEdit != null) {
|
||||
menu.findItem(R.id.menu_upload_single).setEnabled(titleEdit.getText().length() != 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -78,6 +77,11 @@ public class SingleUploadFragment extends CommonsDaggerSupportFragment {
|
|||
//What happens when the 'submit' icon is tapped
|
||||
case R.id.menu_upload_single:
|
||||
|
||||
if (titleEdit.getText().toString().isEmpty()) {
|
||||
Toast.makeText(getContext(), R.string.add_title_toast, Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
String title = titleEdit.getText().toString();
|
||||
String desc = descEdit.getText().toString();
|
||||
|
||||
|
|
@ -99,6 +103,14 @@ public class SingleUploadFragment extends CommonsDaggerSupportFragment {
|
|||
View rootView = inflater.inflate(R.layout.fragment_single_upload, container, false);
|
||||
ButterKnife.bind(this, rootView);
|
||||
|
||||
Intent activityIntent = getActivity().getIntent();
|
||||
if (activityIntent.hasExtra("title")) {
|
||||
titleEdit.setText(activityIntent.getStringExtra("title"));
|
||||
}
|
||||
if (activityIntent.hasExtra("description")) {
|
||||
descEdit.setText(activityIntent.getStringExtra("description"));
|
||||
}
|
||||
|
||||
ArrayList<String> licenseItems = new ArrayList<>();
|
||||
licenseItems.add(getString(R.string.license_name_cc0));
|
||||
licenseItems.add(getString(R.string.license_name_cc_by));
|
||||
|
|
@ -242,35 +254,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;
|
||||
}
|
||||
|
|
@ -336,4 +353,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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package fr.free.nrw.commons.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.widget.Toast;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.view.View;
|
||||
|
||||
public class ViewUtil {
|
||||
|
||||
public static void showLongToast(final Context context, @StringRes final int stringResId) {
|
||||
ExecutorUtils.uiExecutor().execute(() -> Toast.makeText(context, context.getString(stringResId), Toast.LENGTH_LONG).show());
|
||||
public static void showSnackbar(View view, int messageResourceId) {
|
||||
Snackbar.make(view, messageResourceId, Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue