Add manage icon packs dialog

This commit is contained in:
MrLetsplay 2023-10-01 15:44:01 +02:00
parent fb3163f21a
commit f66de7fd78
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
8 changed files with 164 additions and 1 deletions

View File

@ -12,6 +12,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -21,6 +22,7 @@ import androidx.exifinterface.media.ExifInterface;
import com.cringe_studios.cringe_authenticator.MainActivity;
import com.cringe_studios.cringe_authenticator.R;
import com.cringe_studios.cringe_authenticator.databinding.FragmentEditOtpBinding;
import com.cringe_studios.cringe_authenticator.icon.IconPack;
import com.cringe_studios.cringe_authenticator.icon.IconUtil;
import com.cringe_studios.cringe_authenticator.model.OTPData;
import com.cringe_studios.cringe_authenticator.util.DialogUtil;
@ -36,6 +38,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
public class EditOTPFragment extends NamedFragment {
@ -184,7 +187,12 @@ public class EditOTPFragment extends NamedFragment {
}
private void pickImageFromIconPack() {
// TODO: check if icon packs installed
List<IconPack> packs = IconUtil.loadAllIconPacks(requireContext());
if(packs.isEmpty()) {
Toast.makeText(requireContext(), R.string.no_icon_packs_installed, Toast.LENGTH_LONG).show();
return;
}
new PickIconDrawerFragment(icon -> {
imageData = Base64.encodeToString(icon.getBytes(), Base64.DEFAULT);
updateImage();

View File

@ -8,9 +8,11 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.cringe_studios.cringe_authenticator.MainActivity;
import com.cringe_studios.cringe_authenticator.R;
@ -20,7 +22,11 @@ import com.cringe_studios.cringe_authenticator.crypto.BiometricKey;
import com.cringe_studios.cringe_authenticator.crypto.Crypto;
import com.cringe_studios.cringe_authenticator.crypto.CryptoException;
import com.cringe_studios.cringe_authenticator.crypto.CryptoParameters;
import com.cringe_studios.cringe_authenticator.databinding.DialogManageIconPacksBinding;
import com.cringe_studios.cringe_authenticator.databinding.FragmentSettingsBinding;
import com.cringe_studios.cringe_authenticator.icon.IconPack;
import com.cringe_studios.cringe_authenticator.icon.IconPackListAdapter;
import com.cringe_studios.cringe_authenticator.icon.IconUtil;
import com.cringe_studios.cringe_authenticator.util.Appearance;
import com.cringe_studios.cringe_authenticator.util.BackupException;
import com.cringe_studios.cringe_authenticator.util.BiometricUtil;
@ -32,6 +38,7 @@ import com.cringe_studios.cringe_authenticator.util.StyledDialogBuilder;
import com.cringe_studios.cringe_authenticator.util.Theme;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import javax.crypto.SecretKey;
@ -256,6 +263,25 @@ public class SettingsFragment extends NamedFragment {
binding.settingsLoadIconPack.setOnClickListener(v -> ((MainActivity) requireActivity()).promptPickIconPackLoad());
binding.settingsManageIconPacks.setOnClickListener(v -> {
List<IconPack> packs = IconUtil.loadAllIconPacks(requireContext());
if(packs.isEmpty()) {
Toast.makeText(requireContext(), R.string.no_icon_packs_installed, Toast.LENGTH_LONG).show();
return;
}
DialogManageIconPacksBinding binding = DialogManageIconPacksBinding.inflate(getLayoutInflater());
binding.manageIconPacksList.setLayoutManager(new LinearLayoutManager(requireContext()));
binding.manageIconPacksList.setAdapter(new IconPackListAdapter(requireContext(), IconUtil.loadAllIconPacks(requireContext())));
new StyledDialogBuilder(requireContext())
.setTitle("Manage icon packs")
.setView(binding.getRoot())
.setPositiveButton(R.string.ok, (d, which) -> {})
.show();
});
return binding.getRoot();
}

View File

@ -0,0 +1,31 @@
package com.cringe_studios.cringe_authenticator.icon;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.cringe_studios.cringe_authenticator.databinding.DialogManageIconPacksItemBinding;
public class IconPackItem extends RecyclerView.ViewHolder {
private DialogManageIconPacksItemBinding binding;
private IconPack pack;
public IconPackItem(@NonNull DialogManageIconPacksItemBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
public DialogManageIconPacksItemBinding getBinding() {
return binding;
}
public void setPack(IconPack pack) {
this.pack = pack;
}
public IconPack getPack() {
return pack;
}
}

View File

@ -0,0 +1,52 @@
package com.cringe_studios.cringe_authenticator.icon;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.cringe_studios.cringe_authenticator.R;
import com.cringe_studios.cringe_authenticator.databinding.DialogManageIconPacksItemBinding;
import com.cringe_studios.cringe_authenticator.util.DialogUtil;
import java.util.List;
public class IconPackListAdapter extends RecyclerView.Adapter<IconPackItem> {
private Context context;
private LayoutInflater inflater;
private List<IconPack> packs;
public IconPackListAdapter(Context context, List<IconPack> packs) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.packs = packs;
}
@NonNull
@Override
public IconPackItem onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new IconPackItem(DialogManageIconPacksItemBinding.inflate(inflater, parent, false));
}
@Override
public void onBindViewHolder(@NonNull IconPackItem holder, int position) {
IconPack pack = packs.get(position);
holder.setPack(pack);
holder.getBinding().iconPackName.setText(pack.getMetadata().getName());
holder.getBinding().iconPackDelete.setOnClickListener(view -> {
DialogUtil.showYesNo(context, R.string.delete_pack_title, R.string.delete_pack_message, () -> IconUtil.removeIconPack(context, pack.getMetadata().getUuid()), null);
});
}
@Override
public int getItemCount() {
return packs.size();
}
}

View File

@ -103,6 +103,12 @@ public class IconUtil {
return meta;
}
public static void removeIconPack(Context context, String uuid) {
File packFile = new File(getIconPacksDir(context), uuid);
packFile.delete();
loadedPacks.remove(uuid);
}
private static IconPackMetadata loadPackMetadata(Context context, Uri uri) throws IconPackException {
try(InputStream in = context.getContentResolver().openInputStream(uri)) {
if(in == null) throw new IconPackException("Failed to read icon pack");

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/manage_icon_packs_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="@+id/icon_pack_name"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:gravity="left|center"
tools:text="My Icon Pack"/>
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/icon_pack_delete"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@android:color/transparent"
android:src="@drawable/baseline_delete_24" />
</LinearLayout>

View File

@ -104,4 +104,7 @@
<string name="otp_add_algorithm">Algorithm</string>
<string name="otp_add_digits">Digits</string>
<string name="show_images">Show Images</string>
<string name="delete_pack_title">Delete pack</string>
<string name="delete_pack_message">Do you want to delete the icon pack?</string>
<string name="no_icon_packs_installed">No icon packs are currently installed</string>
</resources>