Implement Online repo alphabetical sorting. (Implement #8)

pull/55/head
Fox2Code 2 years ago
parent 4ced3453de
commit af02c41c32

@ -3,6 +3,7 @@ package com.fox2code.mmm;
import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
@ -24,6 +25,7 @@ public final class ModuleHolder implements Comparable<ModuleHolder> {
public final NotificationType notificationType;
public final Type separator;
public final int footerPx;
public View.OnClickListener onClickListener;
public LocalModuleInfo moduleInfo;
public RepoModule repoModule;
public int filterLevel;
@ -205,21 +207,21 @@ public final class ModuleHolder implements Comparable<ModuleHolder> {
}
public enum Type implements Comparator<ModuleHolder> {
SEPARATOR(R.string.loading, false) {
SEPARATOR(R.string.loading, false, false) {
@Override
@SuppressWarnings("ConstantConditions")
public int compare(ModuleHolder o1, ModuleHolder o2) {
return o1.separator.compareTo(o2.separator);
}
},
NOTIFICATION(R.string.loading, true) {
NOTIFICATION(R.string.loading, true, false) {
@Override
@SuppressWarnings("ConstantConditions")
public int compare(ModuleHolder o1, ModuleHolder o2) {
return o1.notificationType.compareTo(o2.notificationType);
}
},
UPDATABLE(R.string.updatable, true) {
UPDATABLE(R.string.updatable, true, true) {
@Override
public int compare(ModuleHolder o1, ModuleHolder o2) {
int cmp = Integer.compare(o1.filterLevel, o2.filterLevel);
@ -227,7 +229,7 @@ public final class ModuleHolder implements Comparable<ModuleHolder> {
return Long.compare(o2.repoModule.lastUpdated, o1.repoModule.lastUpdated);
}
},
INSTALLED(R.string.installed, true) {
INSTALLED(R.string.installed, true, true) {
@Override
public int compare(ModuleHolder o1, ModuleHolder o2) {
int cmp = Integer.compare(o1.filterLevel, o2.filterLevel);
@ -235,8 +237,8 @@ public final class ModuleHolder implements Comparable<ModuleHolder> {
return o1.getMainModuleName().compareTo(o2.getMainModuleName());
}
},
SPECIAL_NOTIFICATIONS(R.string.loading, true),
INSTALLABLE(R.string.online_repo, true) {
SPECIAL_NOTIFICATIONS(R.string.loading, true, false),
INSTALLABLE(R.string.online_repo, true, true) {
@Override
public int compare(ModuleHolder o1, ModuleHolder o2) {
int cmp = Integer.compare(o1.filterLevel, o2.filterLevel);
@ -244,15 +246,17 @@ public final class ModuleHolder implements Comparable<ModuleHolder> {
return Long.compare(o2.repoModule.lastUpdated, o1.repoModule.lastUpdated);
}
},
FOOTER(R.string.loading, false);
FOOTER(R.string.loading, false, false);
@StringRes
public final int title;
public final boolean hasBackground;
public final boolean moduleHolder;
Type(@StringRes int title, boolean hasBackground) {
Type(@StringRes int title, boolean hasBackground, boolean moduleHolder) {
this.title = title;
this.hasBackground = hasBackground;
this.moduleHolder = moduleHolder;
}
// Note: This method should only be called if both element have the same type

@ -0,0 +1,48 @@
package com.fox2code.mmm;
import androidx.annotation.DrawableRes;
import java.util.Comparator;
public enum ModuleSorter implements Comparator<ModuleHolder> {
UPDATE(R.drawable.ic_baseline_update_24) {
@Override
public ModuleSorter next() {
return ALPHA;
}
},
ALPHA(R.drawable.ic_baseline_sort_by_alpha_24) {
@Override
public int compare(ModuleHolder holder1, ModuleHolder holder2) {
ModuleHolder.Type type1 = holder1.getType();
ModuleHolder.Type type2 = holder2.getType();
if (type1 == type2 && type1 == ModuleHolder.Type.INSTALLABLE) {
int compare = Integer.compare(holder1.filterLevel, holder2.filterLevel);
if (compare != 0) return compare;
compare = holder1.getMainModuleName()
.compareTo(holder2.getMainModuleName());
if (compare != 0) return compare;
}
return super.compare(holder1, holder2);
}
@Override
public ModuleSorter next() {
return UPDATE;
}
};
@DrawableRes
public final int icon;
ModuleSorter(int icon) {
this.icon = icon;
}
@Override
public int compare(ModuleHolder holder1, ModuleHolder holder2) {
return holder1.compareTo(holder2);
}
public abstract ModuleSorter next();
}

@ -93,12 +93,14 @@ public final class ModuleViewAdapter extends RecyclerView.Adapter<ModuleViewAdap
// Apply default
this.cardView.setOnClickListener(v -> {
ModuleHolder moduleHolder = this.moduleHolder;
if (moduleHolder != null &&
moduleHolder.notificationType != null) {
View.OnClickListener onClickListener =
moduleHolder.notificationType.onClickListener;
if (onClickListener != null)
if (moduleHolder != null) {
View.OnClickListener onClickListener = moduleHolder.onClickListener;
if (onClickListener != null) {
onClickListener.onClick(v);
} else if (moduleHolder.notificationType != null) {
onClickListener = moduleHolder.notificationType.onClickListener;
if (onClickListener != null) onClickListener.onClick(v);
}
}
});
this.switchMaterial.setEnabled(false);
@ -239,9 +241,14 @@ public final class ModuleViewAdapter extends RecyclerView.Adapter<ModuleViewAdap
this.titleText.setTypeface(Typeface.DEFAULT);
}
} else {
this.buttonAction.setVisibility(
type == ModuleHolder.Type.NOTIFICATION ?
View.VISIBLE : View.GONE);
if (type == ModuleHolder.Type.SEPARATOR && moduleHolder.filterLevel != 0) {
this.buttonAction.setVisibility(View.VISIBLE);
this.buttonAction.setImageResource(moduleHolder.filterLevel);
} else {
this.buttonAction.setVisibility(
type == ModuleHolder.Type.NOTIFICATION ?
View.VISIBLE : View.GONE);
}
this.switchMaterial.setVisibility(View.GONE);
this.creditText.setVisibility(View.GONE);
this.descriptionText.setVisibility(View.GONE);
@ -258,11 +265,13 @@ public final class ModuleViewAdapter extends RecyclerView.Adapter<ModuleViewAdap
NotificationType notificationType = moduleHolder.notificationType;
this.titleText.setText(notificationType.textId);
this.buttonAction.setImageResource(notificationType.iconId);
this.cardView.setClickable(notificationType.onClickListener != null);
this.cardView.setClickable(
notificationType.onClickListener != null ||
moduleHolder.onClickListener != null);
this.titleText.setTypeface(notificationType.special ?
Typeface.DEFAULT_BOLD : Typeface.DEFAULT);
} else {
this.cardView.setClickable(false);
this.cardView.setClickable(moduleHolder.onClickListener != null);
this.titleText.setTypeface(Typeface.DEFAULT);
}
}

@ -30,8 +30,9 @@ public class ModuleViewListBuilder {
private final Activity activity;
@NonNull
private String query = "";
private boolean noUpdate;
private boolean updating;
private int footerPx;
private ModuleSorter moduleSorter = ModuleSorter.UPDATE;
public ModuleViewListBuilder(Activity activity) {
this.activity = activity;
@ -94,9 +95,9 @@ public class ModuleViewListBuilder {
}
}
public void applyTo(RecyclerView moduleList, ModuleViewAdapter moduleViewAdapter) {
if (this.noUpdate) return;
this.noUpdate = true;
public void applyTo(final RecyclerView moduleList,final ModuleViewAdapter moduleViewAdapter) {
if (this.updating) return;
this.updating = true;
final ArrayList<ModuleHolder> moduleHolders;
final int newNotificationsLen;
try {
@ -128,14 +129,27 @@ public class ModuleViewListBuilder {
ModuleHolder.Type type = moduleHolder.getType();
if (matchFilter(moduleHolder)) {
if (headerTypes.add(type)) {
moduleHolders.add(new ModuleHolder(type));
ModuleHolder separator = new ModuleHolder(type);
if (type == ModuleHolder.Type.INSTALLABLE) {
ModuleSorter moduleSorter = this.moduleSorter;
separator.filterLevel = this.moduleSorter.icon;
separator.onClickListener = v -> {
if (this.updating || this.moduleSorter != moduleSorter)
return; // Do not allow spams calls
this.moduleSorter = this.moduleSorter.next();
new Thread(() -> // Apply async
this.applyTo(moduleList, moduleViewAdapter),
"Sorter apply Thread").start();
};
}
moduleHolders.add(separator);
}
moduleHolders.add(moduleHolder);
}
}
}
}
Collections.sort(moduleHolders, ModuleHolder::compareTo);
Collections.sort(moduleHolders, this.moduleSorter);
if (this.footerPx != 0) { // Footer is always last
moduleHolders.add(new ModuleHolder(this.footerPx));
}
@ -143,7 +157,7 @@ public class ModuleViewListBuilder {
// Build end
}
} finally {
this.noUpdate = false;
this.updating = false;
}
this.activity.runOnUiThread(() -> {
final EnumSet<NotificationType> oldNotifications =
@ -272,7 +286,6 @@ public class ModuleViewListBuilder {
synchronized (this.updateLock) {
this.footerPx = footerPx;
}
this.noUpdate = false;
}
}
}

@ -21,8 +21,8 @@
<item name="android:activityCloseExitAnimation">@*android:anim/slide_out_right</item> -->
<item name="android:windowEnterAnimation">@android:anim/fade_in</item>
<item name="android:windowExitAnimation">@android:anim/fade_out</item>
<item name="android:dialogCornerRadius" tools:targetApi="p">8dp</item>
<item name="dialogCornerRadius">8dp</item>
<item name="android:dialogCornerRadius" tools:targetApi="p">@dimen/card_corner_radius</item>
<item name="dialogCornerRadius">@dimen/card_corner_radius</item>
</style>
<!-- Base application theme. -->
@ -48,8 +48,8 @@
<item name="android:activityCloseExitAnimation">@*android:anim/slide_out_right</item> -->
<item name="android:windowEnterAnimation">@android:anim/fade_in</item>
<item name="android:windowExitAnimation">@android:anim/fade_out</item>
<item name="android:dialogCornerRadius" tools:targetApi="p">6dp</item>
<item name="dialogCornerRadius">6dp</item>
<item name="android:dialogCornerRadius" tools:targetApi="p">@dimen/card_corner_radius</item>
<item name="dialogCornerRadius">@dimen/card_corner_radius</item>
</style>
<!-- Base application theme. -->

Loading…
Cancel
Save