mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-20 12:13:26 +01:00
Fix changing SideStore app icon not displaying My Apps
This commit is contained in:
@@ -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 isSideStore {
|
||||||
|
return AnyView(
|
||||||
|
Image(uiImage: UIImage(named: sideStoreIconData.selectedIconName! + "-image") ?? UIImage())
|
||||||
|
.resizable()
|
||||||
|
.renderingMode(.original)
|
||||||
|
)
|
||||||
|
}
|
||||||
if let iconUrl {
|
if let iconUrl {
|
||||||
|
return AnyView(
|
||||||
AsyncImage(url: iconUrl) { image in
|
AsyncImage(url: iconUrl) { image in
|
||||||
image
|
image
|
||||||
.resizable()
|
.resizable()
|
||||||
} placeholder: {
|
} placeholder: {
|
||||||
Color(UIColor.secondarySystemBackground)
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user