Feat[profile]: static icons & cache refactor

This commit is contained in:
artdeell 2023-09-03 18:56:34 +03:00
parent c599ee9f6a
commit 209bd9d22a
8 changed files with 86 additions and 16 deletions

View File

@ -56,7 +56,7 @@ public class mcVersionSpinner extends ExtendedTextView {
private ListView mListView = null; private ListView mListView = null;
private PopupWindow mPopupWindow = null; private PopupWindow mPopupWindow = null;
private Object mPopupAnimation; 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, new ProfileAdapterExtra(VERSION_SPINNER_PROFILE_CREATE,
R.string.create_profile, R.string.create_profile,
ResourcesCompat.getDrawable(getResources(), R.drawable.ic_add, null)), ResourcesCompat.getDrawable(getResources(), R.drawable.ic_add, null)),

View File

@ -61,6 +61,7 @@ public class FabriclikeDownloadTask implements Runnable, Tools.DownloaderFeedbac
MinecraftProfile fabricProfile = new MinecraftProfile(); MinecraftProfile fabricProfile = new MinecraftProfile();
fabricProfile.lastVersionId = versionId; fabricProfile.lastVersionId = versionId;
fabricProfile.name = mUtils.getName(); fabricProfile.name = mUtils.getName();
fabricProfile.icon = mUtils.getIconName();
LauncherProfiles.insertMinecraftProfile(fabricProfile); LauncherProfiles.insertMinecraftProfile(fabricProfile);
LauncherProfiles.write(); LauncherProfiles.write();
} }

View File

@ -15,8 +15,8 @@ import java.net.URLEncoder;
public class FabriclikeUtils { public class FabriclikeUtils {
public static final FabriclikeUtils FABRIC_UTILS = new FabriclikeUtils("https://meta.fabricmc.net/v2", "fabric", "Fabric"); 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"); 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 LOADER_METADATA_URL = "%s/versions/loader/%s";
private static final String GAME_METADATA_URL = "%s/versions/game"; private static final String GAME_METADATA_URL = "%s/versions/game";
@ -26,10 +26,12 @@ public class FabriclikeUtils {
private final String mApiUrl; private final String mApiUrl;
private final String mCachePrefix; private final String mCachePrefix;
private final String mName; 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.mApiUrl = mApiUrl;
this.mCachePrefix = cachePrefix; this.mCachePrefix = cachePrefix;
this.mIconName = iconName;
this.mName = mName; this.mName = mName;
} }
@ -72,6 +74,9 @@ public class FabriclikeUtils {
public String getName() { public String getName() {
return mName; return mName;
} }
public String getIconName() {
return mIconName;
}
private static FabricVersion[] deserializeLoaderVersions(String input) throws JSONException { private static FabricVersion[] deserializeLoaderVersions(String input) throws JSONException {
JSONArray jsonArray = new JSONArray(input); JSONArray jsonArray = new JSONArray(input);

View File

@ -33,8 +33,7 @@ public class ProfileAdapter extends BaseAdapter {
private List<String> mProfileList; private List<String> mProfileList;
private ProfileAdapterExtra[] mExtraEntires; private ProfileAdapterExtra[] mExtraEntires;
public ProfileAdapter(Context context, ProfileAdapterExtra[] extraEntries) { public ProfileAdapter(ProfileAdapterExtra[] extraEntries) {
ProfileIconCache.initDefault(context);
reloadProfiles(extraEntries); reloadProfiles(extraEntries);
} }
/* /*
@ -96,11 +95,7 @@ public class ProfileAdapter extends BaseAdapter {
MinecraftProfile minecraftProfile = mProfiles.get(nm); MinecraftProfile minecraftProfile = mProfiles.get(nm);
if(minecraftProfile == null) minecraftProfile = dummy; if(minecraftProfile == null) minecraftProfile = dummy;
Drawable cachedIcon = ProfileIconCache.getCachedIcon(nm); Drawable cachedIcon = ProfileIconCache.fetchIcon(v.getResources(), nm, minecraftProfile.icon);
if(cachedIcon == null) {
cachedIcon = ProfileIconCache.tryResolveIcon(v.getResources(), nm, minecraftProfile.icon);
}
extendedTextView.setCompoundDrawablesRelative(cachedIcon, null, extendedTextView.getCompoundsDrawables()[2], null); extendedTextView.setCompoundDrawablesRelative(cachedIcon, null, extendedTextView.getCompoundsDrawables()[2], null);
if(Tools.isValidString(minecraftProfile.name)) if(Tools.isValidString(minecraftProfile.name))

View File

@ -1,7 +1,7 @@
package net.kdt.pojavlaunch.profiles; package net.kdt.pojavlaunch.profiles;
import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@ -16,12 +16,81 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class ProfileIconCache { public class ProfileIconCache {
private static final String BASE64_PNG_HEADER = "data:image/png;base64,"; // Data header format: data:<mime>;<encoding>,<data>
private static final String DATA_HEADER = "data:";
private static final String FALLBACK_ICON_NAME = "default";
private static final Map<String, Drawable> sIconCache = new HashMap<>(); private static final Map<String, Drawable> sIconCache = new HashMap<>();
private static Drawable sDefaultIcon; private static final Map<String, Drawable> 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; if(sDefaultIcon != null) return;
sDefaultIcon = ResourcesCompat.getDrawable(context.getResources(), R.mipmap.ic_launcher_foreground, null); sDefaultIcon = ResourcesCompat.getDrawable(context.getResources(), R.mipmap.ic_launcher_foreground, null);
if(sDefaultIcon != null) sDefaultIcon.setBounds(0, 0, 10, 10); if(sDefaultIcon != null) sDefaultIcon.setBounds(0, 0, 10, 10);
@ -53,5 +122,5 @@ public class ProfileIconCache {
sIconCache.put(key, sDefaultIcon); sIconCache.put(key, sDefaultIcon);
return sDefaultIcon; return sDefaultIcon;
} }*/
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB