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 000000000..1e1bb37e1 Binary files /dev/null and b/app_pojavlauncher/src/main/res/drawable/ic_fabric.webp differ 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 000000000..f67320c77 Binary files /dev/null and b/app_pojavlauncher/src/main/res/drawable/ic_pojav_full.webp differ 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 000000000..0e9abc098 Binary files /dev/null and b/app_pojavlauncher/src/main/res/drawable/ic_quilt.webp differ