2022-12-29 10:39:34 +01:00
|
|
|
import DesignSystem
|
2023-01-17 11:36:01 +01:00
|
|
|
import SwiftUI
|
2022-12-04 09:50:25 +01:00
|
|
|
|
2023-09-18 21:03:52 +02:00
|
|
|
@MainActor
|
2022-12-04 09:50:25 +01:00
|
|
|
struct IconSelectorView: View {
|
2022-12-31 14:01:00 +01:00
|
|
|
enum Icon: Int, CaseIterable, Identifiable {
|
2022-12-04 09:50:25 +01:00
|
|
|
var id: String {
|
2022-12-31 14:01:00 +01:00
|
|
|
"\(rawValue)"
|
2022-12-04 09:50:25 +01:00
|
|
|
}
|
2023-01-17 11:36:01 +01:00
|
|
|
|
2022-12-31 14:01:00 +01:00
|
|
|
init(string: String) {
|
2023-12-26 13:24:39 +01:00
|
|
|
if string == "AppIcon" {
|
2022-12-31 14:01:00 +01:00
|
|
|
self = .primary
|
|
|
|
} else {
|
2023-01-21 07:21:51 +01:00
|
|
|
self = .init(rawValue: Int(String(string.replacing("AppIconAlternate", with: "")))!)!
|
2022-12-31 14:01:00 +01:00
|
|
|
}
|
|
|
|
}
|
2023-01-17 11:36:01 +01:00
|
|
|
|
2022-12-31 14:01:00 +01:00
|
|
|
case primary = 0
|
2024-01-02 13:29:21 +01:00
|
|
|
case alt1, alt2, alt3, alt4, alt5, alt6, alt7, alt8, alt9, alt10, alt11, alt12, alt13, alt14, alt15
|
|
|
|
case alt16, alt17, alt18, alt19, alt20, alt21
|
|
|
|
case alt22, alt23, alt24, alt25, alt26
|
|
|
|
case alt27, alt28, alt29
|
|
|
|
case alt30, alt31, alt32, alt33, alt34, alt35, alt36
|
2023-07-18 09:45:44 +02:00
|
|
|
case alt37
|
2024-01-02 13:29:21 +01:00
|
|
|
case alt38
|
|
|
|
case alt39, alt40, alt41, alt42, alt43
|
|
|
|
case alt44, alt45
|
2024-01-21 09:31:50 +01:00
|
|
|
case alt46
|
2023-01-30 07:27:06 +01:00
|
|
|
|
2022-12-31 14:01:00 +01:00
|
|
|
var appIconName: String {
|
2023-12-26 13:24:39 +01:00
|
|
|
return "AppIconAlternate\(rawValue)"
|
2022-12-31 14:01:00 +01:00
|
|
|
}
|
2022-12-04 09:50:25 +01:00
|
|
|
}
|
2023-01-17 11:36:01 +01:00
|
|
|
|
2023-02-09 18:49:03 +01:00
|
|
|
struct IconSelector: Identifiable {
|
|
|
|
var id = UUID()
|
|
|
|
let title: String
|
|
|
|
let icons: [Icon]
|
|
|
|
|
|
|
|
static let items = [
|
2024-01-02 13:29:21 +01:00
|
|
|
IconSelector(title: "settings.app.icon.official".localized, icons: [
|
2024-01-21 09:31:50 +01:00
|
|
|
.primary, .alt46, .alt1, .alt2, .alt3, .alt4,
|
2024-01-02 13:29:21 +01:00
|
|
|
.alt5, .alt6, .alt7, .alt8,
|
|
|
|
.alt9, .alt10, .alt11, .alt12, .alt13, .alt14, .alt15,
|
|
|
|
.alt16, .alt17, .alt18, .alt19, .alt20, .alt21]),
|
|
|
|
IconSelector(title: "\("settings.app.icon.designed-by".localized) Albert Kinng", icons: [.alt22, .alt23, .alt24, .alt25, .alt26]),
|
|
|
|
IconSelector(title: "\("settings.app.icon.designed-by".localized) Dan van Moll", icons: [.alt27, .alt28, .alt29]),
|
|
|
|
IconSelector(title: "\("settings.app.icon.designed-by".localized) Chanhwi Joo (GitHub @te6-in)", icons: [.alt30, .alt31, .alt32, .alt33, .alt34, .alt35, .alt36]),
|
|
|
|
IconSelector(title: "\("settings.app.icon.designed-by".localized) W. Kovács Ágnes (@wildgica)", icons: [.alt37]),
|
|
|
|
IconSelector(title: "\("settings.app.icon.designed-by".localized) Duncan Horne", icons: [.alt38]),
|
|
|
|
IconSelector(title: "\("settings.app.icon.designed-by".localized) BeAware@social.beaware.live", icons: [.alt39, .alt40, .alt41, .alt42, .alt43]),
|
|
|
|
IconSelector(title: "\("settings.app.icon.designed-by".localized) Simone Margio", icons: [.alt44, .alt45]),
|
2023-02-09 18:49:03 +01:00
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2023-09-18 21:03:52 +02:00
|
|
|
@Environment(Theme.self) private var theme
|
2022-12-31 14:01:00 +01:00
|
|
|
@State private var currentIcon = UIApplication.shared.alternateIconName ?? Icon.primary.appIconName
|
2023-01-17 11:36:01 +01:00
|
|
|
|
2022-12-04 09:50:25 +01:00
|
|
|
private let columns = [GridItem(.adaptive(minimum: 125, maximum: 1024))]
|
2023-01-17 11:36:01 +01:00
|
|
|
|
2022-12-04 09:50:25 +01:00
|
|
|
var body: some View {
|
|
|
|
ScrollView {
|
|
|
|
VStack(alignment: .leading) {
|
2023-02-09 18:49:03 +01:00
|
|
|
ForEach(IconSelector.items) { item in
|
|
|
|
Section {
|
|
|
|
makeIconGridView(icons: item.icons)
|
|
|
|
} header: {
|
|
|
|
Text(item.title)
|
|
|
|
.font(.scaledHeadline)
|
|
|
|
}
|
2023-02-09 12:24:24 +01:00
|
|
|
}
|
2022-12-04 09:50:25 +01:00
|
|
|
}
|
|
|
|
.padding(6)
|
2023-01-19 18:14:08 +01:00
|
|
|
.navigationTitle("settings.app.icon.navigation-title")
|
2022-12-04 09:50:25 +01:00
|
|
|
}
|
2023-12-19 09:51:20 +01:00
|
|
|
#if !os(visionOS)
|
2022-12-29 10:39:34 +01:00
|
|
|
.background(theme.primaryBackgroundColor)
|
2023-12-19 09:51:20 +01:00
|
|
|
#endif
|
2022-12-04 09:50:25 +01:00
|
|
|
}
|
2023-01-30 07:27:06 +01:00
|
|
|
|
2023-01-28 08:58:36 +01:00
|
|
|
private func makeIconGridView(icons: [Icon]) -> some View {
|
|
|
|
LazyVGrid(columns: columns, spacing: 6) {
|
|
|
|
ForEach(icons) { icon in
|
|
|
|
Button {
|
|
|
|
currentIcon = icon.appIconName
|
|
|
|
if icon.rawValue == Icon.primary.rawValue {
|
|
|
|
UIApplication.shared.setAlternateIconName(nil)
|
|
|
|
} else {
|
2023-03-26 14:19:34 +02:00
|
|
|
UIApplication.shared.setAlternateIconName(icon.appIconName) { err in
|
|
|
|
guard let err else { return }
|
|
|
|
assertionFailure("\(err.localizedDescription) - Icon name: \(icon.appIconName)")
|
|
|
|
}
|
2023-01-28 08:58:36 +01:00
|
|
|
}
|
|
|
|
} label: {
|
|
|
|
ZStack(alignment: .bottomTrailing) {
|
2023-12-26 13:24:39 +01:00
|
|
|
Image(uiImage: .init(named: icon.appIconName) ?? .init())
|
2023-01-28 08:58:36 +01:00
|
|
|
.resizable()
|
|
|
|
.aspectRatio(contentMode: .fit)
|
|
|
|
.frame(minHeight: 125, maxHeight: 1024)
|
|
|
|
.cornerRadius(6)
|
|
|
|
.shadow(radius: 3)
|
|
|
|
if icon.appIconName == currentIcon {
|
|
|
|
Image(systemName: "checkmark.seal.fill")
|
|
|
|
.padding(4)
|
|
|
|
.tint(.green)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-19 09:51:20 +01:00
|
|
|
.buttonStyle(.plain)
|
2023-01-28 08:58:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-12-04 09:50:25 +01:00
|
|
|
}
|
2023-02-14 07:01:34 +01:00
|
|
|
|
|
|
|
extension String {
|
2023-02-18 07:26:48 +01:00
|
|
|
var localized: String {
|
2023-09-16 14:15:03 +02:00
|
|
|
NSLocalizedString(self, comment: "")
|
2023-02-18 07:26:48 +01:00
|
|
|
}
|
2023-02-14 07:01:34 +01:00
|
|
|
}
|