0
0
mirror of https://github.com/TrianguloY/UrlChecker.git synced 2024-09-19 20:02:16 +02:00

rearrange code

move DrawableButtonUtils.setEnabled to AndroidUtils.setEnabled
move UnaryOperator inside JavaUtils
make loadMod and storeMod parameters to attachToEditText
simplify globaldata management
This commit is contained in:
TrianguloY 2023-03-07 20:26:52 +01:00
parent 2b3f1de912
commit 1a8b899fcf
14 changed files with 99 additions and 142 deletions

View File

@ -19,20 +19,20 @@ import com.trianguloy.urlchecker.R;
import com.trianguloy.urlchecker.modules.AModuleData;
import com.trianguloy.urlchecker.modules.AModuleDialog;
import com.trianguloy.urlchecker.modules.ModuleManager;
import com.trianguloy.urlchecker.modules.companions.GlobalData;
import com.trianguloy.urlchecker.url.UrlData;
import com.trianguloy.urlchecker.utilities.AndroidSettings;
import com.trianguloy.urlchecker.utilities.AndroidUtils;
import com.trianguloy.urlchecker.utilities.GlobalDataContainer;
import com.trianguloy.urlchecker.utilities.Inflater;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* The main dialog, when opening a url
*/
public class MainDialog extends Activity implements GlobalDataContainer {
public class MainDialog extends Activity {
/**
* Maximum number of updates to avoid loops
@ -46,6 +46,11 @@ public class MainDialog extends Activity implements GlobalDataContainer {
*/
private final List<AModuleDialog> modules = new ArrayList<>();
/**
* Global data to keep even if the url changes
*/
public final Map<String, String> globalData = new HashMap<>();
/**
* The current url
*/
@ -123,7 +128,6 @@ public class MainDialog extends Activity implements GlobalDataContainer {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidSettings.setTheme(this, true);
AndroidSettings.setLocale(this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
@ -248,12 +252,6 @@ public class MainDialog extends Activity implements GlobalDataContainer {
return null;
}
private final GlobalData gd = new GlobalData();
@Override
public GlobalData getGlobalData() {
return gd;
}
/* ------------------- its a secret! ------------------- */
/**

View File

@ -6,6 +6,8 @@ import com.trianguloy.urlchecker.dialogs.MainDialog;
import com.trianguloy.urlchecker.fragments.Fragment;
import com.trianguloy.urlchecker.url.UrlData;
import java.util.Map;
/**
* Base class for a module's dialog fragment.
*/
@ -65,4 +67,25 @@ public abstract class AModuleDialog implements Fragment {
dialog.onNewUrl(urlData);
}
/**
* saves global data
*/
public void putData(String key, String value) {
dialog.globalData.put(key, value);
}
/**
* gets global data
*/
public String getData(String key) {
return dialog.globalData.get(key);
}
/**
* returns the global data map, for advanced uses
*/
public Map<String, String> getGlobalData() {
return dialog.globalData;
}
}

View File

@ -1,28 +0,0 @@
package com.trianguloy.urlchecker.modules.companions;
import com.trianguloy.urlchecker.url.UrlData;
import java.util.HashMap;
import java.util.Map;
public class GlobalData {
/**
* Any key-value modules can set, will be kept with automatic updates
*/
private final Map<String, String> extraData = new HashMap<>();
public GlobalData putData(String key, String value) {
extraData.put(key, value);
return this;
}
public String getData(String key) {
return extraData.get(key);
}
@Override
public String toString() {
return super.toString()+"{" + extraData + '}';
}
}

View File

@ -11,7 +11,6 @@ import com.trianguloy.urlchecker.modules.AModuleData;
import com.trianguloy.urlchecker.modules.AModuleDialog;
import com.trianguloy.urlchecker.services.CustomTabs;
import com.trianguloy.urlchecker.url.UrlData;
import com.trianguloy.urlchecker.utilities.GlobalDataContainer;
import java.util.List;
@ -80,8 +79,8 @@ class DebugDialog extends AModuleDialog {
// show current url data
urlData.toString(),
// show global data
((GlobalDataContainer) getActivity()).getGlobalData().toString())
));
getGlobalData().toString()
)));
}
}

View File

@ -19,9 +19,8 @@ import com.trianguloy.urlchecker.modules.AModuleConfig;
import com.trianguloy.urlchecker.modules.AModuleData;
import com.trianguloy.urlchecker.modules.AModuleDialog;
import com.trianguloy.urlchecker.url.UrlData;
import com.trianguloy.urlchecker.utilities.DrawableButtonUtils;
import com.trianguloy.urlchecker.utilities.AndroidUtils;
import com.trianguloy.urlchecker.utilities.GenericPref;
import com.trianguloy.urlchecker.utilities.GlobalDataContainer;
import com.trianguloy.urlchecker.utilities.Inflater;
import java.lang.reflect.Field;
@ -37,10 +36,8 @@ import java.util.Map;
*/
public class FlagsModule extends AModuleData {
public static GenericPref.Str DEFAULTFLAGS_PREF(Context cntx){
String defaultValue = null;
return new GenericPref.Str("flagsEditor_defaultFlags", defaultValue, cntx)
.setStoreMod(str -> str.matches(FlagsDialog.REGEX) ? str : defaultValue);
public static GenericPref.Str DEFAULTFLAGS_PREF(Context cntx) {
return new GenericPref.Str("flagsEditor_defaultFlags", null, cntx);
}
@Override
@ -87,24 +84,24 @@ class FlagsDialog extends AModuleDialog {
public FlagsDialog(MainDialog dialog) {
super(dialog);
try{
try {
flagMap = new HashMap<>();
Collection<String> manualFlags = getDeclaredFlags();
// Only get flags that are present
for (Field field : Intent.class.getFields()) {
if (manualFlags.contains(field.getName())){
if (manualFlags.contains(field.getName())) {
flagMap.put(field.getName(), (Integer) field.get(null));
}
}
}catch (IllegalAccessException e){
} catch (IllegalAccessException e) {
e.printStackTrace();
}
defaultFlagsPref = FlagsModule.DEFAULTFLAGS_PREF(dialog);
}
private Collection<String> getDeclaredFlags(){
private Collection<String> getDeclaredFlags() {
Collection<String> manualFlags = new ArrayList<>();
// https://github.com/MuntashirAkon/AppManager/blob/19782da4c8556c817ba5795554a1cc21f38af13a/app/src/main/java/io/github/muntashirakon/AppManager/intercept/ActivityInterceptor.java#L92
manualFlags.add("FLAG_GRANT_READ_URI_PERMISSION");
@ -166,16 +163,16 @@ class FlagsDialog extends AModuleDialog {
flagNameText.setDropDownAnchor(R.id.addFlagLayout);
// FIXME better search, currently it is an autofill, not a search
// FIXME sometimes its hidden behind keyboard
String defaultFlagsStr = defaultFlagsPref.get();
if (defaultFlagsStr != null){
if (defaultFlagsStr != null) {
setFlags(toInteger(defaultFlagsStr));
}
// Listeners
add.setOnClickListener(v -> {
Integer flag = flagMap.get(flagNameText.getText().toString());
if (flag != null){
if (flag != null) {
setFlags(getFlagsNonNull() | flag);
} else {
Toast.makeText(getActivity(), R.string.mFlags_invalid, Toast.LENGTH_LONG).show();
@ -190,9 +187,9 @@ class FlagsDialog extends AModuleDialog {
setUrl(getUrl());
});
edit.setOnClickListener(v -> {
if (flagsHexText.isEnabled()){
if (flagsHexText.isEnabled()) {
Integer flags = toInteger(flagsHexText.getText().toString());
if (flags != null){
if (flags != null) {
// Extract flags
setFlags(flags);
}
@ -216,7 +213,7 @@ class FlagsDialog extends AModuleDialog {
updateLayout();
}
private void updateLayout(){
private void updateLayout() {
box.removeAllViews();
int flags = getFlagsNonNull();
flagsHexText.setText(toHexString(flags));
@ -226,9 +223,9 @@ class FlagsDialog extends AModuleDialog {
Collections.sort(decodedFlags, (o1, o2) -> flagMap.get(o1).compareTo(flagMap.get(o2)));
if (decodedFlags.size() == 0) {
DrawableButtonUtils.setEnabled(more,false);
AndroidUtils.setEnabled(more, false);
} else {
DrawableButtonUtils.setEnabled(more,true);
AndroidUtils.setEnabled(more, true);
// For each flag, create a button
for (String flag : decodedFlags) {
var button_text = Inflater.inflate(R.layout.button_text, box, getActivity());
@ -253,11 +250,11 @@ class FlagsDialog extends AModuleDialog {
}
// ------------------- utils -------------------
private List<String> decodeFlags(int hex){
private List<String> decodeFlags(int hex) {
List<String> foundFlags = new ArrayList<>();
for (String flagName : flagMap.keySet()) {
// check if flag is present
if ((hex & flagMap.get(flagName)) != 0){
if ((hex & flagMap.get(flagName)) != 0) {
foundFlags.add(flagName);
}
}
@ -271,15 +268,15 @@ class FlagsDialog extends AModuleDialog {
private static final int BASE = 16;
protected static final String REGEX = "0x[a-fA-F\\d]{1,8}";
public static Integer toInteger(String text){
if (text != null && text.matches(REGEX)){
public static Integer toInteger(String text) {
if (text != null && text.matches(REGEX)) {
return Integer.parseInt(text.substring(2), BASE);
} else {
return null;
}
}
public static String toHexString(int flags){
public static String toHexString(int flags) {
return "0x" + Integer.toHexString(flags);
}
@ -287,25 +284,25 @@ class FlagsDialog extends AModuleDialog {
* Retrieves the flags from GlobalData, if it is not defined it will return null
* Intended for use in other modules
*/
public static Integer getFlagsNullable(GlobalDataContainer instance){
return toInteger(instance.getGlobalData().getData(FlagsDialog.FLAGS));
public static Integer getFlagsNullable(AModuleDialog instance) {
return toInteger(instance.getData(FlagsDialog.FLAGS));
}
/**
* Loads the flags from GlobalData, if none were found it gets the flags from the intent that
* started this activity
*/
private int getFlagsNonNull(){
return getFlagsOrDefault((GlobalDataContainer) getActivity(), getActivity().getIntent().getFlags());
private int getFlagsNonNull() {
return getFlagsOrDefault(this, getActivity().getIntent().getFlags());
}
/**
* Loads the flags from GlobalData, if none were found it gets the flags from default
* Can be used by other modules
*/
public static int getFlagsOrDefault(GlobalDataContainer instance, int defaultFlags){
Integer flags = toInteger(instance.getGlobalData().getData(FLAGS));
return flags == null?
public static int getFlagsOrDefault(AModuleDialog instance, int defaultFlags) {
Integer flags = toInteger(instance.getData(FLAGS));
return flags == null ?
defaultFlags :
flags;
}
@ -313,8 +310,8 @@ class FlagsDialog extends AModuleDialog {
/**
* Stores the flags in GlobalData
*/
private void setFlags(Integer flags){
((GlobalDataContainer) getActivity()).getGlobalData().putData(FLAGS, flags == null ? null : toHexString(flags));
private void setFlags(Integer flags) {
putData(FLAGS, flags == null ? null : toHexString(flags));
}
}
@ -322,7 +319,7 @@ class FlagsDialog extends AModuleDialog {
class FlagsConfig extends AModuleConfig {
private final GenericPref.Str defaultFlagsPref;
public FlagsConfig(ModulesActivity activity){
public FlagsConfig(ModulesActivity activity) {
super(activity);
defaultFlagsPref = FlagsModule.DEFAULTFLAGS_PREF(activity);
}
@ -334,6 +331,6 @@ class FlagsConfig extends AModuleConfig {
@Override
public void onInitialize(View views) {
defaultFlagsPref.attachToEditText(views.findViewById(R.id.flags));
defaultFlagsPref.attachToEditText(views.findViewById(R.id.flags), str -> str, str -> str.matches(FlagsDialog.REGEX) ? str : defaultFlagsPref.defaultValue);
}
}

View File

@ -12,7 +12,7 @@ import com.trianguloy.urlchecker.modules.AModuleData;
import com.trianguloy.urlchecker.modules.AModuleDialog;
import com.trianguloy.urlchecker.modules.DescriptionConfig;
import com.trianguloy.urlchecker.url.UrlData;
import com.trianguloy.urlchecker.utilities.DrawableButtonUtils;
import com.trianguloy.urlchecker.utilities.AndroidUtils;
import java.util.ArrayList;
import java.util.Collections;
@ -104,11 +104,11 @@ class HistoryDialog extends AModuleDialog {
* updated the UI with the internal data (buttons visibility)
*/
private void updateUI() {
DrawableButtonUtils.setEnabled(first, index > 0); // at least something to go back
DrawableButtonUtils.setEnabled(back, index > 0); // at least something to go back
AndroidUtils.setEnabled(first, index > 0); // at least something to go back
AndroidUtils.setEnabled(back, index > 0); // at least something to go back
list.setEnabled(!history.isEmpty()); // at least something
DrawableButtonUtils.setEnabled(forward, index < history.size() - 1); // at least something to go forward
DrawableButtonUtils.setEnabled(last, index < history.size() - 1); // at least something to go forward
AndroidUtils.setEnabled(forward, index < history.size() - 1); // at least something to go forward
AndroidUtils.setEnabled(last, index < history.size() - 1); // at least something to go forward
}
@Override

View File

@ -16,13 +16,11 @@ import com.trianguloy.urlchecker.dialogs.MainDialog;
import com.trianguloy.urlchecker.modules.AModuleConfig;
import com.trianguloy.urlchecker.modules.AModuleData;
import com.trianguloy.urlchecker.modules.AModuleDialog;
import com.trianguloy.urlchecker.modules.ModuleManager;
import com.trianguloy.urlchecker.modules.companions.CTabs;
import com.trianguloy.urlchecker.modules.companions.LastOpened;
import com.trianguloy.urlchecker.url.UrlData;
import com.trianguloy.urlchecker.utilities.AndroidUtils;
import com.trianguloy.urlchecker.utilities.GenericPref;
import com.trianguloy.urlchecker.utilities.GlobalDataContainer;
import com.trianguloy.urlchecker.utilities.PackageUtils;
import com.trianguloy.urlchecker.utilities.UrlUtils;
@ -185,8 +183,8 @@ class OpenDialog extends AModuleDialog {
// check no apps
if (packages.isEmpty()) {
btn_open.setText(R.string.mOpen_noapps);
AndroidUtils.setEnabled(openParent, false);
btn_open.setEnabled(false);
openParent.setAlpha(0.35f);
btn_openWith.setVisibility(View.GONE);
return;
}
@ -196,8 +194,8 @@ class OpenDialog extends AModuleDialog {
// set
btn_open.setText(getActivity().getString(R.string.mOpen_with, PackageUtils.getPackageName(packages.get(0), getActivity())));
AndroidUtils.setEnabled(openParent, true);
btn_open.setEnabled(true);
openParent.setAlpha(1);
menu.clear();
if (packages.size() == 1) {
btn_openWith.setVisibility(View.GONE);
@ -252,12 +250,10 @@ class OpenDialog extends AModuleDialog {
intent.removeExtra(CTabs.EXTRA);
}
if (ModuleManager.getEnabledPrefOfModule(new FlagsModule(), getActivity()).get()){
// Get flags from flags module
Integer flags = FlagsDialog.getFlagsNullable((GlobalDataContainer) getActivity());
if (flags != null){
intent.setFlags(flags);
}
// Get flags from global data (probably set by flags module, if active)
Integer flags = FlagsDialog.getFlagsNullable(this);
if (flags != null) {
intent.setFlags(flags);
}
PackageUtils.startActivity(intent, R.string.toast_noApp, getActivity());

View File

@ -47,6 +47,15 @@ public interface AndroidUtils {
}
}
/**
* For some reason some drawable buttons are displayed the same when enabled and disabled.
* This method also sets an alpha as a workaround
*/
static void setEnabled(View view, boolean enabled) {
view.setEnabled(enabled);
view.setAlpha(enabled ? 1f : 0.35f);
}
/**
* In debug mode, throws an AssertionError, in production just logs it and continues.
*/

View File

@ -1,17 +0,0 @@
package com.trianguloy.urlchecker.utilities;
import android.view.View;
public class DrawableButtonUtils {
/**
* For some reason some drawable buttons are displayed the same when enabled and disabled.
* This method also sets an alpha as a workaround
*
* @param view view to enable/disable
* @param enabled new state
*/
public static void setEnabled(View view, boolean enabled) {
view.setEnabled(enabled);
view.setAlpha(enabled ? 1f : 0.35f);
}
}

View File

@ -36,7 +36,7 @@ public abstract class GenericPref<T> {
/**
* This preference default value
*/
protected final T defaultValue;
public final T defaultValue;
/**
* Constructs a generic pref with name and default value, uninitialized
@ -165,13 +165,8 @@ public abstract class GenericPref<T> {
* A string preference
*/
static public class Str extends GenericPref<String> {
private UnaryOperator<String> loadMod;
private UnaryOperator<String> storeMod;
public Str(String prefName, String defaultValue, Context cntx) {
super(prefName, defaultValue, cntx);
loadMod = str -> str;
storeMod = str -> str;
}
@Override
@ -195,6 +190,13 @@ public abstract class GenericPref<T> {
* This editText will be set to the pref value, and when the editText changes the value will too
*/
public void attachToEditText(EditText editText) {
this.attachToEditText(editText, str -> str, str -> str);
}
/**
* This editText will be set to the pref value modified by loadMod, and when the editText changes the value will be modified by storeMod and saved
*/
public void attachToEditText(EditText editText, JavaUtils.UnaryOperator<String> loadMod, JavaUtils.UnaryOperator<String> storeMod) {
editText.setText(loadMod.apply(get()));
editText.addTextChangedListener(new TextWatcher() {
@Override
@ -211,22 +213,6 @@ public abstract class GenericPref<T> {
}
});
}
/**
* Will be executed when loading pref into EditText
*/
public Str setLoadMod(UnaryOperator<String> loadMod) {
this.loadMod = loadMod;
return this;
}
/**
* Will be executed when storing pref from EditText
*/
public Str setStoreMod(UnaryOperator<String> storeMod) {
this.storeMod = storeMod;
return this;
}
}

View File

@ -1,7 +0,0 @@
package com.trianguloy.urlchecker.utilities;
import com.trianguloy.urlchecker.modules.companions.GlobalData;
public interface GlobalDataContainer {
GlobalData getGlobalData();
}

View File

@ -61,4 +61,10 @@ public interface JavaUtils {
R apply(T t);
}
/**
* java.util.function.UnaryOperator requires api 24
*/
@FunctionalInterface
interface UnaryOperator<T> extends Function<T, T> {
}
}

View File

@ -1,5 +0,0 @@
package com.trianguloy.urlchecker.utilities;
public interface UnaryOperator <T>{
T apply(T o);
}

View File

@ -292,7 +292,7 @@ Their api is rate limited to 10 requests per hour for new checks. The module res
<string name="add">Add</string>
<string name="mFlag_desc">"[Beta feature] This is an advanced module, it allows you to edit the intent flags when opening another app.
In the field below you can put flags that will overwrite the default ones, those are taken from the intent that was used to open this app.
While using the module you can hold the edit button to set the flags to the default flags. You can add flags by writing their name in the flags field</string>
While using the module you can hold the edit button to set the flags to the default flags. You can add flags by writing their name in the flags field"</string>
<string name="mFlag_flagHint" translatable="false">FLAG_NAME</string>
</resources>