You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FoxMagiskModuleManager/app/src/main/java/com/fox2code/mmm/ModuleViewAdapter.java

272 lines
13 KiB
Java

package com.fox2code.mmm;
import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.fox2code.mmm.manager.ModuleInfo;
import com.fox2code.mmm.manager.ModuleManager;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.topjohnwu.superuser.internal.UiThreadHandler;
import java.util.ArrayList;
public final class ModuleViewAdapter extends RecyclerView.Adapter<ModuleViewAdapter.ViewHolder> {
private static final boolean DEBUG = false;
public final ArrayList<ModuleHolder> moduleHolders = new ArrayList<>();
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.module_entry, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
final ModuleHolder moduleHolder = this.moduleHolders.get(position);
if (holder.update(moduleHolder)) {
UiThreadHandler.handler.post(() -> {
if (this.moduleHolders.get(position) == moduleHolder) {
this.moduleHolders.remove(position);
this.notifyItemRemoved(position);
}
});
}
}
@Override
public int getItemCount() {
return this.moduleHolders.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final CardView cardView;
private final ImageButton buttonAction;
private final SwitchMaterial switchMaterial;
private final TextView titleText;
private final TextView creditText;
private final TextView descriptionText;
private final TextView updateText;
private final ImageButton[] actionsButtons;
private final ArrayList<ActionButtonType> actionButtonsTypes;
private boolean initState;
public ModuleHolder moduleHolder;
public Drawable background;
public ViewHolder(@NonNull View itemView) {
super(itemView);
this.initState = true;
this.cardView = itemView.findViewById(R.id.card_view);
this.buttonAction = itemView.findViewById(R.id.button_action);
this.switchMaterial = itemView.findViewById(R.id.switch_action);
this.titleText = itemView.findViewById(R.id.title_text);
this.creditText = itemView.findViewById(R.id.credit_text);
this.descriptionText = itemView.findViewById(R.id.description_text);
this.updateText = itemView.findViewById(R.id.updated_text);
this.actionsButtons = new ImageButton[6];
this.actionsButtons[0] = itemView.findViewById(R.id.button_action1);
this.actionsButtons[1] = itemView.findViewById(R.id.button_action2);
this.actionsButtons[2] = itemView.findViewById(R.id.button_action3);
this.actionsButtons[3] = itemView.findViewById(R.id.button_action4);
this.actionsButtons[4] = itemView.findViewById(R.id.button_action5);
this.actionsButtons[5] = itemView.findViewById(R.id.button_action6);
this.background = this.cardView.getBackground();
// 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)
onClickListener.onClick(v);
}
});
this.switchMaterial.setEnabled(false);
this.switchMaterial.setOnCheckedChangeListener((v, checked) -> {
if (this.initState) return; // Skip if non user
ModuleHolder moduleHolder = this.moduleHolder;
if (moduleHolder != null && moduleHolder.moduleInfo != null) {
ModuleInfo moduleInfo = moduleHolder.moduleInfo;
if (!ModuleManager.getINSTANCE().setEnabledState(moduleInfo, checked)) {
this.switchMaterial.setChecked( // Reset to valid state if action failed
(moduleInfo.flags & ModuleInfo.FLAG_MODULE_DISABLED) == 0);
}
}
});
this.actionButtonsTypes = new ArrayList<>();
for (int i = 0; i < this.actionsButtons.length; i++) {
final int index = i;
this.actionsButtons[i].setOnClickListener(v -> {
if (this.initState) return; // Skip if non user
ModuleHolder moduleHolder = this.moduleHolder;
if (index < this.actionButtonsTypes.size() && moduleHolder != null) {
this.actionButtonsTypes.get(index)
.doAction((ImageButton) v, moduleHolder);
if (moduleHolder.shouldRemove()) {
this.cardView.setVisibility(View.GONE);
}
}
});
this.actionsButtons[i].setOnLongClickListener(v -> {
if (this.initState) return false; // Skip if non user
ModuleHolder moduleHolder = this.moduleHolder;
boolean didSomething = false;
if (index < this.actionButtonsTypes.size() && moduleHolder != null) {
didSomething = this.actionButtonsTypes.get(index)
.doActionLong((ImageButton) v, moduleHolder);
if (moduleHolder.shouldRemove()) {
this.cardView.setVisibility(View.GONE);
}
}
return didSomething;
});
}
this.initState = false;
}
@SuppressLint("SetTextI18n")
public boolean update(ModuleHolder moduleHolder) {
this.initState = true;
if (moduleHolder.isModuleHolder() && moduleHolder.shouldRemove()) {
this.cardView.setVisibility(View.GONE);
this.moduleHolder = null;
this.initState = false;
return true;
}
ModuleHolder.Type type = moduleHolder.getType();
ModuleHolder.Type vType = moduleHolder.getCompareType(type);
this.cardView.setVisibility(View.VISIBLE);
boolean showCaseMode = MainApplication.isShowcaseMode();
if (moduleHolder.isModuleHolder()) {
this.buttonAction.setVisibility(View.GONE);
ModuleInfo localModuleInfo = moduleHolder.moduleInfo;
if (localModuleInfo != null) {
this.switchMaterial.setVisibility(View.VISIBLE);
this.switchMaterial.setChecked((localModuleInfo.flags &
ModuleInfo.FLAG_MODULE_DISABLED) == 0);
} else {
this.switchMaterial.setVisibility(View.GONE);
}
this.creditText.setVisibility(View.VISIBLE);
this.descriptionText.setVisibility(View.VISIBLE);
ModuleInfo moduleInfo = moduleHolder.getMainModuleInfo();
this.titleText.setText(moduleInfo.name);
this.creditText.setText(moduleInfo.version + " by " + moduleInfo.author);
this.descriptionText.setText(moduleInfo.description);
String updateText = moduleHolder.getUpdateTimeText();
if (!updateText.isEmpty()) {
this.updateText.setVisibility(View.VISIBLE);
this.updateText.setText(this.updateText.getContext()
.getString(R.string.last_updated) + " " + updateText);
} else if (moduleHolder.moduleId.equals("hosts")) {
this.updateText.setVisibility(View.VISIBLE);
this.updateText.setText(R.string.magisk_builtin_module);
} else {
this.updateText.setVisibility(View.GONE);
}
this.actionButtonsTypes.clear();
moduleHolder.getButtons(itemView.getContext(), this.actionButtonsTypes, showCaseMode);
this.switchMaterial.setEnabled(!showCaseMode &&
!moduleHolder.hasFlag(ModuleInfo.FLAG_MODULE_UPDATING));
for (int i = 0; i < this.actionsButtons.length; i++) {
ImageButton imageButton = this.actionsButtons[i];
if (i < this.actionButtonsTypes.size()) {
imageButton.setVisibility(View.VISIBLE);
this.actionButtonsTypes.get(i)
.update(imageButton, moduleHolder);
} else {
imageButton.setVisibility(View.GONE);
}
}
this.cardView.setClickable(false);
if (moduleHolder.isModuleHolder() &&
moduleHolder.hasFlag(ModuleInfo.FLAG_MODULE_ACTIVE)) {
this.titleText.setTypeface(Typeface.DEFAULT_BOLD);
} else {
this.titleText.setTypeface(Typeface.DEFAULT);
}
} 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);
this.updateText.setVisibility(View.GONE);
this.titleText.setText(" ");
this.creditText.setText(" ");
this.descriptionText.setText(" ");
this.switchMaterial.setEnabled(false);
this.actionButtonsTypes.clear();
for (ImageButton button:this.actionsButtons) {
button.setVisibility(View.GONE);
}
if (type == ModuleHolder.Type.NOTIFICATION) {
NotificationType notificationType = moduleHolder.notificationType;
this.titleText.setText(notificationType.textId);
this.buttonAction.setImageResource(notificationType.iconId);
this.cardView.setClickable(notificationType.onClickListener != null);
this.titleText.setTypeface(notificationType.special ?
Typeface.DEFAULT_BOLD : Typeface.DEFAULT);
} else {
this.cardView.setClickable(false);
this.titleText.setTypeface(Typeface.DEFAULT);
}
}
if (type == ModuleHolder.Type.SEPARATOR) {
this.titleText.setText(moduleHolder.separator.title);
}
if (DEBUG) {
this.titleText.setText(this.titleText.getText() + " " +
formatType(type) + " " + formatType(vType));
}
// Coloration system
Drawable drawable = this.cardView.getBackground();
if (drawable != null) this.background = drawable;
if (type.hasBackground) {
if (drawable == null) {
this.cardView.setBackground(this.background);
}
int backgroundAttr = R.attr.colorBackgroundFloating;
if (type == ModuleHolder.Type.NOTIFICATION) {
backgroundAttr = moduleHolder.notificationType.backgroundAttr;
}
Resources.Theme theme = this.cardView.getContext().getTheme();
TypedValue value = new TypedValue();
theme.resolveAttribute(backgroundAttr, value, true);
this.cardView.setCardBackgroundColor(value.data);
} else {
this.cardView.setBackground(null);
}
if (type == ModuleHolder.Type.FOOTER) {
this.titleText.setMinHeight(moduleHolder.footerPx);
} else {
this.titleText.setMinHeight(0);
}
this.moduleHolder = moduleHolder;
this.initState = false;
return false;
}
}
private static String formatType(ModuleHolder.Type type) {
return type.name().substring(0, 3) + "_" + type.ordinal();
}
}