diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index 02151d2..ee7629a 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -1,17 +1,17 @@
-
+
-
+
-
-
+
+
-
-
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 3cce64f..b9a64be 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -35,15 +35,15 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
- implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1'
- implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1'
+ implementation 'androidx.lifecycle:lifecycle-livedata:2.4.1'
+ implementation 'androidx.lifecycle:lifecycle-viewmodel:2.4.1'
implementation 'androidx.navigation:navigation-fragment:2.5.3'
implementation 'androidx.navigation:navigation-ui:2.5.3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation "androidx.biometric:biometric:1.1.0"
- implementation 'com.cringe_studios:CringeAuthenticatorLibrary:1.0'
+ implementation 'com.cringe_studios:CringeAuthenticatorLibrary:1.2'
implementation 'com.google.mlkit:barcode-scanning:17.1.0'
implementation 'com.google.code.gson:gson:2.8.9'
diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/IntroActivity.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/IntroActivity.java
index ae559cb..bc899c3 100644
--- a/app/src/main/java/com/cringe_studios/cringe_authenticator/IntroActivity.java
+++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/IntroActivity.java
@@ -6,6 +6,7 @@ import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
+import android.util.Log;
import android.view.ViewGroup;
import android.widget.Toast;
@@ -24,6 +25,8 @@ public class IntroActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ Log.i("AMOGUS", "CREATE");
+
if (!SettingsUtil.isIntroVideoEnabled(this)) {
openMainActivity();
return;
@@ -61,11 +64,16 @@ public class IntroActivity extends AppCompatActivity {
@Override
public void onDestroy() {
super.onDestroy();
- // When the Activity is destroyed, release our MediaPlayer and set it to null.
if(mMediaPlayer != null) mMediaPlayer.release();
mMediaPlayer = null;
}
+ @Override
+ protected void onResume() {
+ super.onResume();
+ binding.videoView.start();
+ }
+
private void setDimension() {
float videoProportion = (float) mMediaPlayer.getVideoHeight() / mMediaPlayer.getVideoWidth();
int screenWidth = getResources().getDisplayMetrics().widthPixels;
diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/MainActivity.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/MainActivity.java
index 25188c7..0cda957 100644
--- a/app/src/main/java/com/cringe_studios/cringe_authenticator/MainActivity.java
+++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/MainActivity.java
@@ -23,6 +23,7 @@ import androidx.navigation.ui.NavigationUI;
import com.cringe_studios.cringe_authenticator.databinding.ActivityMainBinding;
import com.cringe_studios.cringe_authenticator.databinding.DialogInputCodeChoiceBinding;
+import com.cringe_studios.cringe_authenticator.databinding.DialogInputCodeHotpBinding;
import com.cringe_studios.cringe_authenticator.databinding.DialogInputCodeTotpBinding;
import com.cringe_studios.cringe_authenticator.fragment.DynamicFragment;
import com.cringe_studios.cringe_authenticator.fragment.HomeFragment;
@@ -185,7 +186,6 @@ public class MainActivity extends AppCompatActivity {
}
private void showTOTPDialog() {
- // TODO: checksum option
DialogInputCodeTotpBinding binding = DialogInputCodeTotpBinding.inflate(getLayoutInflater());
binding.inputAlgorithm.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, OTPAlgorithm.values()));
binding.inputDigits.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new Integer[]{6, 7, 8, 9, 10, 11, 12}));
@@ -199,9 +199,9 @@ public class MainActivity extends AppCompatActivity {
OTPAlgorithm algorithm = (OTPAlgorithm) binding.inputAlgorithm.getSelectedItem();
int digits = (int) binding.inputDigits.getSelectedItem();
int period = Integer.parseInt(binding.inputPeriod.getText().toString());
+ boolean checksum = binding.inputChecksum.isChecked();
- // TODO: checksum
- OTPData data = new OTPData(name, OTPType.TOTP, secret, algorithm, digits, period, 0, false);
+ OTPData data = new OTPData(name, OTPType.TOTP, secret, algorithm, digits, period, 0, checksum);
String errorMessage = data.validate();
if(errorMessage != null) {
@@ -219,8 +219,36 @@ public class MainActivity extends AppCompatActivity {
}
private void showHOTPDialog() {
- DialogInputCodeTotpBinding binding = DialogInputCodeTotpBinding.inflate(getLayoutInflater());
- showCodeDialog(binding.getRoot(), () -> true);
+ DialogInputCodeHotpBinding binding = DialogInputCodeHotpBinding.inflate(getLayoutInflater());
+ binding.inputAlgorithm.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, OTPAlgorithm.values()));
+ binding.inputDigits.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new Integer[]{6, 7, 8, 9, 10, 11, 12}));
+ showCodeDialog(binding.getRoot(), () -> {
+ Fragment fragment = NavigationUtil.getCurrentFragment(this);
+ if(!(fragment instanceof DynamicFragment)) return true;
+
+ try {
+ String name = binding.inputName.getText().toString();
+ String secret = binding.inputSecret.getText().toString();
+ OTPAlgorithm algorithm = (OTPAlgorithm) binding.inputAlgorithm.getSelectedItem();
+ int digits = (int) binding.inputDigits.getSelectedItem();
+ int counter = Integer.parseInt(binding.inputCounter.getText().toString());
+ boolean checksum = binding.inputChecksum.isChecked();
+
+ OTPData data = new OTPData(name, OTPType.TOTP, secret, algorithm, digits, 0, counter, checksum);
+
+ String errorMessage = data.validate();
+ if(errorMessage != null) {
+ showErrorDialog(errorMessage);
+ return false;
+ }
+
+ ((DynamicFragment) fragment).addOTP(data);
+ return true;
+ }catch(NumberFormatException e) {
+ showErrorDialog("Invalid number entered");
+ return false;
+ }
+ });
}
private void showCodeDialog(View view, DialogCallback ok) {
@@ -254,7 +282,17 @@ public class MainActivity extends AppCompatActivity {
new AlertDialog.Builder(this)
.setTitle("New Group")
.setView(t)
- .setPositiveButton("Add", (view, which) -> {})
+ .setPositiveButton("Add", (view, which) -> {
+ if(t.getText().length() == 0) {
+ showErrorDialog("You need to input a name");
+ return;
+ }
+
+ Fragment frag = NavigationUtil.getCurrentFragment(this);
+ if(frag instanceof MenuFragment) {
+ ((MenuFragment) frag).addGroup(t.getText().toString());
+ }
+ })
.setNegativeButton("Cancel", (view, which) -> {})
.show();
}
diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/DynamicFragment.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/DynamicFragment.java
index be2fdbc..4ae1d46 100644
--- a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/DynamicFragment.java
+++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/DynamicFragment.java
@@ -22,7 +22,7 @@ import com.cringe_studios.cringe_authenticator.util.SettingsUtil;
import java.util.List;
-public class DynamicFragment extends Fragment {
+public class DynamicFragment extends NamedFragment {
public static final String BUNDLE_GROUP = "group";
@@ -36,6 +36,11 @@ public class DynamicFragment extends Fragment {
private OTPListAdapter otpListAdapter;
+ @Override
+ public String getName() {
+ return groupName;
+ }
+
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -72,8 +77,7 @@ public class DynamicFragment extends Fragment {
}
private void loadOTPs() {
- SharedPreferences prefs = requireActivity().getSharedPreferences(SettingsUtil.GROUPS_PREFS_NAME, Context.MODE_PRIVATE);
- List data = SettingsUtil.getOTPs(prefs, groupName);
+ List data = SettingsUtil.getOTPs(requireContext(), groupName);
for(OTPData otp : data) {
otpListAdapter.add(otp);
@@ -81,8 +85,7 @@ public class DynamicFragment extends Fragment {
}
public void addOTP(OTPData data) {
- SharedPreferences prefs = requireActivity().getSharedPreferences(SettingsUtil.GROUPS_PREFS_NAME, Context.MODE_PRIVATE);
- SettingsUtil.addOTP(prefs, groupName, data);
+ SettingsUtil.addOTP(requireContext(), groupName, data);
otpListAdapter.add(data);
}
diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/HomeFragment.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/HomeFragment.java
index 7f1ae15..16b267d 100644
--- a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/HomeFragment.java
+++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/HomeFragment.java
@@ -11,10 +11,15 @@ import androidx.fragment.app.Fragment;
import com.cringe_studios.cringe_authenticator.databinding.FragmentHomeBinding;
import com.cringe_studios.cringe_authenticator.util.FabUtil;
-public class HomeFragment extends Fragment {
+public class HomeFragment extends NamedFragment {
private FragmentHomeBinding binding;
+ @Override
+ public String getName() {
+ return "Home";
+ }
+
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentHomeBinding.inflate(inflater, container, false);
diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/MenuFragment.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/MenuFragment.java
index 65a34af..5f639b8 100644
--- a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/MenuFragment.java
+++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/MenuFragment.java
@@ -3,6 +3,7 @@ package com.cringe_studios.cringe_authenticator.fragment;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -12,55 +13,71 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
+import com.cringe_studios.cringe_authenticator.OTPData;
import com.cringe_studios.cringe_authenticator.databinding.FragmentMenuBinding;
import com.cringe_studios.cringe_authenticator.databinding.MenuItemBinding;
+import com.cringe_studios.cringe_authenticator.grouplist.GroupListAdapter;
+import com.cringe_studios.cringe_authenticator.grouplist.GroupListItem;
import com.cringe_studios.cringe_authenticator.util.FabUtil;
import com.cringe_studios.cringe_authenticator.util.NavigationUtil;
+import com.cringe_studios.cringe_authenticator.util.SettingsUtil;
-public class MenuFragment extends Fragment {
+import java.util.List;
+
+public class MenuFragment extends NamedFragment {
private FragmentMenuBinding binding;
+ private GroupListAdapter groupListAdapter;
+
+ @Override
+ public String getName() {
+ return "Menu";
+ }
+
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmentMenuBinding.inflate(inflater);
- SharedPreferences pr = requireContext().getSharedPreferences("menu", Context.MODE_PRIVATE);
+ groupListAdapter = new GroupListAdapter(requireContext(), group -> {
+ Bundle bundle = new Bundle();
+ bundle.putString(DynamicFragment.BUNDLE_GROUP, group);
+ NavigationUtil.navigate(this, DynamicFragment.class, bundle);
+ }, this::removeGroup);
- String[] items = {"a", "b"};
+ binding.menuItems.setAdapter(groupListAdapter);
- for(String item : items) {
- MenuItemBinding itemBinding = MenuItemBinding.inflate(inflater, binding.menuItems, false);
- itemBinding.button.setText(item);
- itemBinding.button.setOnClickListener(view -> {
- Bundle bundle = new Bundle();
- bundle.putString(DynamicFragment.BUNDLE_GROUP, item);
- NavigationUtil.navigate(this, DynamicFragment.class, bundle);
- });
- itemBinding.button.setOnLongClickListener(view -> {
- new AlertDialog.Builder(requireContext())
- .setTitle("Delete?")
- .setMessage("Delete this?")
- .setPositiveButton("Yes", (dialog, which) -> itemBinding.button.setVisibility(View.GONE))
- .setNegativeButton("No", (dialog, which) -> {})
- .show();
- // TODO: better method?
- // TODO: actually delete
- return true;
- });
- binding.menuItems.addView(itemBinding.getRoot());
- }
+ loadGroups();
- binding.editSwitch.setOnCheckedChangeListener((view, checked) -> {
+ /*binding.editSwitch.setOnCheckedChangeListener((view, checked) -> {
// TODO: edit mode
- });
+ });*/
FabUtil.hideFabs(requireActivity());
return binding.getRoot();
}
+ private void loadGroups() {
+ List items = SettingsUtil.getGroups(requireContext());
+ Log.i("AMOGUS", "items: " + items);
+
+ for(String item : items) {
+ groupListAdapter.add(item);
+ }
+ }
+
+ public void addGroup(String group) {
+ SettingsUtil.addGroup(requireContext(), group);
+ groupListAdapter.add(group);
+ }
+
+ public void removeGroup(String group) {
+ SettingsUtil.removeGroup(requireContext(), group);
+ groupListAdapter.remove(group);
+ }
+
@Override
public void onDestroyView() {
super.onDestroyView();
diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/NamedFragment.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/NamedFragment.java
new file mode 100644
index 0000000..9dddbf0
--- /dev/null
+++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/NamedFragment.java
@@ -0,0 +1,9 @@
+package com.cringe_studios.cringe_authenticator.fragment;
+
+import androidx.fragment.app.Fragment;
+
+public abstract class NamedFragment extends Fragment {
+
+ public abstract String getName();
+
+}
diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/SettingsFragment.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/SettingsFragment.java
index f3d9843..9ec41dc 100644
--- a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/SettingsFragment.java
+++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/SettingsFragment.java
@@ -27,10 +27,15 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
-public class SettingsFragment extends Fragment {
+public class SettingsFragment extends NamedFragment {
private FragmentSettingsBinding binding;
+ @Override
+ public String getName() {
+ return "Settings";
+ }
+
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListAdapter.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListAdapter.java
new file mode 100644
index 0000000..d5771eb
--- /dev/null
+++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListAdapter.java
@@ -0,0 +1,93 @@
+package com.cringe_studios.cringe_authenticator.grouplist;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.util.Consumer;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.cringe_studios.cringe_authenticator.OTPData;
+import com.cringe_studios.cringe_authenticator.databinding.MenuItemBinding;
+import com.cringe_studios.cringe_authenticator.fragment.DynamicFragment;
+import com.cringe_studios.cringe_authenticator.util.NavigationUtil;
+import com.cringe_studios.cringe_authenticator.util.SettingsUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GroupListAdapter extends RecyclerView.Adapter {
+
+ private Context context;
+
+ private LayoutInflater inflater;
+
+ private List items;
+
+ private Handler handler;
+
+ private Consumer navigateToGroup;
+
+ private Consumer removeGroup;
+
+ public GroupListAdapter(Context context, Consumer navigateToGroup, Consumer removeGroup) {
+ this.context = context;
+ this.navigateToGroup = navigateToGroup;
+ this.removeGroup = removeGroup;
+ this.inflater = LayoutInflater.from(context);
+ this.items = new ArrayList<>();
+ this.handler = new Handler(Looper.getMainLooper());
+ }
+
+ @NonNull
+ @Override
+ public GroupListItem onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ MenuItemBinding binding = MenuItemBinding.inflate(inflater, parent, false);
+ return new GroupListItem(binding);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull GroupListItem holder, int position) {
+ String group = items.get(position);
+
+ holder.getBinding().button.setText(group);
+
+ holder.getBinding().button.setOnClickListener(view -> navigateToGroup.accept(group));
+ holder.getBinding().button.setOnLongClickListener(view -> {
+ new AlertDialog.Builder(context)
+ .setTitle("Delete?")
+ .setMessage("Delete this?")
+ .setPositiveButton("Yes", (dialog, which) -> removeGroup.accept(group))
+ .setNegativeButton("No", (dialog, which) -> {})
+ .show();
+ // TODO: better method?
+ // TODO: actually delete
+ return true;
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return items.size();
+ }
+
+ public void add(String group) {
+ items.add(group);
+ notifyItemInserted(items.size() - 1);
+ }
+
+ public void remove(String group) {
+ int index = items.indexOf(group);
+ if(index == -1) return;
+ items.remove(group);
+ notifyItemRemoved(index);
+ }
+
+}
diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListItem.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListItem.java
new file mode 100644
index 0000000..3e44f33
--- /dev/null
+++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListItem.java
@@ -0,0 +1,23 @@
+package com.cringe_studios.cringe_authenticator.grouplist;
+
+import android.view.MenuItem;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.cringe_studios.cringe_authenticator.databinding.MenuItemBinding;
+
+public class GroupListItem extends RecyclerView.ViewHolder {
+
+ private MenuItemBinding binding;
+
+ public GroupListItem(@NonNull MenuItemBinding binding) {
+ super(binding.getRoot());
+ this.binding = binding;
+ }
+
+ public MenuItemBinding getBinding() {
+ return binding;
+ }
+}
diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/otplist/OTPListAdapter.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/otplist/OTPListAdapter.java
index ee769a0..f446448 100644
--- a/app/src/main/java/com/cringe_studios/cringe_authenticator/otplist/OTPListAdapter.java
+++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/otplist/OTPListAdapter.java
@@ -68,6 +68,7 @@ public class OTPListAdapter extends RecyclerView.Adapter {
public void remove(OTPData data) {
int index = items.indexOf(data);
+ if(index == -1) return;
items.remove(data);
notifyItemRemoved(index);
}
diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/NavigationUtil.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/NavigationUtil.java
index c53cbe4..555ef70 100644
--- a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/NavigationUtil.java
+++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/NavigationUtil.java
@@ -3,28 +3,44 @@ package com.cringe_studios.cringe_authenticator.util;
import android.content.Context;
import android.os.Bundle;
+import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.cringe_studios.cringe_authenticator.R;
+import com.cringe_studios.cringe_authenticator.fragment.NamedFragment;
+
+import kotlin.Suppress;
public class NavigationUtil {
- public static void navigate(AppCompatActivity activity, Class extends Fragment> fragmentClass, Bundle args) {
- activity.getSupportActionBar().setTitle(fragmentClass.getSimpleName());
- navigate(activity.getSupportFragmentManager().getPrimaryNavigationFragment().getChildFragmentManager(), fragmentClass, args);
+ public static void navigate(AppCompatActivity activity, Class extends NamedFragment> fragmentClass, Bundle args) {
+ FragmentManager manager = activity.getSupportFragmentManager().getPrimaryNavigationFragment().getChildFragmentManager();
+ NamedFragment fragment = instantiateFragment(manager, fragmentClass, args);
+
+ ActionBar bar = activity.getSupportActionBar();
+ navigate(manager, fragment, () -> {
+ if(bar != null) bar.setTitle(fragment.getName());
+ });
}
- public static void navigate(Fragment currentFragment, Class extends Fragment> fragmentClass, Bundle args) {
- ((AppCompatActivity) currentFragment.getActivity()).getSupportActionBar().setTitle(fragmentClass.getSimpleName());
- navigate(currentFragment.getParentFragment().getChildFragmentManager(), fragmentClass, args);
+ public static void navigate(Fragment currentFragment, Class extends NamedFragment> fragmentClass, Bundle args) {
+ navigate((AppCompatActivity) currentFragment.requireActivity(), fragmentClass, args);
}
- private static void navigate(FragmentManager manager, Class extends Fragment> fragmentClass, Bundle args) {
+ @SuppressWarnings("unchecked")
+ private static T instantiateFragment(FragmentManager manager, Class extends T> fragmentClass, Bundle args) {
+ T fragment = (T) manager.getFragmentFactory().instantiate(ClassLoader.getSystemClassLoader(), fragmentClass.getName());
+ if(args != null) fragment.setArguments(args);
+ return fragment;
+ }
+
+ private static void navigate(FragmentManager manager, Fragment fragment, Runnable onCommit) {
manager.beginTransaction()
.setReorderingAllowed(true)
- .replace(R.id.nav_host_fragment_content_main, fragmentClass, args)
+ .replace(R.id.nav_host_fragment_content_main, fragment)
+ .runOnCommit(onCommit)
.commit();
}
diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/SettingsUtil.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/SettingsUtil.java
index 8e81b7f..2c4f3e4 100644
--- a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/SettingsUtil.java
+++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/SettingsUtil.java
@@ -41,21 +41,49 @@ public class SettingsUtil {
private static final Gson GSON = new Gson();
- // TODO: refactor
- public static List getOTPs(SharedPreferences prefs, String group) {
- String currentOTPs = prefs.getString("group." + group, "[]");
+ public static List getGroups(Context ctx) {
+ SharedPreferences prefs = ctx.getSharedPreferences(GROUPS_PREFS_NAME, Context.MODE_PRIVATE);
+ return Arrays.asList(GSON.fromJson(prefs.getString("groups", "[]"), String[].class));
+ }
+
+ public static void addGroup(Context ctx, String group) {
+ List groups = new ArrayList<>(getGroups(ctx));
+ groups.add(group);
+
+ SharedPreferences prefs = ctx.getSharedPreferences(GROUPS_PREFS_NAME, Context.MODE_PRIVATE);
+ prefs.edit().putString("groups", GSON.toJson(groups)).apply();
+ }
+
+ public static void removeGroup(Context ctx, String group) {
+ List groups = new ArrayList<>(getGroups(ctx));
+ groups.remove(group);
+
+ SharedPreferences prefs = ctx.getSharedPreferences(GROUPS_PREFS_NAME, Context.MODE_PRIVATE);
+ prefs.edit().putString("groups", GSON.toJson(groups)).apply();
+
+ deleteOTPs(ctx, group);
+ }
+
+ public static List getOTPs(Context ctx, String group) {
+ String currentOTPs = ctx.getSharedPreferences(GROUPS_PREFS_NAME, Context.MODE_PRIVATE).getString("group." + group, "[]");
return Arrays.asList(GSON.fromJson(currentOTPs, OTPData[].class));
}
- public static void addOTP(SharedPreferences prefs, String group, @NonNull OTPData data) {
- List otps = new ArrayList<>(getOTPs(prefs, group));
+ public static void addOTP(Context ctx, String group, @NonNull OTPData data) {
+ List otps = new ArrayList<>(getOTPs(ctx, group));
otps.add(data);
- prefs.edit()
+ ctx.getSharedPreferences(GROUPS_PREFS_NAME, Context.MODE_PRIVATE).edit()
.putString("group." + group, GSON.toJson(otps.toArray(new OTPData[0])))
.apply();
}
+ private static void deleteOTPs(Context ctx, String group) {
+ ctx.getSharedPreferences(GROUPS_PREFS_NAME, Context.MODE_PRIVATE).edit()
+ .remove("group." + group)
+ .apply();
+ }
+
public static void setEnableIntroVideo(Context ctx, boolean enableIntroVideo) {
SharedPreferences prefs = ctx.getSharedPreferences(GENERAL_PREFS_NAME, Context.MODE_PRIVATE);
prefs.edit().putBoolean("enableIntroVideo", enableIntroVideo).apply();
diff --git a/app/src/main/res/layout/dialog_input_code_hotp.xml b/app/src/main/res/layout/dialog_input_code_hotp.xml
new file mode 100644
index 0000000..fc45af5
--- /dev/null
+++ b/app/src/main/res/layout/dialog_input_code_hotp.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_input_code_totp.xml b/app/src/main/res/layout/dialog_input_code_totp.xml
index eccbf65..806c3d0 100644
--- a/app/src/main/res/layout/dialog_input_code_totp.xml
+++ b/app/src/main/res/layout/dialog_input_code_totp.xml
@@ -11,7 +11,8 @@
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text"
- android:hint="Name" />
+ android:hint="Name"
+ android:autofillHints="" />
+ android:hint="Secret"
+ android:autofillHints="" />
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_menu.xml b/app/src/main/res/layout/fragment_menu.xml
index e001a15..98e5064 100644
--- a/app/src/main/res/layout/fragment_menu.xml
+++ b/app/src/main/res/layout/fragment_menu.xml
@@ -11,7 +11,7 @@
android:layout_height="match_parent"
android:padding="16dp">
-
-
+ -->
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/menu_item.xml b/app/src/main/res/layout/menu_item.xml
index a8f5d5c..57f7894 100644
--- a/app/src/main/res/layout/menu_item.xml
+++ b/app/src/main/res/layout/menu_item.xml
@@ -11,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button"
- android:background="@drawable/button_themed" />
+ android:background="@drawable/button_themed"
+ android:textAllCaps="false" />
\ No newline at end of file