mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Precise error message password change (#5544)
* Precise Error Message and Action When Password is Changed * Make message persistent * code cleanup and fixes * removed unnecessary string resource * removed unnecessary string resource * fix * fix * Upload Client to kotlin * Remove Redundant Code * Remove Redundant Code * code cleanup and Improvements * Improved Java doc * Improved Java doc * Improved Javadoc
This commit is contained in:
parent
152e824aa6
commit
2a6ab66c11
9 changed files with 171 additions and 54 deletions
|
|
@ -9,9 +9,11 @@ import static org.acra.ReportField.STACK_TRACE;
|
|||
import static org.acra.ReportField.USER_COMMENT;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.os.Build;
|
||||
|
|
@ -22,6 +24,7 @@ import androidx.multidex.MultiDexApplication;
|
|||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.facebook.imagepipeline.core.ImagePipeline;
|
||||
import com.facebook.imagepipeline.core.ImagePipelineConfig;
|
||||
import fr.free.nrw.commons.auth.LoginActivity;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table;
|
||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
||||
|
|
@ -33,6 +36,7 @@ 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.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.language.AppLanguageLookUpTable;
|
||||
import fr.free.nrw.commons.logging.FileLoggingTree;
|
||||
import fr.free.nrw.commons.logging.LogUtils;
|
||||
import fr.free.nrw.commons.media.CustomOkHttpNetworkFetcher;
|
||||
|
|
@ -57,7 +61,6 @@ import org.acra.annotation.AcraCore;
|
|||
import org.acra.annotation.AcraDialog;
|
||||
import org.acra.annotation.AcraMailSender;
|
||||
import org.acra.data.StringFormat;
|
||||
import fr.free.nrw.commons.language.AppLanguageLookUpTable;
|
||||
import timber.log.Timber;
|
||||
|
||||
@AcraCore(
|
||||
|
|
@ -82,6 +85,9 @@ import timber.log.Timber;
|
|||
|
||||
public class CommonsApplication extends MultiDexApplication {
|
||||
|
||||
public static final String loginMessageIntentKey = "loginMessage";
|
||||
public static final String loginUsernameIntentKey = "loginUsername";
|
||||
|
||||
public static final String IS_LIMITED_CONNECTION_MODE_ENABLED = "is_limited_connection_mode_enabled";
|
||||
@Inject
|
||||
SessionManager sessionManager;
|
||||
|
|
@ -137,12 +143,12 @@ public class CommonsApplication extends MultiDexApplication {
|
|||
ContributionDao contributionDao;
|
||||
|
||||
/**
|
||||
* In-memory list of contributions whose uploads have been paused by the user
|
||||
* In-memory list of contributions whose uploads have been paused by the user
|
||||
*/
|
||||
public static Map<String, Boolean> pauseUploads = new HashMap<>();
|
||||
|
||||
/**
|
||||
* In-memory list of uploads that have been cancelled by the user
|
||||
* In-memory list of uploads that have been cancelled by the user
|
||||
*/
|
||||
public static HashSet<String> cancelledUploads = new HashSet<>();
|
||||
|
||||
|
|
@ -339,4 +345,96 @@ public class CommonsApplication extends MultiDexApplication {
|
|||
|
||||
void onLogoutComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* This listener is responsible for handling post-logout actions, specifically invoking the LoginActivity
|
||||
* with relevant intent parameters. It does not perform the actual logout operation.
|
||||
*/
|
||||
public static class BaseLogoutListener implements CommonsApplication.LogoutListener {
|
||||
|
||||
Context ctx;
|
||||
String loginMessage, userName;
|
||||
|
||||
/**
|
||||
* Constructor for BaseLogoutListener.
|
||||
*
|
||||
* @param ctx Application context
|
||||
*/
|
||||
public BaseLogoutListener(final Context ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for BaseLogoutListener
|
||||
*
|
||||
* @param ctx The application context, used for invoking the LoginActivity and passing relevant intent parameters as part of the post-logout process.
|
||||
* @param loginMessage Message to be displayed on the login page
|
||||
* @param loginUsername Username to be pre-filled on the login page
|
||||
*/
|
||||
public BaseLogoutListener(final Context ctx, final String loginMessage,
|
||||
final String loginUsername) {
|
||||
this.ctx = ctx;
|
||||
this.loginMessage = loginMessage;
|
||||
this.userName = loginUsername;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLogoutComplete() {
|
||||
Timber.d("Logout complete callback received.");
|
||||
final Intent loginIntent = new Intent(ctx, LoginActivity.class);
|
||||
loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
if (loginMessage != null) {
|
||||
loginIntent.putExtra(loginMessageIntentKey, loginMessage);
|
||||
}
|
||||
if (userName != null) {
|
||||
loginIntent.putExtra(loginUsernameIntentKey, userName);
|
||||
}
|
||||
|
||||
ctx.startActivity(loginIntent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is an extension of BaseLogoutListener, providing additional functionality or customization
|
||||
* for the logout process. It includes specific actions to be taken during logout, such as handling redirection to the login screen.
|
||||
*/
|
||||
public static class ActivityLogoutListener extends BaseLogoutListener {
|
||||
|
||||
Activity activity;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for ActivityLogoutListener.
|
||||
*
|
||||
* @param activity The activity context from which the logout is initiated. Used to perform actions such as finishing the activity.
|
||||
* @param ctx The application context, used for invoking the LoginActivity and passing relevant intent parameters as part of the post-logout process.
|
||||
*/
|
||||
public ActivityLogoutListener(final Activity activity, final Context ctx) {
|
||||
super(ctx);
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for ActivityLogoutListener with additional parameters for the login screen.
|
||||
*
|
||||
* @param activity The activity context from which the logout is initiated. Used to perform actions such as finishing the activity.
|
||||
* @param ctx The application context, used for invoking the LoginActivity and passing relevant intent parameters as part of the post-logout process.
|
||||
* @param loginMessage Message to be displayed on the login page after logout.
|
||||
* @param loginUsername Username to be pre-filled on the login page after logout.
|
||||
*/
|
||||
public ActivityLogoutListener(final Activity activity, final Context ctx,
|
||||
final String loginMessage, final String loginUsername) {
|
||||
super(activity, loginMessage, loginUsername);
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLogoutComplete() {
|
||||
super.onLogoutComplete();
|
||||
activity.finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import androidx.appcompat.app.AlertDialog;
|
|||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.core.app.NavUtils;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import fr.free.nrw.commons.auth.login.LoginClient;
|
||||
import fr.free.nrw.commons.auth.login.LoginResult;
|
||||
import fr.free.nrw.commons.databinding.ActivityLoginBinding;
|
||||
|
|
@ -51,6 +50,8 @@ import timber.log.Timber;
|
|||
import static android.view.KeyEvent.KEYCODE_ENTER;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
|
||||
import static fr.free.nrw.commons.CommonsApplication.loginMessageIntentKey;
|
||||
import static fr.free.nrw.commons.CommonsApplication.loginUsernameIntentKey;
|
||||
|
||||
public class LoginActivity extends AccountAuthenticatorActivity {
|
||||
|
||||
|
|
@ -93,6 +94,9 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
|||
binding = ActivityLoginBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
String message = getIntent().getStringExtra(loginMessageIntentKey);
|
||||
String username = getIntent().getStringExtra(loginUsernameIntentKey);
|
||||
|
||||
binding.loginUsername.addTextChangedListener(textWatcher);
|
||||
binding.loginPassword.addTextChangedListener(textWatcher);
|
||||
binding.loginTwoFactor.addTextChangedListener(textWatcher);
|
||||
|
|
@ -111,6 +115,12 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
|||
} else {
|
||||
binding.loginCredentials.setVisibility(View.GONE);
|
||||
}
|
||||
if (message != null) {
|
||||
showMessage(message, R.color.secondaryDarkColor);
|
||||
}
|
||||
if (username != null) {
|
||||
binding.loginUsername.setText(username);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Hides the keyboard if the user's focus is not on the password (hasFocus is false).
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class CsrfTokenClient(
|
|||
private var retries = 0
|
||||
private var csrfTokenCall: Call<MwQueryResponse?>? = null
|
||||
|
||||
|
||||
@Throws(Throwable::class)
|
||||
fun getTokenBlocking(): String {
|
||||
var token = ""
|
||||
|
|
@ -56,7 +57,7 @@ class CsrfTokenClient(
|
|||
}
|
||||
|
||||
if (token.isEmpty() || token == ANON_TOKEN) {
|
||||
throw IOException("Invalid token, or login failure.")
|
||||
throw IOException(INVALID_TOKEN_ERROR_MESSAGE)
|
||||
}
|
||||
return token
|
||||
}
|
||||
|
|
@ -159,5 +160,6 @@ class CsrfTokenClient(
|
|||
private const val ANON_TOKEN = "+\\"
|
||||
private const val MAX_RETRIES = 1
|
||||
private const val MAX_RETRIES_OF_LOGIN_BLOCKING = 2
|
||||
const val INVALID_TOKEN_ERROR_MESSAGE = "Invalid token, or login failure."
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
|||
import fr.free.nrw.commons.AboutActivity;
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.CommonsApplication.ActivityLogoutListener;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.WelcomeActivity;
|
||||
import fr.free.nrw.commons.actions.PageEditClient;
|
||||
import fr.free.nrw.commons.auth.LoginActivity;
|
||||
import fr.free.nrw.commons.databinding.FragmentMoreBottomSheetBinding;
|
||||
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||
import fr.free.nrw.commons.feedback.FeedbackContentCreator;
|
||||
|
|
@ -41,7 +41,6 @@ import io.reactivex.schedulers.Schedulers;
|
|||
import java.util.concurrent.Callable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import timber.log.Timber;
|
||||
|
||||
public class MoreBottomSheetFragment extends BottomSheetDialogFragment {
|
||||
|
||||
|
|
@ -122,7 +121,7 @@ public class MoreBottomSheetFragment extends BottomSheetDialogFragment {
|
|||
.setPositiveButton(R.string.yes, (dialog, which) -> {
|
||||
final CommonsApplication app = (CommonsApplication)
|
||||
requireContext().getApplicationContext();
|
||||
app.clearApplicationData(requireContext(), new BaseLogoutListener());
|
||||
app.clearApplicationData(requireContext(), new ActivityLogoutListener(requireActivity(), getContext()));
|
||||
})
|
||||
.setNegativeButton(R.string.no, (dialog, which) -> dialog.cancel())
|
||||
.show();
|
||||
|
|
@ -221,19 +220,5 @@ public class MoreBottomSheetFragment extends BottomSheetDialogFragment {
|
|||
protected void onPeerReviewClicked() {
|
||||
ReviewActivity.startYourself(getActivity(), getString(R.string.title_activity_review));
|
||||
}
|
||||
|
||||
private class BaseLogoutListener implements CommonsApplication.LogoutListener {
|
||||
|
||||
@Override
|
||||
public void onLogoutComplete() {
|
||||
Timber.d("Logout complete callback received.");
|
||||
final Intent nearbyIntent = new Intent(
|
||||
getContext(), LoginActivity.class);
|
||||
nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(nearbyIntent);
|
||||
requireActivity().finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@ import com.jakewharton.rxbinding2.view.RxView;
|
|||
import com.jakewharton.rxbinding3.appcompat.RxSearchView;
|
||||
import fr.free.nrw.commons.BaseMarker;
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.CommonsApplication.BaseLogoutListener;
|
||||
import fr.free.nrw.commons.MapController.NearbyPlacesInfo;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.Utils;
|
||||
import fr.free.nrw.commons.auth.LoginActivity;
|
||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
||||
import fr.free.nrw.commons.contributions.ContributionController;
|
||||
import fr.free.nrw.commons.contributions.MainActivity;
|
||||
|
|
@ -1372,8 +1372,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
.setMessage(R.string.login_alert_message)
|
||||
.setPositiveButton(R.string.login, (dialog, which) -> {
|
||||
// logout of the app
|
||||
BaseLogoutListener logoutListener = new BaseLogoutListener();
|
||||
CommonsApplication app = (CommonsApplication) getActivity().getApplication();
|
||||
BaseLogoutListener logoutListener = new BaseLogoutListener(getActivity()); CommonsApplication app = (CommonsApplication) getActivity().getApplication();
|
||||
app.clearApplicationData(getContext(), logoutListener);
|
||||
})
|
||||
.show();
|
||||
|
|
@ -1419,18 +1418,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
* onLogoutComplete is called after shared preferences and data stored in local database are
|
||||
* cleared.
|
||||
*/
|
||||
private class BaseLogoutListener implements CommonsApplication.LogoutListener {
|
||||
|
||||
@Override
|
||||
public void onLogoutComplete() {
|
||||
Timber.d("Logout complete callback received.");
|
||||
final Intent nearbyIntent = new Intent(getActivity(), LoginActivity.class);
|
||||
nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(nearbyIntent);
|
||||
getActivity().finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFABPlusAction(final View.OnClickListener onClickListener) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ package fr.free.nrw.commons.upload
|
|||
|
||||
data class StashUploadResult(
|
||||
val state: StashUploadState,
|
||||
val fileKey: String?
|
||||
val fileKey: String?,
|
||||
val errorMessage : String?
|
||||
)
|
||||
|
||||
enum class StashUploadState {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class UploadClient @Inject constructor(
|
|||
): Observable<StashUploadResult> {
|
||||
if (contribution.isCompleted()) {
|
||||
return Observable.just(
|
||||
StashUploadResult(StashUploadState.SUCCESS, contribution.fileKey)
|
||||
StashUploadResult(StashUploadState.SUCCESS, contribution.fileKey,null)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -76,12 +76,13 @@ class UploadClient @Inject constructor(
|
|||
|
||||
val index = AtomicInteger()
|
||||
val failures = AtomicBoolean()
|
||||
val errorMessage = AtomicReference<String>()
|
||||
compositeDisposable.add(
|
||||
Observable.fromIterable(fileChunks).forEach { chunkFile: File ->
|
||||
if (canProcess(contribution, failures)) {
|
||||
processChunk(
|
||||
filename, contribution, notificationUpdater, chunkFile,
|
||||
failures, chunkInfo, index, mediaType!!, file!!, fileChunks.size
|
||||
failures, chunkInfo, index, errorMessage, mediaType!!, file!!, fileChunks.size
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -90,24 +91,25 @@ class UploadClient @Inject constructor(
|
|||
return when {
|
||||
contribution.isPaused() -> {
|
||||
Timber.d("Upload stash paused %s", contribution.pageId)
|
||||
Observable.just(StashUploadResult(StashUploadState.PAUSED, null))
|
||||
Observable.just(StashUploadResult(StashUploadState.PAUSED, null, null))
|
||||
}
|
||||
failures.get() -> {
|
||||
Timber.d("Upload stash contains failures %s", contribution.pageId)
|
||||
Observable.just(StashUploadResult(StashUploadState.FAILED, null))
|
||||
Observable.just(StashUploadResult(StashUploadState.FAILED, null, errorMessage.get()))
|
||||
}
|
||||
chunkInfo.get() != null -> {
|
||||
Timber.d("Upload stash success %s", contribution.pageId)
|
||||
Observable.just(
|
||||
StashUploadResult(
|
||||
StashUploadState.SUCCESS,
|
||||
chunkInfo.get()!!.uploadResult!!.filekey
|
||||
chunkInfo.get()!!.uploadResult!!.filekey,
|
||||
"success"
|
||||
)
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
Timber.d("Upload stash failed %s", contribution.pageId)
|
||||
Observable.just(StashUploadResult(StashUploadState.FAILED, null))
|
||||
Observable.just(StashUploadResult(StashUploadState.FAILED, null,null))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -116,7 +118,7 @@ class UploadClient @Inject constructor(
|
|||
filename: String, contribution: Contribution,
|
||||
notificationUpdater: NotificationUpdateProgressListener, chunkFile: File,
|
||||
failures: AtomicBoolean, chunkInfo: AtomicReference<ChunkInfo?>, index: AtomicInteger,
|
||||
mediaType: MediaType, file: File, totalChunks: Int
|
||||
errorMessage : AtomicReference<String>, mediaType: MediaType, file: File, totalChunks: Int
|
||||
) {
|
||||
if (shouldSkip(chunkInfo, index)) {
|
||||
index.incrementAndGet()
|
||||
|
|
@ -150,6 +152,7 @@ class UploadClient @Inject constructor(
|
|||
notificationUpdater.onChunkUploaded(contribution, chunkInfo.get())
|
||||
}, { throwable: Throwable? ->
|
||||
Timber.e(throwable, "Received error in chunk upload")
|
||||
errorMessage.set(throwable?.message)
|
||||
failures.set(true)
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,16 +10,17 @@ import android.graphics.BitmapFactory
|
|||
import android.os.Build
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.multidex.BuildConfig
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.Data
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.multidex.BuildConfig
|
||||
import androidx.work.ForegroundInfo
|
||||
import androidx.work.WorkerParameters
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import fr.free.nrw.commons.CommonsApplication
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.auth.SessionManager
|
||||
import fr.free.nrw.commons.auth.csrf.CsrfTokenClient
|
||||
import fr.free.nrw.commons.contributions.ChunkInfo
|
||||
import fr.free.nrw.commons.contributions.Contribution
|
||||
import fr.free.nrw.commons.contributions.ContributionDao
|
||||
|
|
@ -29,8 +30,8 @@ import fr.free.nrw.commons.customselector.database.UploadedStatusDao
|
|||
import fr.free.nrw.commons.di.ApplicationlessInjection
|
||||
import fr.free.nrw.commons.media.MediaClient
|
||||
import fr.free.nrw.commons.theme.BaseActivity
|
||||
import fr.free.nrw.commons.upload.StashUploadResult
|
||||
import fr.free.nrw.commons.upload.FileUtilsWrapper
|
||||
import fr.free.nrw.commons.upload.StashUploadResult
|
||||
import fr.free.nrw.commons.upload.StashUploadState
|
||||
import fr.free.nrw.commons.upload.UploadClient
|
||||
import fr.free.nrw.commons.upload.UploadResult
|
||||
|
|
@ -46,13 +47,14 @@ import timber.log.Timber
|
|||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
import javax.inject.Inject
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
|
||||
class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
||||
CoroutineWorker(appContext, workerParams) {
|
||||
|
||||
private var notificationManager: NotificationManagerCompat? = null
|
||||
|
||||
|
||||
@Inject
|
||||
lateinit var wikidataEditService: WikidataEditService
|
||||
|
||||
|
|
@ -79,6 +81,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
|||
private val PROCESSING_UPLOADS_NOTIFICATION_ID = 101
|
||||
|
||||
|
||||
|
||||
//Attributes of the current-upload notification
|
||||
private var currentNotificationID: Int = -1// lateinit is not allowed with primitives
|
||||
private lateinit var currentNotificationTag: String
|
||||
|
|
@ -295,7 +298,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
|||
* Upload the contribution
|
||||
* @param contribution
|
||||
*/
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
@SuppressLint("StringFormatInvalid", "CheckResult")
|
||||
private suspend fun uploadContribution(contribution: Contribution) {
|
||||
if (contribution.localUri == null || contribution.localUri.path == null) {
|
||||
Timber.e("""upload: ${contribution.media.filename} failed, file path is null""")
|
||||
|
|
@ -338,7 +341,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
|||
val stashUploadResult = uploadClient.uploadFileToStash(
|
||||
filename!!, contribution, notificationProgressUpdater
|
||||
).onErrorReturn{
|
||||
return@onErrorReturn StashUploadResult(StashUploadState.FAILED,fileKey = null)
|
||||
return@onErrorReturn StashUploadResult(StashUploadState.FAILED,fileKey = null,errorMessage = it.message)
|
||||
}.blockingSingle()
|
||||
|
||||
when (stashUploadResult.state) {
|
||||
|
|
@ -402,10 +405,21 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
|||
}
|
||||
else -> {
|
||||
Timber.e("""upload file to stash failed with status: ${stashUploadResult.state}""")
|
||||
showFailedNotification(contribution)
|
||||
showInvalidLoginNotification(contribution)
|
||||
contribution.state = Contribution.STATE_FAILED
|
||||
contribution.chunkInfo = null
|
||||
contributionDao.saveSynchronous(contribution)
|
||||
if (stashUploadResult.errorMessage.equals(CsrfTokenClient.INVALID_TOKEN_ERROR_MESSAGE)) {
|
||||
Timber.e("Invalid Login, logging out")
|
||||
val username = sessionManager.userName
|
||||
var logoutListener = CommonsApplication.BaseLogoutListener(
|
||||
appContext,
|
||||
appContext.getString(R.string.invalid_login_message),
|
||||
username
|
||||
)
|
||||
CommonsApplication.getInstance()
|
||||
.clearApplicationData(appContext, logoutListener)
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (exception: Exception){
|
||||
|
|
@ -566,6 +580,23 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
|||
curentNotification.build()
|
||||
)
|
||||
}
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
private fun showInvalidLoginNotification(contribution: Contribution) {
|
||||
val displayTitle = contribution.media.displayTitle
|
||||
curentNotification.setContentTitle(
|
||||
appContext.getString(
|
||||
R.string.upload_failed_notification_title,
|
||||
displayTitle
|
||||
)
|
||||
)
|
||||
.setContentText(appContext.getString(R.string.invalid_login_message))
|
||||
.setProgress(0, 0, false)
|
||||
.setOngoing(false)
|
||||
notificationManager?.notify(
|
||||
currentNotificationTag, currentNotificationID,
|
||||
curentNotification.build()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify that the current upload is paused
|
||||
|
|
@ -605,5 +636,4 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -792,6 +792,7 @@ Upload your first media by tapping on the add button.</string>
|
|||
<string name="edit_location">Edit Location</string>
|
||||
<string name="send_thanks_to_author">Thank the author</string>
|
||||
<string name="error_sending_thanks">Error sending thanks to author.</string>
|
||||
<string name="invalid_login_message">Your login has expired, Please login again.</string>
|
||||
<plurals name="custom_picker_images_selected_title_appendix">
|
||||
<item quantity="one">%d image selected</item>
|
||||
<item quantity="other">%d images selected</item>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue