Fix changing SideStore app icon not displaying My Apps

This commit is contained in:
naturecodevoid
2023-02-19 09:16:07 -08:00
parent 839699ee03
commit d9a4b07095
5 changed files with 68 additions and 34 deletions

View File

@@ -10,23 +10,42 @@ import SwiftUI
import AsyncImage import AsyncImage
struct AppIconView: View { struct AppIconView: View {
@ObservedObject private var iO = Inject.observer
@ObservedObject private var sideStoreIconData = AppIconsData.shared
let iconUrl: URL? let iconUrl: URL?
var isSideStore = false
var size: CGFloat = 64 var size: CGFloat = 64
var cornerRadius: CGFloat { var cornerRadius: CGFloat {
size * 0.234 size * 0.234
} }
var body: some View { var image: some View {
if let iconUrl { if isSideStore {
AsyncImage(url: iconUrl) { image in return AnyView(
image Image(uiImage: UIImage(named: sideStoreIconData.selectedIconName! + "-image") ?? UIImage())
.resizable() .resizable()
} placeholder: { .renderingMode(.original)
Color(UIColor.secondarySystemBackground) )
} }
if let iconUrl {
return AnyView(
AsyncImage(url: iconUrl) { image in
image
.resizable()
} placeholder: {
Color(UIColor.secondarySystemBackground)
}
)
}
return AnyView(Color(UIColor.secondarySystemBackground))
}
var body: some View {
image
.frame(width: size, height: size) .frame(width: size, height: size)
.clipShape(RoundedRectangle(cornerRadius: cornerRadius, style: .continuous)) .clipShape(RoundedRectangle(cornerRadius: cornerRadius, style: .continuous))
} .enableInjection()
} }
} }

View File

@@ -20,7 +20,7 @@ struct AppRowView: View {
var body: some View { var body: some View {
HStack(alignment: .center, spacing: 12) { HStack(alignment: .center, spacing: 12) {
AppIconView(iconUrl: storeApp?.iconURL) AppIconView(iconUrl: storeApp?.iconURL, isSideStore: storeApp?.bundleIdentifier == Bundle.Info.appbundleIdentifier)
VStack(alignment: .leading, spacing: 2) { VStack(alignment: .leading, spacing: 2) {
Text(app.name) Text(app.name)

View File

@@ -58,7 +58,7 @@ struct AppDetailView: View {
ToolbarItemGroup(placement: .principal) { ToolbarItemGroup(placement: .principal) {
HStack { HStack {
Spacer() Spacer()
AppIconView(iconUrl: storeApp.iconURL, size: 24) AppIconView(iconUrl: storeApp.iconURL, isSideStore: storeApp.bundleIdentifier == Bundle.Info.appbundleIdentifier, size: 24)
Text(storeApp.name) Text(storeApp.name)
.bold() .bold()
Spacer() Spacer()
@@ -74,7 +74,7 @@ struct AppDetailView: View {
var headerView: some View { var headerView: some View {
ZStack(alignment: .center) { ZStack(alignment: .center) {
GeometryReader { proxy in GeometryReader { proxy in
AppIconView(iconUrl: storeApp.iconURL, size: proxy.frame(in: .global).width) AppIconView(iconUrl: storeApp.iconURL, isSideStore: storeApp.bundleIdentifier == Bundle.Info.appbundleIdentifier, size: proxy.frame(in: .global).width)
.blur(radius: headerBlurRadius) .blur(radius: headerBlurRadius)
.offset(y: min(0, scrollOffset)) .offset(y: min(0, scrollOffset))
} }

View File

@@ -9,7 +9,7 @@
import SwiftUI import SwiftUI
import SFSafeSymbols import SFSafeSymbols
private struct Icon: Identifiable { struct Icon: Identifiable {
var id: String { assetName } var id: String { assetName }
var displayName: String var displayName: String
let assetName: String let assetName: String
@@ -21,22 +21,18 @@ private struct SpecialIcon {
let forceIndex: Int? let forceIndex: Int?
} }
struct AppIconsView: View { class AppIconsData: ObservableObject {
private let specialIcons = [ static let shared: AppIconsData = AppIconsData()
private static let specialIcons = [
SpecialIcon(assetName: "Neon", suffix: "(Stable)", forceIndex: 0), SpecialIcon(assetName: "Neon", suffix: "(Stable)", forceIndex: 0),
SpecialIcon(assetName: "Starburst", suffix: "(Beta)", forceIndex: 1), SpecialIcon(assetName: "Starburst", suffix: "(Beta)", forceIndex: 1),
SpecialIcon(assetName: "Steel", suffix: "(Nightly)", forceIndex: 2), SpecialIcon(assetName: "Steel", suffix: "(Nightly)", forceIndex: 2),
] ]
private let artists = [
"Chris (LitRitt)": ["Neon", "Starburst", "Steel", "Storm"],
"naturecodevoid": ["Honeydew", "Midnight", "Sky"]
]
private var icons: [Icon] = [] @Published var icons: [Icon] = []
private var primaryIcon: Icon @Published var primaryIcon: Icon?
@Published var selectedIconName: String?
@State private var selectedIcon: String? = "" // this is just so the list row background changes when selecting a value, I couldn't get it to keep the selected icon name (for some reason it was always "", even when I set it to the selected icon asset name)
@State private var selectedIconAssetName: String // FIXME: use selectedIcon instead
init() { init() {
let bundleIcons = Bundle.main.object(forInfoDictionaryKey: "CFBundleIcons") as! [String: Any] let bundleIcons = Bundle.main.object(forInfoDictionaryKey: "CFBundleIcons") as! [String: Any]
@@ -44,7 +40,7 @@ struct AppIconsView: View {
let primaryIconData = bundleIcons["CFBundlePrimaryIcon"] as! [String: Any] let primaryIconData = bundleIcons["CFBundlePrimaryIcon"] as! [String: Any]
let primaryIconName = primaryIconData["CFBundleIconName"] as! String let primaryIconName = primaryIconData["CFBundleIconName"] as! String
primaryIcon = Icon(displayName: primaryIconName, assetName: primaryIconName) primaryIcon = Icon(displayName: primaryIconName, assetName: primaryIconName)
icons.append(primaryIcon) icons.append(primaryIcon!)
for (key, _) in bundleIcons["CFBundleAlternateIcons"] as! [String: Any] { for (key, _) in bundleIcons["CFBundleAlternateIcons"] as! [String: Any] {
icons.append(Icon(displayName: key, assetName: key)) icons.append(Icon(displayName: key, assetName: key))
@@ -53,7 +49,7 @@ struct AppIconsView: View {
// sort alphabetically // sort alphabetically
icons.sort { $0.assetName < $1.assetName } icons.sort { $0.assetName < $1.assetName }
for specialIcon in specialIcons { for specialIcon in AppIconsData.specialIcons {
guard let icon = icons.enumerated().first(where: { $0.element.assetName == specialIcon.assetName }) else { continue } guard let icon = icons.enumerated().first(where: { $0.element.assetName == specialIcon.assetName }) else { continue }
if let suffix = specialIcon.suffix { if let suffix = specialIcon.suffix {
@@ -67,18 +63,36 @@ struct AppIconsView: View {
} }
if let alternateIconName = UIApplication.shared.alternateIconName { if let alternateIconName = UIApplication.shared.alternateIconName {
selectedIconAssetName = icons.first { $0.assetName == alternateIconName }?.assetName ?? primaryIcon.assetName selectedIconName = icons.first { $0.assetName == alternateIconName }?.assetName ?? primaryIcon!.assetName
} else { } else {
selectedIconAssetName = primaryIcon.assetName selectedIconName = primaryIcon!.assetName
} }
} }
}
struct AppIconsView: View {
@ObservedObject private var iO = Inject.observer
@ObservedObject private var data = AppIconsData.shared
private let artists = [
"Chris (LitRitt)": ["Neon", "Starburst", "Steel", "Storm"],
"naturecodevoid": ["Honeydew", "Midnight", "Sky"],
"Swifticul": ["Vista"],
]
@State private var selectedIcon: String? = "" // this is just so the list row background changes when selecting a value, I couldn't get it to keep the selected icon name (for some reason it was always "", even when I set it to the selected icon asset name)
private let size: CGFloat = 72
private var cornerRadius: CGFloat {
size * 0.234
}
var body: some View { var body: some View {
List(icons, selection: $selectedIcon) { icon in List(data.icons, selection: $selectedIcon) { icon in
SwiftUI.Button(action: { SwiftUI.Button(action: {
selectedIconAssetName = icon.assetName data.selectedIconName = icon.assetName
// Pass nil for primary icon // Pass nil for primary icon
UIApplication.shared.setAlternateIconName(icon.assetName == primaryIcon.assetName ? nil : icon.assetName, completionHandler: { error in UIApplication.shared.setAlternateIconName(icon.assetName == data.primaryIcon!.assetName ? nil : icon.assetName, completionHandler: { error in
if let error = error { if let error = error {
print("error when setting alternate app icon to \(icon.assetName): \(error.localizedDescription)") print("error when setting alternate app icon to \(icon.assetName): \(error.localizedDescription)")
} else { } else {
@@ -91,8 +105,8 @@ struct AppIconsView: View {
Image(uiImage: UIImage(named: icon.assetName + "-image") ?? UIImage()) Image(uiImage: UIImage(named: icon.assetName + "-image") ?? UIImage())
.resizable() .resizable()
.renderingMode(.original) .renderingMode(.original)
.cornerRadius(12.6) // https://stackoverflow.com/a/10239376 .cornerRadius(cornerRadius)
.frame(width: 72, height: 72) .frame(width: size, height: size)
VStack(alignment: .leading) { VStack(alignment: .leading) {
Text(icon.displayName) Text(icon.displayName)
if let artist = artists.first(where: { $0.value.contains(icon.assetName) }) { if let artist = artists.first(where: { $0.value.contains(icon.assetName) }) {
@@ -101,7 +115,7 @@ struct AppIconsView: View {
} }
} }
Spacer() Spacer()
if selectedIconAssetName == icon.assetName { if data.selectedIconName == icon.assetName {
Image(systemSymbol: .checkmark) Image(systemSymbol: .checkmark)
.foregroundColor(Color.blue) .foregroundColor(Color.blue)
} }
@@ -109,6 +123,7 @@ struct AppIconsView: View {
}.foregroundColor(.primary) }.foregroundColor(.primary)
} }
.navigationTitle(L10n.AppIconsView.title) .navigationTitle(L10n.AppIconsView.title)
.enableInjection()
} }
} }

View File

@@ -37,7 +37,7 @@ struct ErrorLogView: View {
HStack(alignment: .top) { HStack(alignment: .top) {
Group { Group {
if let storeApp = error.storeApp { if let storeApp = error.storeApp {
AppIconView(iconUrl: storeApp.iconURL, size: 50) AppIconView(iconUrl: storeApp.iconURL, isSideStore: storeApp.bundleIdentifier == Bundle.Info.appbundleIdentifier, size: 50)
} else { } else {
ZStack { ZStack {
RoundedRectangle(cornerRadius: 50*0.234, style: .continuous) RoundedRectangle(cornerRadius: 50*0.234, style: .continuous)