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 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)),

View File

@ -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();
}

View File

@ -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);

View File

@ -33,8 +33,7 @@ public class ProfileAdapter extends BaseAdapter {
private List<String> 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))

View File

@ -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:<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 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;
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;
}
}*/
}

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