convert alpha sort into "sort by search terms", keep "last updated"

refs #1600
closes #1522
closes #1185
This commit is contained in:
Hans-Christoph Steiner 2021-02-08 22:04:24 +01:00
parent 646f2c8e9f
commit c3c31ed033
3 changed files with 60 additions and 31 deletions

View File

@ -74,7 +74,7 @@ public class AppListActivity extends AppCompatActivity implements LoaderManager.
private Utils.KeyboardStateMonitor keyboardStateMonitor; private Utils.KeyboardStateMonitor keyboardStateMonitor;
private interface SortClause { private interface SortClause {
String NAME = Cols.NAME; String WORDS = Cols.NAME;
String LAST_UPDATED = Cols.LAST_UPDATED; String LAST_UPDATED = Cols.LAST_UPDATED;
} }
@ -115,14 +115,14 @@ public class AppListActivity extends AppCompatActivity implements LoaderManager.
@Override @Override
public void onClick(View view) { public void onClick(View view) {
switch (sortClauseSelected) { switch (sortClauseSelected) {
case SortClause.NAME: case SortClause.WORDS:
sortClauseSelected = SortClause.LAST_UPDATED; sortClauseSelected = SortClause.LAST_UPDATED;
sortImage.setImageDrawable(lastUpdated); sortImage.setImageDrawable(lastUpdated);
break; break;
case SortClause.LAST_UPDATED: case SortClause.LAST_UPDATED:
sortClauseSelected = SortClause.NAME; sortClauseSelected = SortClause.WORDS;
final Drawable alphabetical = DrawableCompat.wrap( final Drawable alphabetical = DrawableCompat.wrap(
ContextCompat.getDrawable(AppListActivity.this, R.drawable.ic_sort_by_alpha)) ContextCompat.getDrawable(AppListActivity.this, R.drawable.ic_sort))
.mutate(); .mutate();
DrawableCompat.setTint(alphabetical, FDroidApp.isAppThemeLight() ? Color.BLACK : Color.WHITE); DrawableCompat.setTint(alphabetical, FDroidApp.isAppThemeLight() ? Color.BLACK : Color.WHITE);
sortImage.setImageDrawable(alphabetical); sortImage.setImageDrawable(alphabetical);
@ -253,25 +253,36 @@ public class AppListActivity extends AppCompatActivity implements LoaderManager.
} }
private String getSortOrder() { private String getSortOrder() {
final String nameCol = AppMetadataTable.NAME + "." + AppMetadataTable.Cols.NAME; final String table = AppMetadataTable.NAME;
final String summaryCol = AppMetadataTable.NAME + "." + AppMetadataTable.Cols.SUMMARY; final String nameCol = table + "." + AppMetadataTable.Cols.NAME;
final String nameSort = AppMetadataTable.NAME + "." + Cols.NAME + " COLLATE LOCALIZED "; final String summaryCol = table + "." + AppMetadataTable.Cols.SUMMARY;
final String lastUpdatedSort = AppMetadataTable.NAME + "." + Cols.LAST_UPDATED + " DESC"; final String packageCol = Cols.Package.PACKAGE_NAME;
String sortOrder;
switch (sortClauseSelected) { if (sortClauseSelected.equals(SortClause.LAST_UPDATED)) {
case SortClause.NAME: return table + "." + Cols.LAST_UPDATED + " DESC"
sortOrder = nameSort; + ", " + table + "." + Cols.IS_LOCALIZED + " DESC"
break; + ", " + table + "." + Cols.ADDED + " ASC"
case SortClause.LAST_UPDATED: + ", " + table + "." + Cols.NAME + " IS NULL ASC"
sortOrder = lastUpdatedSort; + ", " + table + "." + Cols.ICON + " IS NULL ASC"
break; + ", " + table + "." + Cols.SUMMARY + " IS NULL ASC"
default: + ", " + table + "." + Cols.DESCRIPTION + " IS NULL ASC"
sortOrder = nameSort; + ", " + table + "." + Cols.WHATSNEW + " IS NULL ASC"
+ ", CASE WHEN " + table + "." + Cols.PHONE_SCREENSHOTS + " IS NULL"
+ " AND " + table + "." + Cols.SEVEN_INCH_SCREENSHOTS + " IS NULL"
+ " AND " + table + "." + Cols.TEN_INCH_SCREENSHOTS + " IS NULL"
+ " AND " + table + "." + Cols.TV_SCREENSHOTS + " IS NULL"
+ " AND " + table + "." + Cols.WEAR_SCREENSHOTS + " IS NULL"
+ " AND " + table + "." + Cols.FEATURE_GRAPHIC + " IS NULL"
+ " AND " + table + "." + Cols.PROMO_GRAPHIC + " IS NULL"
+ " AND " + table + "." + Cols.TV_BANNER + " IS NULL"
+ " THEN 1 ELSE 0 END";
} }
final String[] terms = searchTerms.trim().split("\\s+"); // prevent SQL injection https://en.wikipedia.org/wiki/SQL_injection#Escaping
final String[] terms = searchTerms.trim().replaceAll("[\\x1a\0\n\r\"';\\\\]+", " ").split("\\s+");
if (terms.length == 0 || terms[0].equals("")) { if (terms.length == 0 || terms[0].equals("")) {
return sortOrder; return table + "." + Cols.NAME + " COLLATE LOCALIZED ";
}
} }
StringBuilder titleCase = new StringBuilder(String.format("%s like '%%%s%%'", nameCol, terms[0])); StringBuilder titleCase = new StringBuilder(String.format("%s like '%%%s%%'", nameCol, terms[0]));
StringBuilder summaryCase = new StringBuilder(String.format("%s like '%%%s%%'", summaryCol, terms[0])); StringBuilder summaryCase = new StringBuilder(String.format("%s like '%%%s%%'", summaryCol, terms[0]));
@ -281,6 +292,24 @@ public class AppListActivity extends AppCompatActivity implements LoaderManager.
} }
return String.format("case when %s then 1 when %s then 2 else 3 end, %s", return String.format("case when %s then 1 when %s then 2 else 3 end, %s",
titleCase.toString(), summaryCase.toString(), sortOrder); titleCase.toString(), summaryCase.toString(), ""
+ ", " + table + "." + Cols.IS_LOCALIZED + " DESC"
+ ", " + table + "." + Cols.ADDED + " ASC"
+ ", " + table + "." + Cols.NAME + " IS NULL ASC"
+ ", " + table + "." + Cols.ICON + " IS NULL ASC"
+ ", " + table + "." + Cols.SUMMARY + " IS NULL ASC"
+ ", " + table + "." + Cols.DESCRIPTION + " IS NULL ASC"
+ ", " + table + "." + Cols.WHATSNEW + " IS NULL ASC"
+ ", CASE WHEN " + table + "." + Cols.PHONE_SCREENSHOTS + " IS NULL"
+ " AND " + table + "." + Cols.SEVEN_INCH_SCREENSHOTS + " IS NULL"
+ " AND " + table + "." + Cols.TEN_INCH_SCREENSHOTS + " IS NULL"
+ " AND " + table + "." + Cols.TV_SCREENSHOTS + " IS NULL"
+ " AND " + table + "." + Cols.WEAR_SCREENSHOTS + " IS NULL"
+ " AND " + table + "." + Cols.FEATURE_GRAPHIC + " IS NULL"
+ " AND " + table + "." + Cols.PROMO_GRAPHIC + " IS NULL"
+ " AND " + table + "." + Cols.TV_BANNER + " IS NULL"
+ " THEN 1 ELSE 0 END"
+ ", " + table + "." + Cols.LAST_UPDATED + " DESC"
);
} }
} }

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:autoMirrored="true"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">
<path
android:fillColor="#FFFFFF"
android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z" />
</vector>

View File

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M14.94,4.66h-4.72l2.36,-2.36zM10.25,19.37h4.66l-2.33,2.33zM6.1,6.27L1.6,17.73h1.84l0.92,-2.45h5.11l0.92,2.45h1.84L7.74,6.27L6.1,6.27zM4.97,13.64l1.94,-5.18 1.94,5.18L4.97,13.64zM15.73,16.14h6.12v1.59h-8.53v-1.29l5.92,-8.56h-5.88v-1.6h8.3v1.26l-5.93,8.6z" />
</vector>