Merge branch 'new-ui--minor-ui-tweaks' into 'master'
Minor ui tweaks Closes #896, #894, and #839 See merge request !453
This commit is contained in:
commit
befdc4a850
3
.gitignore
vendored
3
.gitignore
vendored
@ -43,3 +43,6 @@ extern/*/*/libs/
|
||||
|
||||
# Tests
|
||||
junit-report.xml
|
||||
|
||||
# Screen dumps from Android Studio/DDMS
|
||||
captures/
|
||||
|
@ -107,7 +107,6 @@ public class AppDetails extends AppCompatActivity {
|
||||
private static final int REQUEST_PERMISSION_DIALOG = 3;
|
||||
private static final int REQUEST_UNINSTALL_DIALOG = 4;
|
||||
|
||||
public static final String EXTRA_APPID = "appid";
|
||||
public static final String EXTRA_FROM = "from";
|
||||
public static final String EXTRA_HINT_SEARCHING = "searching";
|
||||
|
||||
@ -351,12 +350,12 @@ public class AppDetails extends AppCompatActivity {
|
||||
* and not externally.
|
||||
*/
|
||||
private String getPackageNameFromIntent(Intent intent) {
|
||||
if (!intent.hasExtra(EXTRA_APPID)) {
|
||||
if (!intent.hasExtra(AppDetails2.EXTRA_APPID)) {
|
||||
Log.e(TAG, "No package name found in the intent!");
|
||||
return null;
|
||||
}
|
||||
|
||||
return intent.getStringExtra(EXTRA_APPID);
|
||||
return intent.getStringExtra(AppDetails2.EXTRA_APPID);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,6 +53,7 @@ import org.fdroid.fdroid.views.apps.FeatureImage;
|
||||
|
||||
public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog.ShareChooserDialogListener, AppDetailsRecyclerViewAdapter.AppDetailsRecyclerViewAdapterCallbacks {
|
||||
|
||||
public static final String EXTRA_APPID = "appid";
|
||||
private static final String TAG = "AppDetails2";
|
||||
|
||||
private static final int REQUEST_ENABLE_BLUETOOTH = 2;
|
||||
@ -170,11 +171,11 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
|
||||
}
|
||||
|
||||
private String getPackageNameFromIntent(Intent intent) {
|
||||
if (!intent.hasExtra(AppDetails.EXTRA_APPID)) {
|
||||
if (!intent.hasExtra(EXTRA_APPID)) {
|
||||
Log.e(TAG, "No package name found in the intent!");
|
||||
return null;
|
||||
}
|
||||
return intent.getStringExtra(AppDetails.EXTRA_APPID);
|
||||
return intent.getStringExtra(EXTRA_APPID);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -392,16 +392,16 @@ public final class AppUpdateStatusManager {
|
||||
|
||||
/**
|
||||
* Get a {@link PendingIntent} for a {@link Notification} to send when it
|
||||
* is clicked. {@link AppDetails} handles {@code Intent}s that are missing
|
||||
* or bad {@link AppDetails#EXTRA_APPID}, so it does not need to be checked
|
||||
* is clicked. {@link AppDetails2} handles {@code Intent}s that are missing
|
||||
* or bad {@link AppDetails2#EXTRA_APPID}, so it does not need to be checked
|
||||
* here.
|
||||
*/
|
||||
private PendingIntent getAppDetailsIntent(Apk apk) {
|
||||
Intent notifyIntent = new Intent(context, AppDetails.class)
|
||||
.putExtra(AppDetails.EXTRA_APPID, apk.packageName);
|
||||
Intent notifyIntent = new Intent(context, AppDetails2.class)
|
||||
.putExtra(AppDetails2.EXTRA_APPID, apk.packageName);
|
||||
|
||||
return TaskStackBuilder.create(context)
|
||||
.addParentStack(AppDetails.class)
|
||||
.addParentStack(AppDetails2.class)
|
||||
.addNextIntent(notifyIntent)
|
||||
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.data.AppProvider;
|
||||
import org.fdroid.fdroid.data.Schema;
|
||||
import org.fdroid.fdroid.installer.ApkCache;
|
||||
import org.fdroid.fdroid.installer.InstallManagerService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -53,5 +54,6 @@ public class AppUpdateStatusService extends IntentService {
|
||||
}
|
||||
|
||||
AppUpdateStatusManager.getInstance(this).addApks(apksReadyToInstall, AppUpdateStatusManager.Status.ReadyToInstall);
|
||||
InstallManagerService.managePreviouslyDownloadedApks(this);
|
||||
}
|
||||
}
|
@ -243,7 +243,7 @@ public class FDroid extends AppCompatActivity implements SearchView.OnQueryTextL
|
||||
if (!TextUtils.isEmpty(packageName)) {
|
||||
Utils.debugLog(TAG, "FDroid launched via app link for '" + packageName + "'");
|
||||
Intent intentToInvoke = new Intent(this, AppDetails2.class);
|
||||
intentToInvoke.putExtra(AppDetails.EXTRA_APPID, packageName);
|
||||
intentToInvoke.putExtra(AppDetails2.EXTRA_APPID, packageName);
|
||||
startActivity(intentToInvoke);
|
||||
finish();
|
||||
} else if (!TextUtils.isEmpty(query)) {
|
||||
|
@ -185,7 +185,7 @@ class NotificationHelper {
|
||||
if (entry.status == AppUpdateStatusManager.Status.Unknown) {
|
||||
return true;
|
||||
} else if ((entry.status == AppUpdateStatusManager.Status.Downloading || entry.status == AppUpdateStatusManager.Status.ReadyToInstall || entry.status == AppUpdateStatusManager.Status.InstallError) &&
|
||||
(AppDetails.isAppVisible(entry.app.packageName) || AppDetails2.isAppVisible(entry.app.packageName))) {
|
||||
AppDetails2.isAppVisible(entry.app.packageName)) {
|
||||
// Ignore downloading, readyToInstall and installError if we are showing the details screen for this app
|
||||
return true;
|
||||
}
|
||||
|
@ -68,6 +68,16 @@ public class InstallManagerService extends Service {
|
||||
private static final String ACTION_INSTALL = "org.fdroid.fdroid.installer.action.INSTALL";
|
||||
private static final String ACTION_CANCEL = "org.fdroid.fdroid.installer.action.CANCEL";
|
||||
|
||||
/**
|
||||
* The install manager service needs to monitor downloaded apks so that it can wait for a user to
|
||||
* install them and respond accordingly. Usually the thing which starts listening for such events
|
||||
* does so directly after a download is complete. This works great, except when the user then
|
||||
* subsequently closes F-Droid and opens it at a later date. Under these circumstances, a background
|
||||
* service will scan all downloaded apks and notify the user about them. When it does so, the
|
||||
* install manager service needs to add listeners for if the apks get installed.
|
||||
*/
|
||||
private static final String ACTION_MANAGE_DOWNLOADED_APKS = "org.fdroid.fdroid.installer.action.ACTION_MANAGE_DOWNLOADED_APKS";
|
||||
|
||||
private static final String EXTRA_APP = "org.fdroid.fdroid.installer.extra.APP";
|
||||
private static final String EXTRA_APK = "org.fdroid.fdroid.installer.extra.APK";
|
||||
|
||||
@ -108,13 +118,19 @@ public class InstallManagerService extends Service {
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Utils.debugLog(TAG, "onStartCommand " + intent);
|
||||
|
||||
String action = intent.getAction();
|
||||
|
||||
if (ACTION_MANAGE_DOWNLOADED_APKS.equals(action)) {
|
||||
registerInstallerReceiversForDownlaodedApks();
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
|
||||
String urlString = intent.getDataString();
|
||||
if (TextUtils.isEmpty(urlString)) {
|
||||
Utils.debugLog(TAG, "empty urlString, nothing to do");
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
|
||||
String action = intent.getAction();
|
||||
if (ACTION_CANCEL.equals(action)) {
|
||||
DownloaderService.cancel(this, urlString);
|
||||
Apk apk = appUpdateStatusManager.getApk(urlString);
|
||||
@ -292,6 +308,20 @@ public class InstallManagerService extends Service {
|
||||
DownloaderService.getIntentFilter(urlString));
|
||||
}
|
||||
|
||||
/**
|
||||
* For each app in the {@link AppUpdateStatusManager.Status#ReadyToInstall} state, setup listeners
|
||||
* so that if the user installs it then we can respond accordingly. This makes sure that whether
|
||||
* the user just finished downloading it, or whether they downloaded it a day ago but have not yet
|
||||
* installed it, we get the same experience upon completing an install.
|
||||
*/
|
||||
private void registerInstallerReceiversForDownlaodedApks() {
|
||||
for (AppUpdateStatusManager.AppUpdateStatus appStatus : AppUpdateStatusManager.getInstance(this).getAll()) {
|
||||
if (appStatus.status == AppUpdateStatusManager.Status.ReadyToInstall) {
|
||||
registerInstallerReceivers(Uri.parse(appStatus.getUniqueKey()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerInstallerReceivers(Uri downloadUri) {
|
||||
|
||||
BroadcastReceiver installReceiver = new BroadcastReceiver() {
|
||||
@ -363,4 +393,10 @@ public class InstallManagerService extends Service {
|
||||
intent.setData(Uri.parse(urlString));
|
||||
context.startService(intent);
|
||||
}
|
||||
|
||||
public static void managePreviouslyDownloadedApks(Context context) {
|
||||
Intent intent = new Intent(context, InstallManagerService.class);
|
||||
intent.setAction(ACTION_MANAGE_DOWNLOADED_APKS);
|
||||
context.startService(intent);
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ public class AppListActivity extends AppCompatActivity implements LoaderManager.
|
||||
|
||||
public static final String EXTRA_CATEGORY = "org.fdroid.fdroid.views.apps.AppListActivity.EXTRA_CATEGORY";
|
||||
public static final String EXTRA_SEARCH_TERMS = "org.fdroid.fdroid.views.apps.AppListActivity.EXTRA_SEARCH_TERMS";
|
||||
|
||||
private RecyclerView appView;
|
||||
private AppListAdapter appAdapter;
|
||||
private String category;
|
||||
@ -78,12 +79,11 @@ public class AppListActivity extends AppCompatActivity implements LoaderManager.
|
||||
appView.setHasFixedSize(true);
|
||||
appView.setLayoutManager(new LinearLayoutManager(this));
|
||||
appView.setAdapter(appAdapter);
|
||||
|
||||
parseIntentForSearchQuery();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
private void parseIntentForSearchQuery() {
|
||||
Intent intent = getIntent();
|
||||
category = intent.hasExtra(EXTRA_CATEGORY) ? intent.getStringExtra(EXTRA_CATEGORY) : null;
|
||||
searchTerms = intent.hasExtra(EXTRA_SEARCH_TERMS) ? intent.getStringExtra(EXTRA_SEARCH_TERMS) : null;
|
||||
|
@ -29,7 +29,6 @@ import android.widget.TextView;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
|
||||
import org.fdroid.fdroid.AppDetails;
|
||||
import org.fdroid.fdroid.AppDetails2;
|
||||
import org.fdroid.fdroid.AppUpdateStatusManager;
|
||||
import org.fdroid.fdroid.R;
|
||||
@ -254,6 +253,18 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the {@link AppUpdateStatusManager} and asks if the app was just successfully installed.
|
||||
*/
|
||||
private boolean wasSuccessfullyInstalled(@NonNull App app) {
|
||||
for (AppUpdateStatusManager.AppUpdateStatus appStatus : AppUpdateStatusManager.getInstance(activity).getByPackageName(app.packageName)) {
|
||||
if (appStatus.status == AppUpdateStatusManager.Status.Installed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The app name {@link TextView} is used for a few reasons:
|
||||
* * Display name + summary of the app (most common).
|
||||
@ -277,6 +288,8 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
}
|
||||
} else if (isDownloading(app)) {
|
||||
name.setText(activity.getString(R.string.app_list__name__downloading_in_progress, app.name));
|
||||
} else if (wasSuccessfullyInstalled(app)) {
|
||||
name.setText(activity.getString(R.string.app_list__name__successfully_installed, app.name));
|
||||
} else {
|
||||
name.setText(Utils.formatAppNameAndSummary(app.name, app.summary));
|
||||
}
|
||||
@ -396,7 +409,7 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
}
|
||||
|
||||
Intent intent = new Intent(activity, AppDetails2.class);
|
||||
intent.putExtra(AppDetails.EXTRA_APPID, currentApp.packageName);
|
||||
intent.putExtra(AppDetails2.EXTRA_APPID, currentApp.packageName);
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
Pair<View, String> iconTransitionPair = Pair.create((View) icon, activity.getString(R.string.transition_app_item_icon));
|
||||
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, iconTransitionPair).toBundle();
|
||||
|
@ -22,7 +22,6 @@ import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||
|
||||
import org.fdroid.fdroid.AppDetails;
|
||||
import org.fdroid.fdroid.AppDetails2;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
@ -129,7 +128,7 @@ public class AppCardController extends RecyclerView.ViewHolder implements ImageL
|
||||
}
|
||||
|
||||
Intent intent = new Intent(activity, AppDetails2.class);
|
||||
intent.putExtra(AppDetails.EXTRA_APPID, currentApp.packageName);
|
||||
intent.putExtra(AppDetails2.EXTRA_APPID, currentApp.packageName);
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
Pair<View, String> iconTransitionPair = Pair.create((View) icon, activity.getString(R.string.transition_app_item_icon));
|
||||
|
||||
|
@ -169,7 +169,7 @@ public abstract class AppListFragment extends ListFragment implements
|
||||
if (cursor != null) {
|
||||
final App app = new App(cursor);
|
||||
Intent intent = getAppDetailsIntent(useNewDetailsActivity);
|
||||
intent.putExtra(AppDetails.EXTRA_APPID, app.packageName);
|
||||
intent.putExtra(AppDetails2.EXTRA_APPID, app.packageName);
|
||||
intent.putExtra(AppDetails.EXTRA_FROM, getFromTitle());
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
Pair<View, String> iconTransitionPair = Pair.create(view.findViewById(R.id.icon),
|
||||
|
@ -13,12 +13,13 @@ import android.preference.PreferenceCategory;
|
||||
import android.support.v4.preference.PreferenceFragment;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.fdroid.fdroid.AppDetails;
|
||||
import org.fdroid.fdroid.AppDetails2;
|
||||
import org.fdroid.fdroid.CleanCacheService;
|
||||
import org.fdroid.fdroid.FDroidApp;
|
||||
import org.fdroid.fdroid.Preferences;
|
||||
import org.fdroid.fdroid.PreferencesActivity;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.UpdateService;
|
||||
import org.fdroid.fdroid.installer.InstallHistoryService;
|
||||
import org.fdroid.fdroid.installer.PrivilegedInstaller;
|
||||
|
||||
@ -261,8 +262,8 @@ public class PreferencesFragment extends PreferenceFragment
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
// Open details of F-Droid Privileged
|
||||
Intent intent = new Intent(getActivity(), AppDetails.class);
|
||||
intent.putExtra(AppDetails.EXTRA_APPID,
|
||||
Intent intent = new Intent(getActivity(), AppDetails2.class);
|
||||
intent.putExtra(AppDetails2.EXTRA_APPID,
|
||||
PrivilegedInstaller.PRIVILEGED_EXTENSION_PACKAGE_NAME);
|
||||
startActivity(intent);
|
||||
|
||||
@ -271,21 +272,34 @@ public class PreferencesFragment extends PreferenceFragment
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
/**
|
||||
* If a user specifies they want to fetch updates automatically, then start the download of relevant
|
||||
* updates as soon as they enable the feature.
|
||||
* Also, if the user has the priv extention installed then change the label to indicate that it
|
||||
* will actually _install_ apps, not just fetch their .apk file automatically.
|
||||
*/
|
||||
private void initAutoFetchUpdatesPreference() {
|
||||
updateAutoDownloadPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
|
||||
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (newValue instanceof Boolean && (boolean) newValue) {
|
||||
UpdateService.autoDownloadUpdates(getContext());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
for (final String key : SUMMARIES_TO_UPDATE) {
|
||||
updateSummary(key, false);
|
||||
if (PrivilegedInstaller.isDefault(getContext())) {
|
||||
updateAutoDownloadPref.setTitle(R.string.update_auto_install);
|
||||
updateAutoDownloadPref.setSummary(R.string.update_auto_install_summary);
|
||||
}
|
||||
}
|
||||
|
||||
currentKeepCacheTime = Preferences.get().getKeepCacheTime();
|
||||
|
||||
initPrivilegedInstallerPreference();
|
||||
initUpdatePrivilegedExtensionPreference();
|
||||
// this pref's default is dynamically set based on whether Orbot is installed
|
||||
/**
|
||||
* The default for "Use Tor" is dynamically set based on whether Orbot is installed.
|
||||
*/
|
||||
private void initUseTorPreference() {
|
||||
boolean useTor = Preferences.get().isTorEnabled();
|
||||
useTorCheckPref.setDefaultValue(useTor);
|
||||
useTorCheckPref.setChecked(useTor);
|
||||
@ -308,11 +322,24 @@ public class PreferencesFragment extends PreferenceFragment
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (PrivilegedInstaller.isDefault(getContext())) {
|
||||
updateAutoDownloadPref.setTitle(R.string.update_auto_install);
|
||||
updateAutoDownloadPref.setSummary(R.string.update_auto_install_summary);
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||
|
||||
for (final String key : SUMMARIES_TO_UPDATE) {
|
||||
updateSummary(key, false);
|
||||
}
|
||||
|
||||
currentKeepCacheTime = Preferences.get().getKeepCacheTime();
|
||||
|
||||
initAutoFetchUpdatesPreference();
|
||||
initPrivilegedInstallerPreference();
|
||||
initUpdatePrivilegedExtensionPreference();
|
||||
initUseTorPreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -23,7 +23,6 @@ import com.ashokvarma.bottomnavigation.BadgeItem;
|
||||
import com.ashokvarma.bottomnavigation.BottomNavigationBar;
|
||||
import com.ashokvarma.bottomnavigation.BottomNavigationItem;
|
||||
|
||||
import org.fdroid.fdroid.AppDetails;
|
||||
import org.fdroid.fdroid.AppDetails2;
|
||||
import org.fdroid.fdroid.AppUpdateStatusManager;
|
||||
import org.fdroid.fdroid.FDroidApp;
|
||||
@ -281,7 +280,7 @@ public class MainActivity extends AppCompatActivity implements BottomNavigationB
|
||||
if (!TextUtils.isEmpty(packageName)) {
|
||||
Utils.debugLog(TAG, "FDroid launched via app link for '" + packageName + "'");
|
||||
Intent intentToInvoke = new Intent(this, AppDetails2.class);
|
||||
intentToInvoke.putExtra(AppDetails.EXTRA_APPID, packageName);
|
||||
intentToInvoke.putExtra(AppDetails2.EXTRA_APPID, packageName);
|
||||
startActivity(intentToInvoke);
|
||||
finish();
|
||||
} else if (!TextUtils.isEmpty(query)) {
|
||||
|
@ -69,7 +69,8 @@ class MainViewAdapter extends RecyclerView.Adapter<MainViewController> {
|
||||
holder.bindSwapView();
|
||||
break;
|
||||
case R.id.updates:
|
||||
holder.bindUpdates();
|
||||
// Hold of until onViewAttachedToWindow, because that is where we want to start listening
|
||||
// for broadcast events (which is what the data binding does).
|
||||
break;
|
||||
case R.id.settings:
|
||||
holder.bindSettingsView();
|
||||
|
@ -8,6 +8,7 @@ import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.views.fragments.PreferencesFragment;
|
||||
@ -75,6 +76,11 @@ class MainViewController extends RecyclerView.ViewHolder {
|
||||
public void bindSwapView() {
|
||||
View swapView = activity.getLayoutInflater().inflate(R.layout.main_tab_swap, frame, true);
|
||||
|
||||
// To allow for whitelabel versions of F-Droid, make sure not to hardcode "F-Droid" into our
|
||||
// translation here.
|
||||
TextView subtext = (TextView) swapView.findViewById(R.id.text2);
|
||||
subtext.setText(activity.getString(R.string.nearby_splash__both_parties_need_fdroid, activity.getString(R.string.app_name)));
|
||||
|
||||
Button startButton = (Button) swapView.findViewById(R.id.button);
|
||||
startButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
@ -57,6 +57,9 @@ import java.util.List;
|
||||
* repopulate it from the original source lists of data. When this is done, the adapter will notify
|
||||
* the recycler view that its data has changed. Sometimes it will also ask the recycler view to
|
||||
* scroll to the newly added item (if attached to the recycler view).
|
||||
*
|
||||
* TODO: If a user downloads an old version of an app (resulting in a new update being available
|
||||
* instantly), then we need to refresh the list of apps to update.
|
||||
*/
|
||||
public class UpdatesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
@ -84,16 +87,12 @@ public class UpdatesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||
.addDelegate(new UpdateableApp.Delegate(activity))
|
||||
.addDelegate(new UpdateableAppsHeader.Delegate(activity));
|
||||
|
||||
populateAppStatuses();
|
||||
notifyDataSetChanged();
|
||||
|
||||
activity.getSupportLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* There are some statuses managed by {@link AppUpdateStatusManager} which we don't care about
|
||||
* for the "Updates" view. For example {@link org.fdroid.fdroid.AppUpdateStatusManager.Status#Installed}
|
||||
* apps are not interesting in the Updates" view at this point in time. Also, although this
|
||||
* for the "Updates" view. For example Also, although this
|
||||
* adapter does know about apps with updates availble, it does so by querying the database not
|
||||
* by querying the app update status manager. As such, apps with the status
|
||||
* {@link org.fdroid.fdroid.AppUpdateStatusManager.Status#UpdateAvailable} are not interesting here.
|
||||
@ -101,6 +100,7 @@ public class UpdatesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||
private boolean shouldShowStatus(AppUpdateStatusManager.AppUpdateStatus status) {
|
||||
return status.status == AppUpdateStatusManager.Status.Unknown ||
|
||||
status.status == AppUpdateStatusManager.Status.Downloading ||
|
||||
status.status == AppUpdateStatusManager.Status.Installed ||
|
||||
status.status == AppUpdateStatusManager.Status.ReadyToInstall;
|
||||
}
|
||||
|
||||
@ -245,11 +245,18 @@ public class UpdatesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||
public void onLoaderReset(Loader<Cursor> loader) { }
|
||||
|
||||
/**
|
||||
* If this adapter is "active" then it is part of the current UI that the user is looking to.
|
||||
* Under those circumstances, we want to make sure it is up to date, and also listen to the
|
||||
* correct set of broadcasts.
|
||||
* Doesn't listen for {@link AppUpdateStatusManager#BROADCAST_APPSTATUS_CHANGED} because the
|
||||
* individual items in the recycler view will listen for the appropriate changes in state and
|
||||
* update themselves accordingly (if they are displayed).
|
||||
*/
|
||||
public void listenForStatusUpdates() {
|
||||
public void setIsActive() {
|
||||
appsToShowStatus.clear();
|
||||
populateAppStatuses();
|
||||
notifyDataSetChanged();
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(AppUpdateStatusManager.BROADCAST_APPSTATUS_ADDED);
|
||||
filter.addAction(AppUpdateStatusManager.BROADCAST_APPSTATUS_REMOVED);
|
||||
|
@ -24,7 +24,7 @@ public class UpdatesViewBinder {
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
adapter.listenForStatusUpdates();
|
||||
adapter.setIsActive();
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
|
6
app/src/main/res/drawable/nearby_splash.xml
Normal file
6
app/src/main/res/drawable/nearby_splash.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<vector android:height="24dp" android:viewportHeight="634.0"
|
||||
android:viewportWidth="720.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillAlpha="1" android:fillColor="#f9f9f9"
|
||||
android:pathData="M105,0L105,321.3L0,387.7L0,405.9L105,339.5L105,392L104.6,392L104.6,407.5L105,407.5L105,633L120,633L120,407.5L209,407.5L209,633L224,633L224,407.5L393,407.5L498.7,633.1L514.6,633.6L408.7,407.5L624.5,407.5L624.5,633L639.5,633L639.5,470.5L720,435.9L720,419L639.5,453.6L639.5,67.1L720,67.1L720,51.5L120,51.5L120,0L105,0zM120,67.1L233.4,67.1L385.7,392L120,392L120,67.1zM249.1,67.1L624.5,67.1L624.5,392L401.4,392L249.1,67.1z"
|
||||
android:strokeColor="#00000000" android:strokeWidth="1"/>
|
||||
</vector>
|
@ -151,7 +151,6 @@
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="marquee"
|
||||
android:padding="12dp"
|
||||
tools:text="THIS IS 2" />
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -4,60 +4,66 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@drawable/swap_start_header"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
android:layout_height="match_parent"
|
||||
android:background="#FAFAFA">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Download apps from people near you."
|
||||
android:layout_marginEnd="48dp"
|
||||
android:layout_marginLeft="48dp"
|
||||
android:layout_marginRight="48dp"
|
||||
android:layout_marginStart="48dp"
|
||||
android:layout_marginTop="48dp"
|
||||
android:text="@string/nearby_splash__download_apps_from_people_nearby"
|
||||
android:textAlignment="center"
|
||||
android:textSize="20sp"
|
||||
android:textAlignment="center"
|
||||
app:layout_constraintTop_toBottomOf="@+id/image"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:textColor="#4a4a4a"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginEnd="48dp"
|
||||
android:layout_marginRight="48dp"
|
||||
android:layout_marginStart="48dp"
|
||||
android:layout_marginLeft="48dp" />
|
||||
|
||||
<!-- TODO: Use @string/app_name instead of "F-Droid". -->
|
||||
<!-- TODO: The swap process helps to get F-Droid to the other user. That should probably be made a bit clearer here. -->
|
||||
<TextView
|
||||
android:id="@+id/text2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Participants must have F-Droid installed."
|
||||
android:textSize="14sp"
|
||||
android:textAlignment="center"
|
||||
app:layout_constraintTop_toBottomOf="@+id/text1"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="48dp"
|
||||
android:layout_marginRight="48dp"
|
||||
android:layout_marginStart="48dp"
|
||||
android:layout_marginLeft="48dp" />
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Find people near me"
|
||||
android:text="@string/nearby_splash__find_people_button"
|
||||
style="@style/DetailsSecondaryButtonStyle"
|
||||
app:layout_constraintTop_toBottomOf="@+id/text2"
|
||||
app:layout_constraintTop_toBottomOf="@+id/text1"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:layout_marginTop="16dp" />
|
||||
android:layout_marginTop="24dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="@string/nearby_splash__both_parties_need_fdroid"
|
||||
android:textSize="15sp"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#5B5B5B"
|
||||
app:layout_constraintTop_toBottomOf="@+id/button"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginEnd="48dp"
|
||||
android:layout_marginRight="48dp"
|
||||
android:layout_marginStart="48dp"
|
||||
android:layout_marginLeft="48dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:srcCompat="@drawable/nearby_splash"
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/text2"
|
||||
android:layout_marginTop="36dp"
|
||||
android:tint="#f5f5f5"
|
||||
android:scaleType="fitXY" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
@ -72,7 +72,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/action_button"
|
||||
style="@style/DetailsPrimaryButtonStyle"
|
||||
style="@style/DetailsPrimaryButtonStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
|
@ -23,6 +23,10 @@
|
||||
<dimen name="whats_new__padding__app_card__horizontal">12dp</dimen>
|
||||
<dimen name="whats_new__padding__app_card__vertical">10dp</dimen>
|
||||
|
||||
<!-- Used by the BottomNavigation library so that our text labels are not truncated so easily.
|
||||
The default is 12dp or something like that which only really allows for very short labels. -->
|
||||
<dimen name="fixed_width_padding">2dp</dimen>
|
||||
|
||||
<dimen name="category_preview__app_list__padding__horizontal">4dp</dimen>
|
||||
<dimen name="category_preview__app_list__padding__horizontal__first">72dp</dimen>
|
||||
<dimen name="category_preview__app_list__padding__vertical">18dp</dimen>
|
||||
|
@ -22,8 +22,8 @@
|
||||
<string name="update_interval_zero">No automatic app list updates</string>
|
||||
<string name="automatic_scan_wifi">Only on Wi-Fi</string>
|
||||
<string name="automatic_scan_wifi_on">Only update automatically on unmetered networks like Wi-Fi</string>
|
||||
<string name="update_auto_download">Automatically download updates</string>
|
||||
<string name="update_auto_download_summary">Download the update files in the background</string>
|
||||
<string name="update_auto_download">Automatically fetch updates</string>
|
||||
<string name="update_auto_download_summary">Updates are downloaded automatically and you are notified to install them</string>
|
||||
<string name="update_auto_install">Automatically install updates</string>
|
||||
<string name="update_auto_install_summary">Download and install update apps in the background</string>
|
||||
<string name="notify">Update notifications</string>
|
||||
@ -73,6 +73,7 @@
|
||||
<string name="app_list__name__downloaded_and_ready_to_update">Update %1$s</string>
|
||||
<string name="app_list__name__downloaded_and_ready_to_install">Install %1$s</string>
|
||||
<string name="app_list__name__downloading_in_progress">Downloading %1$s</string>
|
||||
<string name="app_list__name__successfully_installed">%1$s successfully installed</string>
|
||||
<plurals name="app_list__age__released_x_days_ago">
|
||||
<item quantity="one">Released %1$d day ago</item>
|
||||
<item quantity="other">Released %1$d days ago</item>
|
||||
@ -342,6 +343,10 @@
|
||||
<string name="system_uninstall_button">Uninstall</string>
|
||||
<string name="system_install_not_supported">Installation of F-Droid Privileged Extension is currently not supported on Android 5.1 or later.</string>
|
||||
|
||||
<string name="nearby_splash__download_apps_from_people_nearby">No internet? Download apps from people near you!</string>
|
||||
<string name="nearby_splash__find_people_button">Find people near me</string>
|
||||
<string name="nearby_splash__both_parties_need_fdroid">Both parties need %1$s to use nearby.</string>
|
||||
|
||||
<string name="swap_nfc_title">Touch to swap</string>
|
||||
<string name="swap_nfc_description">If your friend has F-Droid and NFC turned on touch your devices together.</string>
|
||||
<string name="swap_join_same_wifi">Join the same Wi-Fi as your friend</string>
|
||||
|
@ -1,30 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="DetailsButtonStyleBase">
|
||||
<item name="android:paddingTop">5dp</item>
|
||||
<item name="android:paddingBottom">5dp</item>
|
||||
<item name="android:paddingLeft">20dp</item>
|
||||
<item name="android:paddingRight">20dp</item>
|
||||
<item name="android:textSize">12sp</item>
|
||||
<item name="android:textStyle">normal</item>
|
||||
</style>
|
||||
<item name="android:minHeight">32dp</item>
|
||||
<item name="android:minWidth">0dp</item>
|
||||
<item name="android:padding">12dp</item>
|
||||
</style>qgi
|
||||
|
||||
<style name="DetailsButtonStyle" parent="DetailsButtonStyleBase" />
|
||||
|
||||
<style name="DetailsPrimaryButtonStyle" parent="DetailsButtonStyle">
|
||||
<item name="android:textColor">#ffffff</item>
|
||||
<item name="android:background">@drawable/button_primary_background_selector</item>
|
||||
</style>
|
||||
|
||||
<style name="DetailsPrimaryButtonStyleSmall" parent="DetailsPrimaryButtonStyle">
|
||||
<item name="android:padding">8dp</item>
|
||||
<item name="android:minHeight">32dp</item>
|
||||
<item name="android:minWidth">0dp</item>
|
||||
</style>
|
||||
|
||||
<style name="DetailsSecondaryButtonStyle" parent="DetailsButtonStyle">
|
||||
<item name="android:textColor">@color/fdroid_blue</item>
|
||||
<item name="android:background">@drawable/button_secondary_background_selector</item>
|
||||
<item name="android:padding">8dp</item>
|
||||
<item name="android:minHeight">32dp</item>
|
||||
<item name="android:minWidth">0dp</item>
|
||||
</style>
|
||||
|
||||
<style name="DetailsMoreButtonStyle">
|
||||
|
Loading…
x
Reference in New Issue
Block a user