// // CustomizeView.swift // Feels (iOS) // // Created by Trey Tartt on 2/19/22. // import SwiftUI struct CustomizeView: View { @AppStorage(UserDefaultsStore.Keys.theme.rawValue, store: GroupUserDefaults.groupDefaults) private var theme: Theme = .system @AppStorage(UserDefaultsStore.Keys.moodImages.rawValue, store: GroupUserDefaults.groupDefaults) private var imagePack: MoodImages = .FontAwesome @AppStorage(UserDefaultsStore.Keys.moodTint.rawValue, store: GroupUserDefaults.groupDefaults) private var moodTint: MoodTints = .Default @AppStorage(UserDefaultsStore.Keys.personalityPack.rawValue, store: GroupUserDefaults.groupDefaults) private var personalityPack: PersonalityPack = .Default @AppStorage(UserDefaultsStore.Keys.customMoodTintUpdateNumber.rawValue, store: GroupUserDefaults.groupDefaults) private var customMoodTintUpdateNumber: Int = 0 @StateObject private var customMoodTint = UserDefaultsStore.getCustomMoodTint() class StupidAssCustomWidgetObservableObject: ObservableObject { @Published var fuckingWrapped: CustomWidgetModel? = nil @Published var showFuckingSheet = false } @StateObject private var selectedWidget = StupidAssCustomWidgetObservableObject() let iconSets: [(String,String)] = [ ("AppIconGoodImage", "AppIconGood"), ("AppIconAverageImage", "AppIconAverage"), ("AppIconBadImage", "AppIconBad"), ("AppIconBlueGreenImage", "AppIconBlueGreen"), ("AppIconNeonGreenImage", "AppIconNeonGreen"), ("AppIconPinkImage", "AppIconPink"), ("AppIconPurpleImage", "AppIconPurple") ] var body: some View { ScrollView { VStack { createCustomWidget changeIcon themePicker pickMoodImagePack pickMoodTintPack pickPeronsalityPack } } .padding() .sheet(isPresented: $selectedWidget.showFuckingSheet) { if let fuckingWrapped = selectedWidget.fuckingWrapped { CreateWidgetView(customWidget: fuckingWrapped) } } .background( theme.currentTheme.bg .edgesIgnoringSafeArea(.all) ) } private var changeIcon: some View { ZStack { theme.currentTheme.secondaryBGColor VStack { ScrollView(.horizontal) { HStack { Button(action: { UIApplication.shared.setAlternateIconName(nil) }, label: { Image("AppIconImage", bundle: .main) .resizable() .frame(width: 50, height:50) .cornerRadius(10) }) ForEach(iconSets, id: \.self.0){ iconSet in Button(action: { UIApplication.shared.setAlternateIconName(iconSet.1) { (error) in // FIXME: Handle error } }, label: { Image(iconSet.0, bundle: .main) .resizable() .frame(width: 50, height:50) .cornerRadius(10) }) } } .padding() } .background(RoundedRectangle(cornerRadius: 10).fill().foregroundColor(theme.currentTheme.bgColor)) .padding() .cornerRadius(10) } } .fixedSize(horizontal: false, vertical: true) .cornerRadius(10, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight]) } private var themePicker: some View { ZStack { theme.currentTheme.secondaryBGColor VStack { HStack { Spacer() ForEach(Theme.allCases, id:\.rawValue) { aTheme in Button(action: { theme = aTheme }, label: { VStack { aTheme.currentTheme.preview .overlay( Circle() .stroke(Color(UIColor.systemGray), style: StrokeStyle(lineWidth: 2)) ) Text(aTheme.title) } }) .contentShape(Rectangle()) .background( RoundedRectangle(cornerRadius: 10, style: .continuous) .fill(theme == aTheme ? theme.currentTheme.bgColor : .clear) .padding(-5) ) Spacer() } } .padding(.top) } .padding() } .fixedSize(horizontal: false, vertical: true) .cornerRadius(10, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight]) } private var createCustomWidget: some View { ZStack { theme.currentTheme.secondaryBGColor VStack { ScrollView(.horizontal) { HStack { ForEach(UserDefaultsStore.getCustomWidgets(), id: \.uuid) { widget in CustomWidgetView(customWidgetModel: widget) .frame(width: 50, height: 50) .cornerRadius(10) .onTapGesture { selectedWidget.fuckingWrapped = widget.copy() as? CustomWidgetModel selectedWidget.showFuckingSheet = true } } RoundedRectangle(cornerRadius: 10).fill().foregroundColor(theme.currentTheme.secondaryBGColor) .frame(width: 50, height: 50) .overlay( Image(systemName: "plus") ) .onTapGesture { selectedWidget.fuckingWrapped = CustomWidgetModel.randomWidget selectedWidget.showFuckingSheet = true } } .padding() } .background(RoundedRectangle(cornerRadius: 10).fill().foregroundColor(theme.currentTheme.bgColor)) .padding() .cornerRadius(10) Text("[How to add widget](https://support.apple.com/guide/iphone/add-widgets-iphb8f1bf206/ios)") .padding(.bottom) } } .fixedSize(horizontal: false, vertical: true) .cornerRadius(10, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight]) } private var pickMoodImagePack: some View { ZStack { theme.currentTheme.secondaryBGColor VStack { ForEach(MoodImages.allCases, id: \.rawValue) { images in ZStack { VStack { HStack { ForEach(Mood.allValues, id: \.self) { mood in images.icon(forMood: mood) .resizable() .aspectRatio(contentMode: .fit) .frame(width: 35, height: 35) .foregroundColor( moodTint.color(forMood: mood) ) } .frame(minWidth: 0, maxWidth: .infinity) } .contentShape(Rectangle()) .background( RoundedRectangle(cornerRadius: 10, style: .continuous) .fill(imagePack == images ? theme.currentTheme.bgColor : .clear) .padding([.top, .bottom], -3) ) .onTapGesture { let impactMed = UIImpactFeedbackGenerator(style: .heavy) impactMed.impactOccurred() imagePack = images } if images.rawValue != (MoodImages.allCases.sorted(by: { $0.rawValue > $1.rawValue }).first?.rawValue) ?? 0 { Divider() } } } } } .padding() } .fixedSize(horizontal: false, vertical: true) .cornerRadius(10, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight]) } private var pickMoodTintPack: some View { ZStack { theme.currentTheme.secondaryBGColor VStack { ForEach(MoodTints.defaultOptions, id: \.rawValue) { tint in HStack { ForEach(Mood.allValues, id: \.self) { mood in Circle() .frame(width: 35, height: 35) .foregroundColor( tint.color(forMood: mood) ) } .frame(minWidth: 0, maxWidth: .infinity) } .contentShape(Rectangle()) .background( RoundedRectangle(cornerRadius: 10, style: .continuous) .fill(moodTint == tint ? theme.currentTheme.bgColor : .clear) .padding([.top, .bottom], -3) ) .onTapGesture { let impactMed = UIImpactFeedbackGenerator(style: .heavy) impactMed.impactOccurred() moodTint = tint } Divider() } ZStack { Color.clear Rectangle() .frame(height: 35) .frame(minWidth: 0, maxWidth: .infinity) .foregroundColor(.clear) .contentShape(Rectangle()) .onTapGesture { moodTint = .Custom let impactMed = UIImpactFeedbackGenerator(style: .heavy) impactMed.impactOccurred() } HStack { ColorPicker("", selection: $customMoodTint.colorOne) .onChange(of: customMoodTint.colorOne, perform: { _ in saveCustomMoodTint() }) .labelsHidden() .frame(minWidth: 0, maxWidth: .infinity) ColorPicker("", selection: $customMoodTint.colorTwo) .labelsHidden() .frame(minWidth: 0, maxWidth: .infinity) .onChange(of: customMoodTint.colorTwo, perform: { _ in saveCustomMoodTint() }) ColorPicker("", selection: $customMoodTint.colorThree) .labelsHidden() .frame(minWidth: 0, maxWidth: .infinity) .onChange(of: customMoodTint.colorThree, perform: { _ in saveCustomMoodTint() }) ColorPicker("", selection: $customMoodTint.colorFour) .labelsHidden() .frame(minWidth: 0, maxWidth: .infinity) .onChange(of: customMoodTint.colorFour, perform: { _ in saveCustomMoodTint() }) ColorPicker("", selection: $customMoodTint.colorFive) .labelsHidden() .frame(minWidth: 0, maxWidth: .infinity) .onChange(of: customMoodTint.colorFive, perform: { _ in saveCustomMoodTint() }) } .background( Color.clear ) } .background( RoundedRectangle(cornerRadius: 10, style: .continuous) .fill(moodTint == .Custom ? theme.currentTheme.bgColor : .clear) .padding([.top, .bottom], -3) ) } .padding() } .fixedSize(horizontal: false, vertical: true) .cornerRadius(10, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight]) } private func saveCustomMoodTint() { UserDefaultsStore.saveCustomMoodTint(customTint: customMoodTint) moodTint = .Custom customMoodTintUpdateNumber += 1 } private var pickPeronsalityPack: some View { ZStack { theme.currentTheme.secondaryBGColor VStack { ForEach(PersonalityPack.allCases, id: \.self) { aPack in VStack(spacing: 10) { Text(String(aPack.title())) .font(.body) .foregroundColor(theme.currentTheme.labelColor) Text(aPack.randomPushNotificationStrings().title) .font(.body) .foregroundColor(Color(UIColor.systemGray)) Text(aPack.randomPushNotificationStrings().body) .font(.body) .foregroundColor(Color(UIColor.systemGray)) } .frame(minWidth: 0, maxWidth: .infinity) .padding() .contentShape(Rectangle()) .background( RoundedRectangle(cornerRadius: 10, style: .continuous) .fill(personalityPack == aPack ? theme.currentTheme.bgColor : .clear) .padding(5) ) .onTapGesture { let impactMed = UIImpactFeedbackGenerator(style: .heavy) impactMed.impactOccurred() personalityPack = aPack LocalNotification.rescheduleNotifiations() } if aPack.rawValue != (PersonalityPack.allCases.sorted(by: { $0.rawValue > $1.rawValue }).first?.rawValue) ?? 0 { Divider() } } } } .fixedSize(horizontal: false, vertical: true) .cornerRadius(10, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight]) } }