From 209bd9d22a9fe791e191b7fbc87dfcf4db98c3fc Mon Sep 17 00:00:00 2001 From: artdeell Date: Sun, 3 Sep 2023 18:56:34 +0300 Subject: [PATCH] Feat[profile]: static icons & cache refactor --- .../java/com/kdt/mcgui/mcVersionSpinner.java | 2 +- .../modloaders/FabriclikeDownloadTask.java | 1 + .../modloaders/FabriclikeUtils.java | 11 ++- .../pojavlaunch/profiles/ProfileAdapter.java | 9 +- .../profiles/ProfileIconCache.java | 79 ++++++++++++++++-- .../src/main/res/drawable/ic_fabric.webp | Bin 0 -> 274 bytes .../src/main/res/drawable/ic_pojav_full.webp | Bin 0 -> 11480 bytes .../src/main/res/drawable/ic_quilt.webp | Bin 0 -> 5614 bytes 8 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 app_pojavlauncher/src/main/res/drawable/ic_fabric.webp create mode 100644 app_pojavlauncher/src/main/res/drawable/ic_pojav_full.webp create mode 100644 app_pojavlauncher/src/main/res/drawable/ic_quilt.webp diff --git a/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcVersionSpinner.java b/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcVersionSpinner.java index ae2e66f88..64ab6c35b 100644 --- a/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcVersionSpinner.java +++ b/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcVersionSpinner.java @@ -56,7 +56,7 @@ public class mcVersionSpinner extends ExtendedTextView { private ListView mListView = null; private PopupWindow mPopupWindow = null; private Object mPopupAnimation; - private final ProfileAdapter mProfileAdapter = new ProfileAdapter(getContext(), new ProfileAdapterExtra[]{ + private final ProfileAdapter mProfileAdapter = new ProfileAdapter(new ProfileAdapterExtra[]{ new ProfileAdapterExtra(VERSION_SPINNER_PROFILE_CREATE, R.string.create_profile, ResourcesCompat.getDrawable(getResources(), R.drawable.ic_add, null)), diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabriclikeDownloadTask.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabriclikeDownloadTask.java index fafa06935..706acbce3 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabriclikeDownloadTask.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabriclikeDownloadTask.java @@ -61,6 +61,7 @@ public class FabriclikeDownloadTask implements Runnable, Tools.DownloaderFeedbac MinecraftProfile fabricProfile = new MinecraftProfile(); fabricProfile.lastVersionId = versionId; fabricProfile.name = mUtils.getName(); + fabricProfile.icon = mUtils.getIconName(); LauncherProfiles.insertMinecraftProfile(fabricProfile); LauncherProfiles.write(); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabriclikeUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabriclikeUtils.java index c94528846..9dddb0049 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabriclikeUtils.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabriclikeUtils.java @@ -15,8 +15,8 @@ import java.net.URLEncoder; public class FabriclikeUtils { - public static final FabriclikeUtils FABRIC_UTILS = new FabriclikeUtils("https://meta.fabricmc.net/v2", "fabric", "Fabric"); - public static final FabriclikeUtils QUILT_UTILS = new FabriclikeUtils("https://meta.quiltmc.org/v3", "quilt", "Quilt"); + public static final FabriclikeUtils FABRIC_UTILS = new FabriclikeUtils("https://meta.fabricmc.net/v2", "fabric", "Fabric", "fabric"); + public static final FabriclikeUtils QUILT_UTILS = new FabriclikeUtils("https://meta.quiltmc.org/v3", "quilt", "Quilt", "quilt"); private static final String LOADER_METADATA_URL = "%s/versions/loader/%s"; private static final String GAME_METADATA_URL = "%s/versions/game"; @@ -26,10 +26,12 @@ public class FabriclikeUtils { private final String mApiUrl; private final String mCachePrefix; private final String mName; + private final String mIconName; - private FabriclikeUtils(String mApiUrl, String cachePrefix, String mName) { + private FabriclikeUtils(String mApiUrl, String cachePrefix, String mName, String iconName) { this.mApiUrl = mApiUrl; this.mCachePrefix = cachePrefix; + this.mIconName = iconName; this.mName = mName; } @@ -72,6 +74,9 @@ public class FabriclikeUtils { public String getName() { return mName; } + public String getIconName() { + return mIconName; + } private static FabricVersion[] deserializeLoaderVersions(String input) throws JSONException { JSONArray jsonArray = new JSONArray(input); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapter.java index 91295d5b2..367a73c95 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapter.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapter.java @@ -33,8 +33,7 @@ public class ProfileAdapter extends BaseAdapter { private List mProfileList; private ProfileAdapterExtra[] mExtraEntires; - public ProfileAdapter(Context context, ProfileAdapterExtra[] extraEntries) { - ProfileIconCache.initDefault(context); + public ProfileAdapter(ProfileAdapterExtra[] extraEntries) { reloadProfiles(extraEntries); } /* @@ -96,11 +95,7 @@ public class ProfileAdapter extends BaseAdapter { MinecraftProfile minecraftProfile = mProfiles.get(nm); if(minecraftProfile == null) minecraftProfile = dummy; - Drawable cachedIcon = ProfileIconCache.getCachedIcon(nm); - - if(cachedIcon == null) { - cachedIcon = ProfileIconCache.tryResolveIcon(v.getResources(), nm, minecraftProfile.icon); - } + Drawable cachedIcon = ProfileIconCache.fetchIcon(v.getResources(), nm, minecraftProfile.icon); extendedTextView.setCompoundDrawablesRelative(cachedIcon, null, extendedTextView.getCompoundsDrawables()[2], null); if(Tools.isValidString(minecraftProfile.name)) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileIconCache.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileIconCache.java index ccbd05470..9cf343e9d 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileIconCache.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileIconCache.java @@ -1,7 +1,7 @@ package net.kdt.pojavlaunch.profiles; -import android.content.Context; import android.content.res.Resources; +import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -16,12 +16,81 @@ import java.util.HashMap; import java.util.Map; public class ProfileIconCache { - private static final String BASE64_PNG_HEADER = "data:image/png;base64,"; + // Data header format: data:;, + private static final String DATA_HEADER = "data:"; + private static final String FALLBACK_ICON_NAME = "default"; private static final Map sIconCache = new HashMap<>(); - private static Drawable sDefaultIcon; + private static final Map sStaticIconCache = new HashMap<>(); - public static void initDefault(Context context) { + public static Drawable fetchIcon(Resources resources, String key, String icon) { + Drawable cachedIcon = sIconCache.get(key); + if(cachedIcon != null) return cachedIcon; + if(icon != null && icon.startsWith(DATA_HEADER)) return fetchDataIcon(resources, key, icon); + else return fetchStaticIcon(resources, key, icon); + } + + private static Drawable fetchDataIcon(Resources resources, String key, String icon) { + Drawable dataIcon = readDataIcon(resources, icon); + if(dataIcon == null) dataIcon = fetchFallbackIcon(resources); + sIconCache.put(key, dataIcon); + return dataIcon; + } + + private static Drawable fetchStaticIcon(Resources resources, String key, String icon) { + Drawable staticIcon = sStaticIconCache.get(icon); + if(staticIcon == null) { + if(icon != null) staticIcon = getStaticIcon(resources, icon); + if(staticIcon == null) staticIcon = fetchFallbackIcon(resources); + sStaticIconCache.put(icon, staticIcon); + } + sIconCache.put(key, staticIcon); + return staticIcon; + } + + private static Drawable fetchFallbackIcon(Resources resources) { + Drawable fallbackIcon = sStaticIconCache.get(FALLBACK_ICON_NAME); + if(fallbackIcon == null) { + fallbackIcon = getStaticIcon(resources, FALLBACK_ICON_NAME); + sStaticIconCache.put(FALLBACK_ICON_NAME, fallbackIcon); + } + return fallbackIcon; + } + + private static Drawable getStaticIcon(Resources resources, String icon) { + int staticIconResource = getStaticIconResource(icon); + if(staticIconResource == -1) return null; + return ResourcesCompat.getDrawable(resources, staticIconResource, null); + } + + private static int getStaticIconResource(String icon) { + switch (icon) { + case "default": return R.drawable.ic_pojav_full; + case "fabric": return R.drawable.ic_fabric; + case "quilt": return R.drawable.ic_quilt; + default: return -1; + } + } + + private static Drawable readDataIcon(Resources resources, String icon) { + byte[] iconData = extractIconData(icon); + if(iconData == null) return null; + Bitmap iconBitmap = BitmapFactory.decodeByteArray(iconData, 0, iconData.length); + if(iconBitmap == null) return null; + return new BitmapDrawable(resources, iconBitmap); + } + + private static byte[] extractIconData(String inputString) { + int firstSemicolon = inputString.indexOf(';'); + int commaAfterSemicolon = inputString.indexOf(','); + if(firstSemicolon == -1 || commaAfterSemicolon == -1) return null; + String dataEncoding = inputString.substring(firstSemicolon+1, commaAfterSemicolon); + if(!dataEncoding.equals("base64")) return null; + return Base64.decode(inputString.substring(commaAfterSemicolon+1), 0); + } + + + /*public static void initDefault(Context context) { if(sDefaultIcon != null) return; sDefaultIcon = ResourcesCompat.getDrawable(context.getResources(), R.mipmap.ic_launcher_foreground, null); if(sDefaultIcon != null) sDefaultIcon.setBounds(0, 0, 10, 10); @@ -53,5 +122,5 @@ public class ProfileIconCache { sIconCache.put(key, sDefaultIcon); return sDefaultIcon; - } + }*/ } diff --git a/app_pojavlauncher/src/main/res/drawable/ic_fabric.webp b/app_pojavlauncher/src/main/res/drawable/ic_fabric.webp new file mode 100644 index 0000000000000000000000000000000000000000..1e1bb37e1c71f27fc5651efb0b13b8dc40d53c06 GIT binary patch literal 274 zcmWIYbaUfkWMBw)bqWXzu<-fEz`&s2e=u3VbVrxU$u6ITe3Bgw4ENO^rF=bi=F^*A zrqdwa9<#~Yd!n_hxnQ}_S4xmXhe}7pMTxAvibjHFf ziQPb3ZthQY@^^Op74bA8>kg1_xuH08LeS%55PO=YNSXgTT+jDLMQq8#_N_qq%58A@ N%-BAl73LEv7y%3El4t+` literal 0 HcmV?d00001 diff --git a/app_pojavlauncher/src/main/res/drawable/ic_pojav_full.webp b/app_pojavlauncher/src/main/res/drawable/ic_pojav_full.webp new file mode 100644 index 0000000000000000000000000000000000000000..f67320c7744c1a8bb4486508a19e7036d2639170 GIT binary patch literal 11480 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 literal 0 HcmV?d00001 diff --git a/app_pojavlauncher/src/main/res/drawable/ic_quilt.webp b/app_pojavlauncher/src/main/res/drawable/ic_quilt.webp new file mode 100644 index 0000000000000000000000000000000000000000..0e9abc098287b949ebdb55197c288626cde87bf1 GIT binary patch literal 5614 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 Y#}tPUo|Q$XtWlFB1==?Wck*BRA141FyZ`_I literal 0 HcmV?d00001