Add option to download icon packs to settings
This commit is contained in:
parent
b30b0df5b4
commit
baac0ccec2
@ -3,7 +3,20 @@
|
|||||||
<component name="deploymentTargetDropDown">
|
<component name="deploymentTargetDropDown">
|
||||||
<value>
|
<value>
|
||||||
<entry key="app">
|
<entry key="app">
|
||||||
<State />
|
<State>
|
||||||
|
<targetSelectedWithDropDown>
|
||||||
|
<Target>
|
||||||
|
<type value="QUICK_BOOT_TARGET" />
|
||||||
|
<deviceKey>
|
||||||
|
<Key>
|
||||||
|
<type value="VIRTUAL_DEVICE_PATH" />
|
||||||
|
<value value="$USER_HOME$/.android/avd/Pixel_2_API_34.avd" />
|
||||||
|
</Key>
|
||||||
|
</deviceKey>
|
||||||
|
</Target>
|
||||||
|
</targetSelectedWithDropDown>
|
||||||
|
<timeTargetWasSelectedWithDropDown value="2024-04-21T10:28:14.063607866Z" />
|
||||||
|
</State>
|
||||||
</entry>
|
</entry>
|
||||||
</value>
|
</value>
|
||||||
</component>
|
</component>
|
||||||
|
@ -22,8 +22,11 @@ import com.cringe_studios.code_guard.crypto.BiometricKey;
|
|||||||
import com.cringe_studios.code_guard.crypto.Crypto;
|
import com.cringe_studios.code_guard.crypto.Crypto;
|
||||||
import com.cringe_studios.code_guard.crypto.CryptoException;
|
import com.cringe_studios.code_guard.crypto.CryptoException;
|
||||||
import com.cringe_studios.code_guard.crypto.CryptoParameters;
|
import com.cringe_studios.code_guard.crypto.CryptoParameters;
|
||||||
|
import com.cringe_studios.code_guard.databinding.DialogDownloadIconPacksBinding;
|
||||||
import com.cringe_studios.code_guard.databinding.DialogManageIconPacksBinding;
|
import com.cringe_studios.code_guard.databinding.DialogManageIconPacksBinding;
|
||||||
import com.cringe_studios.code_guard.databinding.FragmentSettingsBinding;
|
import com.cringe_studios.code_guard.databinding.FragmentSettingsBinding;
|
||||||
|
import com.cringe_studios.code_guard.icon.DownloadIconPackListAdapter;
|
||||||
|
import com.cringe_studios.code_guard.icon.DownloadableIconPack;
|
||||||
import com.cringe_studios.code_guard.icon.IconPack;
|
import com.cringe_studios.code_guard.icon.IconPack;
|
||||||
import com.cringe_studios.code_guard.icon.IconPackListAdapter;
|
import com.cringe_studios.code_guard.icon.IconPackListAdapter;
|
||||||
import com.cringe_studios.code_guard.icon.IconUtil;
|
import com.cringe_studios.code_guard.icon.IconUtil;
|
||||||
@ -275,6 +278,19 @@ public class SettingsFragment extends NamedFragment {
|
|||||||
|
|
||||||
binding.settingsLoadIconPack.setOnClickListener(v -> ((MainActivity) requireActivity()).promptPickIconPackFile());
|
binding.settingsLoadIconPack.setOnClickListener(v -> ((MainActivity) requireActivity()).promptPickIconPackFile());
|
||||||
|
|
||||||
|
binding.settingsDownloadIconPacks.setOnClickListener(v -> {
|
||||||
|
DialogDownloadIconPacksBinding binding = DialogDownloadIconPacksBinding.inflate(getLayoutInflater());
|
||||||
|
|
||||||
|
binding.downloadIconPacksList.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||||
|
binding.downloadIconPacksList.setAdapter(new DownloadIconPackListAdapter(requireContext(), Arrays.asList(DownloadableIconPack.values())));
|
||||||
|
|
||||||
|
new StyledDialogBuilder(requireContext())
|
||||||
|
.setTitle(R.string.download_icon_packs_title)
|
||||||
|
.setView(binding.getRoot())
|
||||||
|
.setPositiveButton(R.string.ok, (d, which) -> {})
|
||||||
|
.show();
|
||||||
|
});
|
||||||
|
|
||||||
binding.settingsManageIconPacks.setOnClickListener(v -> {
|
binding.settingsManageIconPacks.setOnClickListener(v -> {
|
||||||
List<String> brokenPacks = new ArrayList<>();
|
List<String> brokenPacks = new ArrayList<>();
|
||||||
List<IconPack> packs = IconUtil.loadAllIconPacks(requireContext(), brokenPacks::add);
|
List<IconPack> packs = IconUtil.loadAllIconPacks(requireContext(), brokenPacks::add);
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.cringe_studios.code_guard.icon;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.cringe_studios.code_guard.databinding.DialogDownloadIconPacksItemBinding;
|
||||||
|
|
||||||
|
public class DownloadIconPackItem extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
private final DialogDownloadIconPacksItemBinding binding;
|
||||||
|
|
||||||
|
private DownloadableIconPack pack;
|
||||||
|
|
||||||
|
public DownloadIconPackItem(@NonNull DialogDownloadIconPacksItemBinding binding) {
|
||||||
|
super(binding.getRoot());
|
||||||
|
this.binding = binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DialogDownloadIconPacksItemBinding getBinding() {
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPack(DownloadableIconPack pack) {
|
||||||
|
this.pack = pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadableIconPack getPack() {
|
||||||
|
return pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
package com.cringe_studios.code_guard.icon;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.cringe_studios.code_guard.R;
|
||||||
|
import com.cringe_studios.code_guard.databinding.DialogDownloadIconPacksItemBinding;
|
||||||
|
import com.cringe_studios.code_guard.util.DialogUtil;
|
||||||
|
import com.cringe_studios.code_guard.util.StyledDialogBuilder;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
public class DownloadIconPackListAdapter extends RecyclerView.Adapter<DownloadIconPackItem> {
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
|
|
||||||
|
private final LayoutInflater inflater;
|
||||||
|
|
||||||
|
private final List<DownloadableIconPack> packs;
|
||||||
|
|
||||||
|
private final Handler handler;
|
||||||
|
|
||||||
|
public DownloadIconPackListAdapter(Context context, List<DownloadableIconPack> packs) {
|
||||||
|
this.context = context;
|
||||||
|
this.inflater = LayoutInflater.from(context);
|
||||||
|
this.packs = packs;
|
||||||
|
this.handler = new Handler(Looper.getMainLooper());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public DownloadIconPackItem onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
return new DownloadIconPackItem(DialogDownloadIconPacksItemBinding.inflate(inflater, parent, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull DownloadIconPackItem holder, int position) {
|
||||||
|
DownloadableIconPack pack = packs.get(position);
|
||||||
|
holder.setPack(pack);
|
||||||
|
|
||||||
|
holder.getBinding().iconPackName.setText(pack.getName());
|
||||||
|
holder.getBinding().iconPackCredit.setText(pack.getCredit());
|
||||||
|
|
||||||
|
IconPack installedPack = null;
|
||||||
|
try {
|
||||||
|
installedPack = IconUtil.loadIconPack(context, pack.getId());
|
||||||
|
} catch (IconPackException ignored) { /* ignored, the user can just download the icon pack again */ }
|
||||||
|
|
||||||
|
if(installedPack != null) {
|
||||||
|
holder.getBinding().iconPackDownload.setImageResource(R.drawable.baseline_refresh_24);
|
||||||
|
holder.getBinding().iconPackInstalled.setText(context.getString(R.string.icon_pack_version, installedPack.getMetadata().getVersion()));
|
||||||
|
}else {
|
||||||
|
holder.getBinding().iconPackInstalled.setText(R.string.icon_pack_not_installed);
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.getBinding().iconPackDownload.setOnClickListener(view -> {
|
||||||
|
AlertDialog dialog = new StyledDialogBuilder(context)
|
||||||
|
.setTitle(R.string.icon_pack_downloading_title)
|
||||||
|
.setMessage(R.string.icon_pack_downloading_message)
|
||||||
|
.setCancelable(false)
|
||||||
|
.show();
|
||||||
|
|
||||||
|
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||||
|
executor.submit(() -> {
|
||||||
|
executor.shutdown();
|
||||||
|
|
||||||
|
File file = null;
|
||||||
|
try {
|
||||||
|
file = File.createTempFile("iconpack", ".zip", context.getCacheDir());
|
||||||
|
pack.download(file);
|
||||||
|
|
||||||
|
IconPackMetadata meta = IconUtil.importIconPack(context, Uri.fromFile(file));
|
||||||
|
|
||||||
|
handler.post(() -> {
|
||||||
|
dialog.dismiss();
|
||||||
|
notifyItemChanged(position);
|
||||||
|
Toast.makeText(context, context.getString(R.string.icon_pack_imported, meta.getIcons().length), Toast.LENGTH_LONG).show();
|
||||||
|
});
|
||||||
|
}catch(Exception e) {
|
||||||
|
handler.post(() -> {
|
||||||
|
dialog.dismiss();
|
||||||
|
DialogUtil.showErrorDialog(context, context.getString(R.string.error_import_icon_pack), e);
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
if(file != null) file.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return packs.size();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
package com.cringe_studios.code_guard.icon;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.cringe_studios.code_guard.util.DownloadUtil;
|
||||||
|
import com.cringe_studios.code_guard.util.SettingsUtil;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public enum DownloadableIconPack {
|
||||||
|
|
||||||
|
AEGIS_ICONS("c1018b93-4e8c-490a-b575-30dde62a833e", "aegis-icons", "https://aegis-icons.github.io/", "https://github.com/aegis-icons/aegis-icons/releases/latest/download/aegis-icons.zip"),
|
||||||
|
AEGIS_SIMPLE_ICONS("6a371ea0-1178-4677-ae93-cda7a7a5b378", "aegis-simple-icons", "https://github.com/alexbakker/aegis-simple-icons", () -> {
|
||||||
|
String apiURL = "https://api.github.com/repos/alexbakker/aegis-simple-icons/releases/latest";
|
||||||
|
JsonObject object = SettingsUtil.GSON.fromJson(new String(DownloadUtil.downloadURL(apiURL), StandardCharsets.UTF_8), JsonObject.class);
|
||||||
|
return object.get("assets").getAsJsonArray()
|
||||||
|
.get(0).getAsJsonObject()
|
||||||
|
.get("browser_download_url").getAsString();
|
||||||
|
}),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String id;
|
||||||
|
private final String name;
|
||||||
|
private final String credit;
|
||||||
|
private final URLLoader url;
|
||||||
|
|
||||||
|
DownloadableIconPack(String id, String name, String credit, URLLoader url) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.credit = credit;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadableIconPack(String id, String name, String credit, String url) {
|
||||||
|
this(id, name, credit, () -> url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCredit() {
|
||||||
|
return credit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void download(File destinationFile) throws IOException {
|
||||||
|
String downloadURL = url.load();
|
||||||
|
Log.d("Download", "Downloading from " + downloadURL);
|
||||||
|
try(InputStream in = DownloadUtil.openURL(downloadURL);
|
||||||
|
FileOutputStream fOut = new FileOutputStream(destinationFile)) {
|
||||||
|
byte[] buf = new byte[1024];
|
||||||
|
int len;
|
||||||
|
while((len = in.read(buf)) != -1) {
|
||||||
|
fOut.write(buf, 0, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface URLLoader {
|
||||||
|
|
||||||
|
String load() throws IOException;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -24,7 +24,7 @@ public class IconMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getCategory() {
|
public String getCategory() {
|
||||||
return category;
|
return category == null ? "No category" : category;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getIssuer() {
|
public String[] getIssuer() {
|
||||||
@ -32,7 +32,7 @@ public class IconMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean validate() {
|
public boolean validate() {
|
||||||
return filename != null && category != null && issuer != null;
|
return filename != null && issuer != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,16 @@ public class IconUtil {
|
|||||||
return iconPacksDir;
|
return iconPacksDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void importIconPack(Context context, Uri uri) throws IconPackException {
|
public static List<String> getIconPackIds(Context context) {
|
||||||
|
File iconPacksDir = getIconPacksDir(context);
|
||||||
|
|
||||||
|
String[] packIDs = iconPacksDir.list();
|
||||||
|
if(packIDs == null) return Collections.emptyList();
|
||||||
|
|
||||||
|
return Arrays.asList(packIDs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IconPackMetadata importIconPack(Context context, Uri uri) throws IconPackException {
|
||||||
IconPackMetadata meta = loadPackMetadata(context, uri);
|
IconPackMetadata meta = loadPackMetadata(context, uri);
|
||||||
|
|
||||||
File iconPackFile = new File(getIconPacksDir(context), meta.getUuid());
|
File iconPackFile = new File(getIconPacksDir(context), meta.getUuid());
|
||||||
@ -98,6 +107,8 @@ public class IconUtil {
|
|||||||
byte[] bytes = IOUtil.readBytes(in);
|
byte[] bytes = IOUtil.readBytes(in);
|
||||||
out.write(bytes);
|
out.write(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return meta;
|
||||||
}catch(IOException e) {
|
}catch(IOException e) {
|
||||||
throw new IconPackException("Failed to import icon pack", e);
|
throw new IconPackException("Failed to import icon pack", e);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.cringe_studios.code_guard.util;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
public class DownloadUtil {
|
||||||
|
|
||||||
|
public static InputStream openURL(String url) throws IOException {
|
||||||
|
return new URL(url).openStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] downloadURL(String url) throws IOException {
|
||||||
|
try(InputStream in = openURL(url)) {
|
||||||
|
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||||
|
byte[] buf = new byte[1024];
|
||||||
|
int len;
|
||||||
|
while ((len = in.read(buf)) != -1) {
|
||||||
|
bOut.write(buf, 0, len);
|
||||||
|
}
|
||||||
|
return bOut.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
5
app/src/main/res/drawable/baseline_download_24.xml
Normal file
5
app/src/main/res/drawable/baseline_download_24.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M5,20h14v-2H5V20zM19,9h-4V3H9v6H5l7,7L19,9z"/>
|
||||||
|
|
||||||
|
</vector>
|
13
app/src/main/res/layout/dialog_download_icon_packs.xml
Normal file
13
app/src/main/res/layout/dialog_download_icon_packs.xml
Normal 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/download_icon_packs_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
48
app/src/main/res/layout/dialog_download_icon_packs_item.xml
Normal file
48
app/src/main/res/layout/dialog_download_icon_packs_item.xml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?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">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/icon_pack_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="start|center"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="My Icon Pack" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/icon_pack_credit"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="start|center"
|
||||||
|
android:autoLink="web"
|
||||||
|
tools:text="https://cringe-studios.com/my-icon-pack" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/icon_pack_installed"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="start|center"
|
||||||
|
android:autoLink="web"
|
||||||
|
tools:text="Not installed" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/icon_pack_download"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:src="@drawable/baseline_download_24"
|
||||||
|
android:layout_gravity="center"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -197,6 +197,15 @@
|
|||||||
android:text="@string/settings_icon_packs_import"
|
android:text="@string/settings_icon_packs_import"
|
||||||
android:textAllCaps="false" />
|
android:textAllCaps="false" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
|
android:id="@+id/settings_download_icon_packs"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:background="?attr/buttonBackground"
|
||||||
|
android:text="@string/settings_icon_packs_download"
|
||||||
|
android:textAllCaps="false" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatButton
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:id="@+id/settings_manage_icon_packs"
|
android:id="@+id/settings_manage_icon_packs"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -176,4 +176,10 @@
|
|||||||
<string name="settings_cringe_icon">Extra-Cringe-Symbol verwenden</string>
|
<string name="settings_cringe_icon">Extra-Cringe-Symbol verwenden</string>
|
||||||
<string name="otp_copy_error">Kopieren des OTP-Codes fehlgeschlagen</string>
|
<string name="otp_copy_error">Kopieren des OTP-Codes fehlgeschlagen</string>
|
||||||
<string name="otp_copied">OTP-Code in die Zwischenablage kopiert</string>
|
<string name="otp_copied">OTP-Code in die Zwischenablage kopiert</string>
|
||||||
|
<string name="settings_icon_packs_download">Symbolpakete herunterladen</string>
|
||||||
|
<string name="download_icon_packs_title">Symbolpakete herunterladen</string>
|
||||||
|
<string name="icon_pack_not_installed">Nicht installiert</string>
|
||||||
|
<string name="icon_pack_version">Installiert (version %d)</string>
|
||||||
|
<string name="icon_pack_downloading_title">Symbolpaket wird heruntergeladen</string>
|
||||||
|
<string name="icon_pack_downloading_message">Bitte habe einen Moment Geduld…</string>
|
||||||
</resources>
|
</resources>
|
@ -162,4 +162,10 @@
|
|||||||
<string name="settings_cringe_icon">Utiliser l\'icône de l\'humour supplémentaire</string>
|
<string name="settings_cringe_icon">Utiliser l\'icône de l\'humour supplémentaire</string>
|
||||||
<string name="otp_copy_error">Échec de la copie de l\'OTP dans le presse-papiers</string>
|
<string name="otp_copy_error">Échec de la copie de l\'OTP dans le presse-papiers</string>
|
||||||
<string name="otp_copied">OTP copié dans le presse-papiers</string>
|
<string name="otp_copied">OTP copié dans le presse-papiers</string>
|
||||||
|
<string name="settings_icon_packs_download">Télécharger les packs d\'icônes</string>
|
||||||
|
<string name="download_icon_packs_title">Télécharger les packs d\'icônes</string>
|
||||||
|
<string name="icon_pack_not_installed">Non installé</string>
|
||||||
|
<string name="icon_pack_version">Installé (version %d)</string>
|
||||||
|
<string name="icon_pack_downloading_title">Téléchargement du pack d\'icônes</string>
|
||||||
|
<string name="icon_pack_downloading_message">Veuillez patienter un instant…</string>
|
||||||
</resources>
|
</resources>
|
@ -162,4 +162,10 @@
|
|||||||
<string name="settings_cringe_icon">Użyj dodatkowej ikony cringe</string>
|
<string name="settings_cringe_icon">Użyj dodatkowej ikony cringe</string>
|
||||||
<string name="otp_copy_error">Nie udało się skopiować OTP do schowka</string>
|
<string name="otp_copy_error">Nie udało się skopiować OTP do schowka</string>
|
||||||
<string name="otp_copied">OTP skopiowany do schowka</string>
|
<string name="otp_copied">OTP skopiowany do schowka</string>
|
||||||
|
<string name="settings_icon_packs_download">Pobierz pakiety ikon</string>
|
||||||
|
<string name="download_icon_packs_title">Pobierz pakiety ikon</string>
|
||||||
|
<string name="icon_pack_not_installed">Nie zainstalowano</string>
|
||||||
|
<string name="icon_pack_version">Zainstalowano (wersja %d)</string>
|
||||||
|
<string name="icon_pack_downloading_title">Pobieranie pakietu ikon</string>
|
||||||
|
<string name="icon_pack_downloading_message">Poczekaj chwilę…</string>
|
||||||
</resources>
|
</resources>
|
@ -162,4 +162,10 @@
|
|||||||
<string name="settings_cringe_icon">Використовуйте додаткову піктограму обтиснення</string>
|
<string name="settings_cringe_icon">Використовуйте додаткову піктограму обтиснення</string>
|
||||||
<string name="otp_copy_error">Не вдалося скопіювати OTP до буфера обміну</string>
|
<string name="otp_copy_error">Не вдалося скопіювати OTP до буфера обміну</string>
|
||||||
<string name="otp_copied">OTP скопійовано в буфер обміну</string>
|
<string name="otp_copied">OTP скопійовано в буфер обміну</string>
|
||||||
|
<string name="settings_icon_packs_download">Завантажити пакети іконок</string>
|
||||||
|
<string name="download_icon_packs_title">Завантажити пакети іконок</string>
|
||||||
|
<string name="icon_pack_not_installed">Не встановлено</string>
|
||||||
|
<string name="icon_pack_version">Встановлено (версія %d)</string>
|
||||||
|
<string name="icon_pack_downloading_title">Завантаження пакета іконок</string>
|
||||||
|
<string name="icon_pack_downloading_message">Будь ласка, зачекайте хвилинку…</string>
|
||||||
</resources>
|
</resources>
|
@ -125,7 +125,7 @@
|
|||||||
<string name="patreon_link" translatable="false">https://git.cringe-studios.com/CringeStudios/Code-Guard</string>
|
<string name="patreon_link" translatable="false">https://git.cringe-studios.com/CringeStudios/Code-Guard</string>
|
||||||
<string name="error_icon_pack_empty">The icon pack doesn\'t contain any icons</string>
|
<string name="error_icon_pack_empty">The icon pack doesn\'t contain any icons</string>
|
||||||
<string name="error_icon_pack_invalid">Pack contains invalid metadata. Make sure you selected the correct file</string>
|
<string name="error_icon_pack_invalid">Pack contains invalid metadata. Make sure you selected the correct file</string>
|
||||||
<string name="error_icon_pack_exists">The icon pack you\'re trying to import already exists.\n\nImported: %s (version %d)\nExisting: %s (version %d) What do you want to do?</string>
|
<string name="error_icon_pack_exists">The icon pack you\'re trying to import already exists.\n\nImported: %s (version %d)\nExisting: %s (version %d)\n\nWhat do you want to do?</string>
|
||||||
<string name="broken_icon_packs_title">Broken icon packs</string>
|
<string name="broken_icon_packs_title">Broken icon packs</string>
|
||||||
<string name="broken_icon_packs_message">Some icon packs failed to load.\n\nDo you want to delete the broken icon packs?</string>
|
<string name="broken_icon_packs_message">Some icon packs failed to load.\n\nDo you want to delete the broken icon packs?</string>
|
||||||
<string name="icon_pack_imported">Icon pack with %d icon(s) imported</string>
|
<string name="icon_pack_imported">Icon pack with %d icon(s) imported</string>
|
||||||
@ -183,7 +183,7 @@
|
|||||||
<item>Reset to default image</item>
|
<item>Reset to default image</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="error_icon_pack_exists_choices">
|
<string-array name="error_icon_pack_exists_choices">
|
||||||
<item>Override</item>
|
<item>Overwrite</item>
|
||||||
<item>Rename existing</item>
|
<item>Rename existing</item>
|
||||||
<item>Rename imported</item>
|
<item>Rename imported</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
@ -193,4 +193,10 @@
|
|||||||
<string name="settings_hamburger_mode">I like hamburgers 🍔</string>
|
<string name="settings_hamburger_mode">I like hamburgers 🍔</string>
|
||||||
<string name="settings_cringe_icon">Use extra cringe icon</string>
|
<string name="settings_cringe_icon">Use extra cringe icon</string>
|
||||||
<string name="otp_copied">OTP copied to clipboard</string>
|
<string name="otp_copied">OTP copied to clipboard</string>
|
||||||
|
<string name="settings_icon_packs_download">Download icon packs</string>
|
||||||
|
<string name="download_icon_packs_title">Download icon packs</string>
|
||||||
|
<string name="icon_pack_not_installed">Not installed</string>
|
||||||
|
<string name="icon_pack_version">Installed (version %d)</string>
|
||||||
|
<string name="icon_pack_downloading_title">Downloading icon pack</string>
|
||||||
|
<string name="icon_pack_downloading_message">Please wait a moment…</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user