diff --git a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusService.java b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusService.java index 94cc3e26a..f9b0e370c 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusService.java +++ b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusService.java @@ -22,6 +22,9 @@ import java.util.List; * {@link AppUpdateStatusManager.Status#ReadyToInstall}. This is an {@link IntentService} so as to * run on a background thread, as it hits the disk a bit to figure out the hash of each downloaded * file. + * + * TODO: Deal with more than just the suggested version. It should also work for people downloading earlier versions (but still newer than their current) + * TODO: Identify new apps which have not been installed before, but which have been downloading. Currently only works for updates. */ public class AppUpdateStatusService extends IntentService { 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 c6f831c97..a2de4f01f 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 @@ -126,6 +126,10 @@ public class AppListItemController extends RecyclerView.ViewHolder { cancelButton = (ImageButton) itemView.findViewById(R.id.cancel_button); actionButton = (Button) itemView.findViewById(R.id.action_button); + if (actionButton != null) { + actionButton.setOnClickListener(onInstallClicked); + } + if (cancelButton != null) { cancelButton.setOnClickListener(onCancelDownload); } @@ -137,7 +141,6 @@ public class AppListItemController extends RecyclerView.ViewHolder { public void bindModel(@NonNull App app) { currentApp = app; - name.setText(Utils.formatAppNameAndSummary(app.name, app.summary)); ImageLoader.getInstance().displayImage(app.iconUrl, icon, displayImageOptions); @@ -151,6 +154,7 @@ public class AppListItemController extends RecyclerView.ViewHolder { broadcastManager.registerReceiver(onDownloadProgress, DownloaderService.getIntentFilter(currentAppDownloadUrl)); broadcastManager.registerReceiver(onInstallAction, Installer.getInstallIntentFilter(Uri.parse(currentAppDownloadUrl))); + configureAppName(app); configureStatusText(app); configureInstalledVersion(app); configureIgnoredStatus(app); @@ -163,8 +167,6 @@ public class AppListItemController extends RecyclerView.ViewHolder { * * Is compatible with the users device * * Is installed * * Can be updated - * - * TODO: This button also needs to be repurposed to support the "Downloaded but not installed" state. */ private void configureStatusText(@NonNull App app) { if (status == null) { @@ -226,6 +228,10 @@ public class AppListItemController extends RecyclerView.ViewHolder { } } + /** + * Queries the {@link AppUpdateStatusManager} to find out if there are any apks corresponding to + * `app` which are ready to install. + */ private boolean isReadyToInstall(@NonNull App app) { for (AppUpdateStatusManager.AppUpdateStatus appStatus : AppUpdateStatusManager.getInstance(activity).getByPackageName(app.packageName)) { if (appStatus.status == AppUpdateStatusManager.Status.ReadyToInstall) { @@ -235,6 +241,38 @@ public class AppListItemController extends RecyclerView.ViewHolder { return false; } + /** + * Queries the {@link AppUpdateStatusManager} to find out if there are any apks corresponding to + * `app` which are in the process of being downloaded. + */ + private boolean isDownloading(@NonNull App app) { + for (AppUpdateStatusManager.AppUpdateStatus appStatus : AppUpdateStatusManager.getInstance(activity).getByPackageName(app.packageName)) { + if (appStatus.status == AppUpdateStatusManager.Status.Downloading) { + return true; + } + } + return false; + } + + /** + * The app name {@link TextView} is used for a few reasons: + * * Display name + summary of the app (most common). + * * If downloading, mention that it is downloading instead of showing the summary. + * * If downloaded and ready to install, mention that it is ready to update/install. + */ + private void configureAppName(@NonNull App app) { + if (isReadyToInstall(app)) { + if (app.isInstalled()) { + name.setText(activity.getString(R.string.app_list__name__downloaded_and_ready_to_update, app.name)); + } else { + name.setText(activity.getString(R.string.app_list__name__downloaded_and_ready_to_install, app.name)); + } + } else if (isDownloading(app)) { + name.setText(activity.getString(R.string.app_list__name__downloading_in_progress, app.name)); + } else { + name.setText(Utils.formatAppNameAndSummary(app.name, app.summary)); + } + } /** * The action button will either tell the user to "Update" or "Install" the app. Both actually do @@ -246,15 +284,7 @@ public class AppListItemController extends RecyclerView.ViewHolder { return; } - boolean readyToInstall = false; - for (AppUpdateStatusManager.AppUpdateStatus status : AppUpdateStatusManager.getInstance(activity).getByPackageName(app.packageName)) { - if (status.status == AppUpdateStatusManager.Status.ReadyToInstall) { - readyToInstall = true; - break; - } - } - - if (!readyToInstall) { + if (!isReadyToInstall(app)) { actionButton.setVisibility(View.GONE); } else { actionButton.setVisibility(View.VISIBLE); @@ -271,8 +301,6 @@ public class AppListItemController extends RecyclerView.ViewHolder { * * Is compatible with the users device. * * Has not been filtered due to anti-features/root/etc. * * Is either not installed or installed but can be updated. - * - * TODO: This button also needs to be repurposed to support the "Downloaded but not installed" state. */ private void configureInstallButton(@NonNull App app) { if (installButton == null) { @@ -382,6 +410,8 @@ public class AppListItemController extends RecyclerView.ViewHolder { return; } + configureAppName(currentApp); + if (Downloader.ACTION_STARTED.equals(intent.getAction())) { onDownloadStarted(); } else if (Downloader.ACTION_PROGRESS.equals(intent.getAction())) { @@ -401,6 +431,8 @@ public class AppListItemController extends RecyclerView.ViewHolder { return; } + configureAppName(currentApp); + Apk apk = intent.getParcelableExtra(Installer.EXTRA_APK); if (!TextUtils.equals(apk.packageName, currentApp.packageName)) { return; diff --git a/app/src/main/res/layout/updateable_app_status_item.xml b/app/src/main/res/layout/updateable_app_status_item.xml index 2272c480b..3d71775fc 100644 --- a/app/src/main/res/layout/updateable_app_status_item.xml +++ b/app/src/main/res/layout/updateable_app_status_item.xml @@ -26,7 +26,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" tools:text="F-Droid Application manager with a long name that will wrap and then ellipsize" - android:textSize="18sp" + android:textSize="16sp" android:textColor="#424242" android:maxLines="2" android:ellipsize="end" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index aa07b58e3..d5cf893e1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -70,6 +70,10 @@ Added on %s Update + Update %1$s + Install %1$s + Downloading %1$s + Installed Apps Updates ignored Updates ignored for Version %1$s