diff --git a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java
index 7801ff82e..67be68ead 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java
@@ -26,7 +26,9 @@ import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
+
import com.nostra13.universalimageloader.core.ImageLoader;
+
import org.fdroid.fdroid.AppUpdateStatusManager;
import org.fdroid.fdroid.AppUpdateStatusManager.AppUpdateStatus;
import org.fdroid.fdroid.R;
@@ -39,7 +41,7 @@ import org.fdroid.fdroid.installer.InstallManagerService;
import org.fdroid.fdroid.installer.Installer;
import org.fdroid.fdroid.installer.InstallerFactory;
import org.fdroid.fdroid.views.AppDetailsActivity;
-import org.fdroid.fdroid.views.updates.DismissResult;
+import org.fdroid.fdroid.views.updates.UpdatesAdapter;
import java.io.File;
import java.util.Iterator;
@@ -206,29 +208,24 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder {
}
/**
- * If able, forwards the request onto {@link #onDismissApp(App)}.
+ * If able, forwards the request onto {@link #onDismissApp(App, UpdatesAdapter)}.
* This mainly exists to keep the API consistent, in that the {@link App} is threaded through to the relevant
* method with a guarantee that it is not null, rather than every method having to check if it is null or not.
*/
- @NonNull
- public final DismissResult onDismiss() {
+ public final void onDismiss(UpdatesAdapter adapter) {
if (currentApp != null && canDismiss()) {
- return onDismissApp(currentApp);
+ onDismissApp(currentApp, adapter);
}
-
- return new DismissResult();
}
/**
* Override to respond to the user swiping an app to dismiss it from the list.
+ * @param app The app that was swiped away
+ * @param updatesAdapter The adapter. Can be used for refreshing the adapter with adapter.refreshStatuses().
*
- * @return Optionally return a description of what you did if it is not obvious to the user. It will be shown as
- * a {@link android.widget.Toast} for a {@link android.widget.Toast#LENGTH_SHORT} time.
* @see #canDismiss() This must also be overriden and should return true.
*/
- @NonNull
- protected DismissResult onDismissApp(@NonNull App app) {
- return new DismissResult();
+ protected void onDismissApp(@NonNull App app, UpdatesAdapter updatesAdapter) {
}
/**
diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/DismissResult.java b/app/src/main/java/org/fdroid/fdroid/views/updates/DismissResult.java
deleted file mode 100644
index f37d58fb4..000000000
--- a/app/src/main/java/org/fdroid/fdroid/views/updates/DismissResult.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.fdroid.fdroid.views.updates;
-
-import android.support.annotation.Nullable;
-
-/**
- * When dismissing an item from the Updates tab, there is two different things we need to return.
- * This is a dumb data object to represent these things, because a method is only allowed to return one thing.
- */
-public class DismissResult {
-
- @Nullable
- public final CharSequence message;
-
- public final boolean requiresAdapterRefresh;
-
- public DismissResult() {
- this(null, false);
- }
-
- public DismissResult(@Nullable CharSequence message, boolean requiresAdapterRefresh) {
- this.message = message;
- this.requiresAdapterRefresh = requiresAdapterRefresh;
- }
-
-}
diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesItemTouchCallback.java b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesItemTouchCallback.java
index 9d7f40296..cde7ae3ac 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesItemTouchCallback.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesItemTouchCallback.java
@@ -1,9 +1,7 @@
package org.fdroid.fdroid.views.updates;
-import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
-import android.widget.Toast;
import org.fdroid.fdroid.views.apps.AppListItemController;
import org.fdroid.fdroid.views.updates.items.AppStatusListItemController;
@@ -33,11 +31,9 @@ import org.fdroid.fdroid.views.updates.items.UpdateableAppListItemController;
*/
public class UpdatesItemTouchCallback extends ItemTouchHelper.Callback {
- private final Context context;
private final UpdatesAdapter adapter;
- public UpdatesItemTouchCallback(Context context, UpdatesAdapter adapter) {
- this.context = context;
+ public UpdatesItemTouchCallback(UpdatesAdapter adapter) {
this.adapter = adapter;
}
@@ -62,15 +58,7 @@ public class UpdatesItemTouchCallback extends ItemTouchHelper.Callback {
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
AppListItemController controller = (AppListItemController) viewHolder;
- DismissResult result = controller.onDismiss();
-
- if (result.message != null) {
- Toast.makeText(context, result.message, Toast.LENGTH_SHORT).show();
- }
-
- if (result.requiresAdapterRefresh) {
- adapter.refreshStatuses();
- }
+ controller.onDismiss(adapter);
}
@Override
diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesViewBinder.java b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesViewBinder.java
index 4e763741b..1a8bf2a56 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesViewBinder.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesViewBinder.java
@@ -32,7 +32,7 @@ public class UpdatesViewBinder {
list.setLayoutManager(new LinearLayoutManager(activity));
list.setAdapter(adapter);
- ItemTouchHelper touchHelper = new ItemTouchHelper(new UpdatesItemTouchCallback(activity, adapter));
+ ItemTouchHelper touchHelper = new ItemTouchHelper(new UpdatesItemTouchCallback(adapter));
touchHelper.attachToRecyclerView(list);
emptyState = (TextView) view.findViewById(R.id.empty_state);
diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/items/AppStatusListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/updates/items/AppStatusListItemController.java
index 2f612ca16..34ee0d502 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/updates/items/AppStatusListItemController.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/updates/items/AppStatusListItemController.java
@@ -3,6 +3,7 @@ package org.fdroid.fdroid.views.updates.items;
import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.design.widget.Snackbar;
import android.view.View;
import org.fdroid.fdroid.AppUpdateStatusManager;
@@ -11,7 +12,7 @@ import org.fdroid.fdroid.R;
import org.fdroid.fdroid.data.App;
import org.fdroid.fdroid.views.apps.AppListItemController;
import org.fdroid.fdroid.views.apps.AppListItemState;
-import org.fdroid.fdroid.views.updates.DismissResult;
+import org.fdroid.fdroid.views.updates.UpdatesAdapter;
/**
* Shows apps which are:
@@ -52,22 +53,41 @@ public class AppStatusListItemController extends AppListItemController {
return true;
}
- @NonNull
@Override
- protected DismissResult onDismissApp(@NonNull App app) {
+ protected void onDismissApp(@NonNull final App app, final UpdatesAdapter adapter) {
AppUpdateStatus status = getCurrentStatus();
- CharSequence message = null;
if (status != null) {
- AppUpdateStatusManager manager = AppUpdateStatusManager.getInstance(activity);
+ final AppUpdateStatusManager manager = AppUpdateStatusManager.getInstance(activity);
+ final AppUpdateStatus appUpdateStatus = manager.get(status.getCanonicalUrl());
manager.removeApk(status.getCanonicalUrl());
+
+
switch (status.status) {
+
case Downloading:
cancelDownload();
- message = activity.getString(R.string.app_list__dismiss_downloading_app);
+ Snackbar.make(itemView, R.string.app_list__dismiss_downloading_app, Snackbar.LENGTH_SHORT).show();
break;
+
+ case ReadyToInstall:
+ if (appUpdateStatus != null) {
+ Snackbar.make(
+ itemView,
+ R.string.app_list__dismiss_installing_app,
+ Snackbar.LENGTH_LONG
+ ).setAction(R.string.undo, new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ manager.addApk(appUpdateStatus.apk, appUpdateStatus.status, appUpdateStatus.intent);
+ adapter.refreshStatuses();
+ }
+ }).show();
+ break;
+ }
}
}
- return new DismissResult(message, true);
+ adapter.refreshStatuses();
}
+
}
diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java
index 0d1ac37dd..451f0118a 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java
@@ -7,8 +7,10 @@ import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.design.widget.Snackbar;
import android.support.v4.content.LocalBroadcastManager;
import android.view.View;
+
import org.fdroid.fdroid.AppUpdateStatusManager;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.data.Apk;
@@ -22,7 +24,7 @@ import org.fdroid.fdroid.installer.Installer;
import org.fdroid.fdroid.installer.InstallerService;
import org.fdroid.fdroid.views.apps.AppListItemController;
import org.fdroid.fdroid.views.apps.AppListItemState;
-import org.fdroid.fdroid.views.updates.DismissResult;
+import org.fdroid.fdroid.views.updates.UpdatesAdapter;
/**
* Tell the user that an app they have installed has a known vulnerability.
@@ -86,11 +88,9 @@ public class KnownVulnAppListItemController extends AppListItemController {
return true;
}
- @NonNull
@Override
- protected DismissResult onDismissApp(@NonNull App app) {
+ protected void onDismissApp(@NonNull final App app, UpdatesAdapter adapter) {
this.ignoreVulnerableApp(app);
- return new DismissResult(activity.getString(R.string.app_list__dismiss_vulnerable_app), false);
}
@Override
@@ -98,9 +98,26 @@ public class KnownVulnAppListItemController extends AppListItemController {
this.ignoreVulnerableApp(app);
}
- private void ignoreVulnerableApp(@NonNull App app) {
+ private void ignoreVulnerableApp(@NonNull final App app) {
+ setIgnoreVulnerableApp(app, true);
+
+ Snackbar.make(
+ itemView,
+ R.string.app_list__dismiss_vulnerable_app,
+ Snackbar.LENGTH_LONG
+ )
+ .setAction(R.string.undo, new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ setIgnoreVulnerableApp(app, false);
+ }
+ })
+ .show();
+ }
+
+ private void setIgnoreVulnerableApp(@NonNull App app, boolean ignore) {
AppPrefs prefs = app.getPrefs(activity);
- prefs.ignoreVulnerabilities = true;
+ prefs.ignoreVulnerabilities = ignore;
AppPrefsProvider.Helper.update(activity, app, prefs);
refreshUpdatesList();
}
diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/items/UpdateableAppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/updates/items/UpdateableAppListItemController.java
index 5baa5f89e..34c3bc6df 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/updates/items/UpdateableAppListItemController.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/updates/items/UpdateableAppListItemController.java
@@ -3,6 +3,7 @@ package org.fdroid.fdroid.views.updates.items;
import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.design.widget.Snackbar;
import android.view.View;
import org.fdroid.fdroid.AppUpdateStatusManager;
@@ -12,7 +13,7 @@ import org.fdroid.fdroid.data.AppPrefs;
import org.fdroid.fdroid.data.AppPrefsProvider;
import org.fdroid.fdroid.views.apps.AppListItemController;
import org.fdroid.fdroid.views.apps.AppListItemState;
-import org.fdroid.fdroid.views.updates.DismissResult;
+import org.fdroid.fdroid.views.updates.UpdatesAdapter;
/**
* Very trimmed down list item. Only displays the app icon, name, and a download button.
@@ -39,14 +40,27 @@ public class UpdateableAppListItemController extends AppListItemController {
}
@Override
- @NonNull
- protected DismissResult onDismissApp(@NonNull App app) {
- AppPrefs prefs = app.getPrefs(activity);
+ protected void onDismissApp(@NonNull final App app, UpdatesAdapter adapter) {
+ final AppPrefs prefs = app.getPrefs(activity);
prefs.ignoreThisUpdate = app.suggestedVersionCode;
+ Snackbar.make(
+ itemView,
+ R.string.app_list__dismiss_app_update,
+ Snackbar.LENGTH_LONG
+ )
+ .setAction(R.string.undo, new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ prefs.ignoreThisUpdate = 0;
+ AppPrefsProvider.Helper.update(activity, app, prefs);
+ }
+ })
+ .show();
+
+
// The act of updating here will trigger a re-query of the "can update" apps, so no need to do anything else
// to update the UI in response to this.
AppPrefsProvider.Helper.update(activity, app, prefs);
- return new DismissResult(activity.getString(R.string.app_list__dismiss_app_update), false);
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 06104328a..2137c088b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -619,7 +619,9 @@ This often occurs with apps installed via Google Play or other sources, if they
Updated today
Your camera doesn\'t seem to have an autofocus. It might be difficult to scan the code.
-
+ Undo
+ Installation cancelled
+
- Updated %1$d day ago
- Updated %1$d days ago