Mercurial > public > geoquiz
changeset 14:136928bae534
add user profile
author | Dennis C. M. <dennis@denniscm.com> |
---|---|
date | Wed, 19 Oct 2022 07:56:33 +0200 |
parents | bdfff35dd43c |
children | f1967f8cc67b |
files | GeoQuiz.xcodeproj/project.pbxproj GeoQuiz/Assets.xcassets/flag.imageset/Contents.json GeoQuiz/Assets.xcassets/flag.imageset/flag.png GeoQuiz/Components/ProfileEditModalView.swift GeoQuiz/Components/UserImageHelper.swift GeoQuiz/ContentView.swift GeoQuiz/Logic/CityGameClass.swift GeoQuiz/Logic/CountryGameClass.swift GeoQuiz/Logic/GameModeEnum.swift GeoQuiz/Logic/GameProtocol+Extension.swift GeoQuiz/Logic/GameTypeEnum.swift GeoQuiz/Logic/HapticsClass.swift GeoQuiz/Logic/StoreKitRCClass.swift GeoQuiz/Logic/UserClass.swift GeoQuiz/Logic/UserDataModel.swift GeoQuiz/Logic/UserSettingsModel.swift GeoQuiz/ProfileModalView.swift GeoQuiz/SettingsModalView.swift |
diffstat | 18 files changed, 358 insertions(+), 167 deletions(-) [+] |
line wrap: on
line diff
--- a/GeoQuiz.xcodeproj/project.pbxproj Wed Oct 12 11:47:29 2022 +0200 +++ b/GeoQuiz.xcodeproj/project.pbxproj Wed Oct 19 07:56:33 2022 +0200 @@ -34,7 +34,6 @@ 956273EA28CB2E98008DC094 /* FlagImageHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 956273E928CB2E98008DC094 /* FlagImageHelper.swift */; }; 9590359528E098FF00B24560 /* ProfileModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9590359428E098FF00B24560 /* ProfileModalView.swift */; }; 95919DB628F076BF00F21F8F /* UserClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95919DB528F076BF00F21F8F /* UserClass.swift */; }; - 95919DB828F079D100F21F8F /* UserSettingsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95919DB728F079D100F21F8F /* UserSettingsModel.swift */; }; 95919DBC28F08D0600F21F8F /* LinkHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95919DBB28F08D0600F21F8F /* LinkHelper.swift */; }; 95AE8D5728C8750E0067F219 /* LoadFunc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AE8D5628C8750E0067F219 /* LoadFunc.swift */; }; 95AF322A28DF293900023ACC /* GuessTheCountryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AF322928DF293900023ACC /* GuessTheCountryView.swift */; }; @@ -42,8 +41,12 @@ 95C430F928D0A8E500480D23 /* GradientExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C430F828D0A8E500480D23 /* GradientExtension.swift */; }; 95C4315628C64A8C00212131 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C4315528C64A8C00212131 /* ContentView.swift */; }; 95C4315928C6500000212131 /* GameButtonHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C4315828C6500000212131 /* GameButtonHelper.swift */; }; - 95CA294028F5769700CE0B7A /* GameModeEnum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95CA293F28F5769700CE0B7A /* GameModeEnum.swift */; }; + 95C6456C28FE87E4000CD570 /* UserDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C6456B28FE87E4000CD570 /* UserDataModel.swift */; }; + 95C6456E28FE8C04000CD570 /* UserImageHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C6456D28FE8C04000CD570 /* UserImageHelper.swift */; }; + 95C6457228FFC4DC000CD570 /* ProfileEditModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C6457128FFC4DC000CD570 /* ProfileEditModalView.swift */; }; + 95C6457428FFC8E0000CD570 /* DataController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C6457328FFC8E0000CD570 /* DataController.swift */; }; 95CA295028F6BB4500CE0B7A /* ActivityAlertHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95CA294F28F6BB4500CE0B7A /* ActivityAlertHelper.swift */; }; + 95CC404928F98503001F74E1 /* GameTypeEnum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95CC404828F98503001F74E1 /* GameTypeEnum.swift */; }; 95FA409A28D9876B00129B60 /* GuessTheFlagView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95FA409928D9876B00129B60 /* GuessTheFlagView.swift */; }; 95FA409C28D9881100129B60 /* CountryGameClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95FA409B28D9881100129B60 /* CountryGameClass.swift */; }; /* End PBXBuildFile section */ @@ -76,7 +79,6 @@ 956273E928CB2E98008DC094 /* FlagImageHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlagImageHelper.swift; sourceTree = "<group>"; }; 9590359428E098FF00B24560 /* ProfileModalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileModalView.swift; sourceTree = "<group>"; }; 95919DB528F076BF00F21F8F /* UserClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserClass.swift; sourceTree = "<group>"; }; - 95919DB728F079D100F21F8F /* UserSettingsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettingsModel.swift; sourceTree = "<group>"; }; 95919DBB28F08D0600F21F8F /* LinkHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkHelper.swift; sourceTree = "<group>"; }; 95AE8D5628C8750E0067F219 /* LoadFunc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadFunc.swift; sourceTree = "<group>"; }; 95AF322928DF293900023ACC /* GuessTheCountryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuessTheCountryView.swift; sourceTree = "<group>"; }; @@ -84,8 +86,12 @@ 95C430F828D0A8E500480D23 /* GradientExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientExtension.swift; sourceTree = "<group>"; }; 95C4315528C64A8C00212131 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; }; 95C4315828C6500000212131 /* GameButtonHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameButtonHelper.swift; sourceTree = "<group>"; }; - 95CA293F28F5769700CE0B7A /* GameModeEnum.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameModeEnum.swift; sourceTree = "<group>"; }; + 95C6456B28FE87E4000CD570 /* UserDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDataModel.swift; sourceTree = "<group>"; }; + 95C6456D28FE8C04000CD570 /* UserImageHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserImageHelper.swift; sourceTree = "<group>"; }; + 95C6457128FFC4DC000CD570 /* ProfileEditModalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileEditModalView.swift; sourceTree = "<group>"; }; + 95C6457328FFC8E0000CD570 /* DataController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataController.swift; sourceTree = "<group>"; }; 95CA294F28F6BB4500CE0B7A /* ActivityAlertHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityAlertHelper.swift; sourceTree = "<group>"; }; + 95CC404828F98503001F74E1 /* GameTypeEnum.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameTypeEnum.swift; sourceTree = "<group>"; }; 95E6188428DDDB5C003359ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; 95FA409928D9876B00129B60 /* GuessTheFlagView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuessTheFlagView.swift; sourceTree = "<group>"; }; 95FA409B28D9881100129B60 /* CountryGameClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountryGameClass.swift; sourceTree = "<group>"; }; @@ -109,15 +115,16 @@ children = ( 951AFAEC28E5657500A4A4BD /* CityModel.swift */, 951AFAEE28E565FE00A4A4BD /* CountryModel.swift */, - 95919DB728F079D100F21F8F /* UserSettingsModel.swift */, + 95C6456B28FE87E4000CD570 /* UserDataModel.swift */, 955A658228D733E400CEEC6D /* GameProtocol+Extension.swift */, 955A65A828D7815E00CEEC6D /* HapticsClass.swift */, 95FA409B28D9881100129B60 /* CountryGameClass.swift */, 951AFAF028E5735400A4A4BD /* CityGameClass.swift */, 95919DB528F076BF00F21F8F /* UserClass.swift */, 95197EFC28F339AE00FE67E9 /* StoreKitRCClass.swift */, + 95CC404828F98503001F74E1 /* GameTypeEnum.swift */, 95AE8D5628C8750E0067F219 /* LoadFunc.swift */, - 95CA293F28F5769700CE0B7A /* GameModeEnum.swift */, + 95C6457328FFC8E0000CD570 /* DataController.swift */, ); path = Logic; sourceTree = "<group>"; @@ -198,10 +205,12 @@ 95BC392C28EC42570049AB49 /* CityMapHelper.swift */, 95919DBB28F08D0600F21F8F /* LinkHelper.swift */, 95CA294F28F6BB4500CE0B7A /* ActivityAlertHelper.swift */, + 95C6456D28FE8C04000CD570 /* UserImageHelper.swift */, 952E41E828DC521200198643 /* GameAlertsModifier.swift */, 95C430F828D0A8E500480D23 /* GradientExtension.swift */, 951D197228D485E000671FAD /* ColorExtension.swift */, 955950BA28F15FF2001BDEE8 /* FormatterExtension.swift */, + 95C6457128FFC4DC000CD570 /* ProfileEditModalView.swift */, ); path = Components; sourceTree = "<group>"; @@ -290,10 +299,12 @@ 95BC392D28EC42570049AB49 /* CityMapHelper.swift in Sources */, 952E41E928DC521200198643 /* GameAlertsModifier.swift in Sources */, 95197EFD28F339AE00FE67E9 /* StoreKitRCClass.swift in Sources */, - 95919DB828F079D100F21F8F /* UserSettingsModel.swift in Sources */, 9509A8E228E5A3D700CFCDBA /* GuessThePopulationView.swift in Sources */, 955A658328D733E400CEEC6D /* GameProtocol+Extension.swift in Sources */, + 95CC404928F98503001F74E1 /* GameTypeEnum.swift in Sources */, + 95C6457428FFC8E0000CD570 /* DataController.swift in Sources */, 95919DB628F076BF00F21F8F /* UserClass.swift in Sources */, + 95C6456E28FE8C04000CD570 /* UserImageHelper.swift in Sources */, 95C4315628C64A8C00212131 /* ContentView.swift in Sources */, 95C4315928C6500000212131 /* GameButtonHelper.swift in Sources */, 956273EA28CB2E98008DC094 /* FlagImageHelper.swift in Sources */, @@ -308,11 +319,12 @@ 95FA409C28D9881100129B60 /* CountryGameClass.swift in Sources */, 95CA295028F6BB4500CE0B7A /* ActivityAlertHelper.swift in Sources */, 955A658128D703EB00CEEC6D /* GameToolbarHelper.swift in Sources */, - 95CA294028F5769700CE0B7A /* GameModeEnum.swift in Sources */, 95AE8D5728C8750E0067F219 /* LoadFunc.swift in Sources */, 9590359528E098FF00B24560 /* ProfileModalView.swift in Sources */, 955950BB28F15FF2001BDEE8 /* FormatterExtension.swift in Sources */, + 95C6456C28FE87E4000CD570 /* UserDataModel.swift in Sources */, 951D197328D485E000671FAD /* ColorExtension.swift in Sources */, + 95C6457228FFC4DC000CD570 /* ProfileEditModalView.swift in Sources */, 95C430F928D0A8E500480D23 /* GradientExtension.swift in Sources */, 952E41ED28DC658900198643 /* SettingsModalView.swift in Sources */, 95FA409A28D9876B00129B60 /* GuessTheFlagView.swift in Sources */, @@ -456,6 +468,7 @@ INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -489,6 +502,7 @@ INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks",
--- a/GeoQuiz/Assets.xcassets/flag.imageset/Contents.json Wed Oct 12 11:47:29 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "filename" : "flag.png", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GeoQuiz/Components/ProfileEditModalView.swift Wed Oct 19 07:56:33 2022 +0200 @@ -0,0 +1,70 @@ +// +// ProfileEditModalView.swift +// GeoQuiz +// +// Created by Dennis Concepci贸n Mart铆n on 19/10/22. +// + +import SwiftUI +import PhotosUI + +struct ProfileEditModalView: View { + @ObservedObject var user: User + @Environment(\.dismiss) var dismiss + + @State private var selectedItem: PhotosPickerItem? = nil + + var body: some View { + NavigationStack { + Form { + Section { + HStack { + Spacer() + ZStack { + UserImage(uiImage: user.data.uiImage) + .onChange(of: selectedItem) { newItem in + Task { + if let data = try? await newItem?.loadTransferable(type: Data.self) { + user.data.imageData = data + } + } + } + + PhotosPicker( + selection: $selectedItem, + matching: .images, + photoLibrary: .shared()) { + EmptyView() + } + } + + Spacer() + } + } header: { + Text("Profile image") + } + + Section { + TextField("Enter a username", text: $user.data.username) + } header: { + Text("Username") + } + } + .navigationTitle("Edit profile") + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Button("Done") { + dismiss() + } + } + } + } + } +} + +struct ProfileEditModalView_Previews: PreviewProvider { + static var previews: some View { + ProfileEditModalView(user: User()) + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GeoQuiz/Components/UserImageHelper.swift Wed Oct 19 07:56:33 2022 +0200 @@ -0,0 +1,39 @@ +// +// UserImageHelper.swift +// GeoQuiz +// +// Created by Dennis Concepci贸n Mart铆n on 18/10/22. +// + +import SwiftUI + +struct UserImage: View { + var uiImage: UIImage? + + var body: some View { + if let uiImage = uiImage { + Circle() + .frame(height: 100) + .overlay( + Image(uiImage: uiImage) + .resizable() + .scaledToFill() + .clipShape(Circle()) + ) + } else { + Circle() + .frame(height: 100) + .foregroundColor(.secondary.opacity(0.3)) + .overlay( + Image(systemName: "person") + .font(.largeTitle) + ) + } + } +} + +struct UserImage_Previews: PreviewProvider { + static var previews: some View { + UserImage() + } +}
--- a/GeoQuiz/ContentView.swift Wed Oct 12 11:47:29 2022 +0200 +++ b/GeoQuiz/ContentView.swift Wed Oct 19 07:56:33 2022 +0200 @@ -8,116 +8,104 @@ import SwiftUI struct ContentView: View { - @State private var gameModeSelection: GameMode? = nil + @State private var path: [GameType] = [] @State private var showingBuyPremiumModalView = false @State private var showingSettingsModalView = false @State private var showingProfileModalView = false @StateObject var storeKitRC = StoreKitRC() + @StateObject var user = User() var body: some View { - NavigationView { - VStack { - NavigationLink( - destination: GuessTheFlagView(), - tag: GameMode.guessTheFlag, - selection: $gameModeSelection) - { - EmptyView() - } + NavigationStack(path: $path) { + ScrollView(showsIndicators: false) { - NavigationLink( - destination: GuessTheCapitalView(), - tag: GameMode.guessTheCapital, - selection: $gameModeSelection) - { - EmptyView() - } - - NavigationLink( - destination: GuessTheCountryView(), - tag: GameMode.guessTheCountry, - selection: $gameModeSelection) - { - EmptyView() - } - - NavigationLink( - destination: GuessThePopulationView(), - tag: GameMode.guessThePopulation, - selection: $gameModeSelection) - { - EmptyView() - } + NavigationLink(value: GameType.guessTheFlag) { EmptyView() } + NavigationLink(value: GameType.guessTheCapital) { EmptyView() } + NavigationLink(value: GameType.guessTheCountry) { EmptyView() } + NavigationLink(value: GameType.guessThePopulation) { EmptyView() } - ScrollView(showsIndicators: false) { - VStack(alignment: .leading, spacing: 30) { - Text("Select a game 馃幃") - .font(.largeTitle.bold()) - .padding(.bottom) - - Button { - gameModeSelection = .guessTheFlag - } label: { - GameButton( - gradient: .main, - level: "Level 1", - symbol: "flag.fill", - name: "Guess the flag" - ) - } - - Button { - if storeKitRC.isActive { - gameModeSelection = .guessTheCapital - } else { - showingBuyPremiumModalView = true - } - } label: { - GameButton( - gradient: .secondary, - level: "Level 2", - symbol: storeKitRC.isActive ? "building.2.fill": "lock.fill", - name: "Guess the capital" - ) + VStack(alignment: .leading, spacing: 30) { + Text("Select a game 馃幃") + .font(.largeTitle.bold()) + .padding(.bottom) + + Button { + path.append(.guessTheFlag) + } label: { + GameButton( + gradient: .main, + level: "Level 1", + symbol: "flag.fill", + name: "Guess the flag" + ) + } + + Button { + if storeKitRC.isActive { + path.append(.guessTheCapital) + } else { + showingBuyPremiumModalView = true } - - Button { - if storeKitRC.isActive { - gameModeSelection = .guessTheCountry - } else { - showingBuyPremiumModalView = true - } - } label: { - GameButton( - gradient: .tertiary, - level: "Level 3", - symbol: storeKitRC.isActive ? "globe.americas.fill": "lock.fill", - name: "Guess the country" - ) + } label: { + GameButton( + gradient: .secondary, + level: "Level 2", + symbol: storeKitRC.isActive ? "building.2.fill": "lock.fill", + name: "Guess the capital" + ) + } + + Button { + if storeKitRC.isActive { + path.append(.guessTheCountry) + } else { + showingBuyPremiumModalView = true } - - Button { - if storeKitRC.isActive { - gameModeSelection = .guessThePopulation - } else { - showingBuyPremiumModalView = true - } - } label: { - GameButton( - gradient: .quaternary, - level: "Level 4", - symbol: storeKitRC.isActive ? "person.fill": "lock.fill", - name: "Guess the population" - ) + } label: { + GameButton( + gradient: .tertiary, + level: "Level 3", + symbol: storeKitRC.isActive ? "globe.americas.fill": "lock.fill", + name: "Guess the country" + ) + } + + Button { + if storeKitRC.isActive { + path.append(.guessThePopulation) + } else { + showingBuyPremiumModalView = true } + } label: { + GameButton( + gradient: .quaternary, + level: "Level 4", + symbol: storeKitRC.isActive ? "person.fill": "lock.fill", + name: "Guess the population" + ) } - .padding() + } + .padding() } .navigationTitle("GeoQuiz") .navigationBarTitleDisplayMode(.inline) + + .navigationDestination(for: GameType.self) { gameMode in + switch gameMode { + case .guessTheFlag: + GuessTheFlagView() + case .guessTheCapital: + GuessTheFlagView() + case .guessTheCountry: + GuessTheCountryView() + case .guessThePopulation: + GuessThePopulationView() + } + } + .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button { @@ -148,11 +136,11 @@ } .sheet(isPresented: $showingSettingsModalView) { - SettingsModalView() + SettingsModalView(user: user) } .sheet(isPresented: $showingProfileModalView) { - ProfileModalView() + ProfileModalView(user: user, storeKitRC: storeKitRC) } } .navigationViewStyle(StackNavigationViewStyle())
--- a/GeoQuiz/Logic/CityGameClass.swift Wed Oct 12 11:47:29 2022 +0200 +++ b/GeoQuiz/Logic/CityGameClass.swift Wed Oct 19 07:56:33 2022 +0200 @@ -49,11 +49,11 @@ self.data = data.cities let user = User() - userLives = user.settings.numberOfLives + userLives = user.data.numberOfLives - if let userSettings = UserDefaults.standard.data(forKey: "UserSettings") { - if let decodedUserSettings = try? JSONDecoder().decode(UserSettings.self, from: userSettings) { - userLives = decodedUserSettings.numberOfLives + if let userData = UserDefaults.standard.data(forKey: "UserData") { + if let decodedUserData = try? JSONDecoder().decode(UserData.self, from: userData) { + userLives = decodedUserData.numberOfLives } }
--- a/GeoQuiz/Logic/CountryGameClass.swift Wed Oct 12 11:47:29 2022 +0200 +++ b/GeoQuiz/Logic/CountryGameClass.swift Wed Oct 19 07:56:33 2022 +0200 @@ -49,11 +49,11 @@ self.data = data.countries let user = User() - userLives = user.settings.numberOfLives + userLives = user.data.numberOfLives - if let userSettings = UserDefaults.standard.data(forKey: "UserSettings") { - if let decodedUserSettings = try? JSONDecoder().decode(UserSettings.self, from: userSettings) { - userLives = decodedUserSettings.numberOfLives + if let userData = UserDefaults.standard.data(forKey: "UserData") { + if let decodedUserData = try? JSONDecoder().decode(UserData.self, from: userData) { + userLives = decodedUserData.numberOfLives } }
--- a/GeoQuiz/Logic/GameModeEnum.swift Wed Oct 12 11:47:29 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -// -// GameModeEnum.swift -// GeoQuiz -// -// Created by Dennis Concepci贸n Mart铆n on 11/10/22. -// - -import Foundation - -enum GameMode { - case guessTheFlag, guessTheCapital, guessTheCountry, guessThePopulation -}
--- a/GeoQuiz/Logic/GameProtocol+Extension.swift Wed Oct 12 11:47:29 2022 +0200 +++ b/GeoQuiz/Logic/GameProtocol+Extension.swift Wed Oct 19 07:56:33 2022 +0200 @@ -121,7 +121,7 @@ private func playSound(_ filename: String) { let user = User() - if user.settings.sound { + if user.data.sound { guard let soundFileURL = Bundle.main.url(forResource: filename, withExtension: "wav") else { fatalError("Sound file \(filename) couldn't be found") }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GeoQuiz/Logic/GameTypeEnum.swift Wed Oct 19 07:56:33 2022 +0200 @@ -0,0 +1,12 @@ +// +// GameTypeEnum.swift +// GeoQuiz +// +// Created by Dennis Concepci贸n Mart铆n on 14/10/22. +// + +import Foundation + +enum GameType { + case guessTheFlag, guessTheCapital, guessTheCountry, guessThePopulation +}
--- a/GeoQuiz/Logic/HapticsClass.swift Wed Oct 12 11:47:29 2022 +0200 +++ b/GeoQuiz/Logic/HapticsClass.swift Wed Oct 19 07:56:33 2022 +0200 @@ -12,14 +12,14 @@ private var user = User() func success() { - if user.settings.haptics { + if user.data.haptics { let generator = UINotificationFeedbackGenerator() generator.notificationOccurred(.success) } } func error() { - if user.settings.haptics { + if user.data.haptics { let generator = UINotificationFeedbackGenerator() generator.notificationOccurred(.error) }
--- a/GeoQuiz/Logic/StoreKitRCClass.swift Wed Oct 12 11:47:29 2022 +0200 +++ b/GeoQuiz/Logic/StoreKitRCClass.swift Wed Oct 19 07:56:33 2022 +0200 @@ -7,7 +7,6 @@ import Foundation import RevenueCat -import SwiftUI class StoreKitRC: ObservableObject { @Published var errorAlertTitle = ""
--- a/GeoQuiz/Logic/UserClass.swift Wed Oct 12 11:47:29 2022 +0200 +++ b/GeoQuiz/Logic/UserClass.swift Wed Oct 19 07:56:33 2022 +0200 @@ -8,19 +8,18 @@ import Foundation class User: ObservableObject { - @Published var settings = UserSettings() { + @Published var data = UserData() { didSet { - if let userSettingsEncoded = try? JSONEncoder().encode(settings) { - UserDefaults.standard.set(userSettingsEncoded, forKey: "UserSettings") + if let userDataEncoded = try? JSONEncoder().encode(data) { + UserDefaults.standard.set(userDataEncoded, forKey: "UserData") } } } - - + init() { - if let userSettings = UserDefaults.standard.data(forKey: "UserSettings") { - if let decodedUserSettings = try? JSONDecoder().decode(UserSettings.self, from: userSettings) { - settings = decodedUserSettings + if let userData = UserDefaults.standard.data(forKey: "UserData") { + if let decodedUserData = try? JSONDecoder().decode(UserData.self, from: userData) { + data = decodedUserData } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GeoQuiz/Logic/UserDataModel.swift Wed Oct 19 07:56:33 2022 +0200 @@ -0,0 +1,26 @@ +// +// UserDataModel.swift +// GeoQuiz +// +// Created by Dennis Concepci贸n Mart铆n on 18/10/22. +// + +import Foundation +import SwiftUI + +struct UserData: Codable { + + // Settings + var haptics: Bool = true + var sound: Bool = true + var numberOfLives: Int = 25 + + // Profile + var username: String = "Anonymous" + var imageData: Data? + + var uiImage: UIImage? { + guard let imageData = imageData else { return nil } + return UIImage(data: imageData) + } +}
--- a/GeoQuiz/Logic/UserSettingsModel.swift Wed Oct 12 11:47:29 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -// -// UserSettingsModel.swift -// GeoQuiz -// -// Created by Dennis Concepci贸n Mart铆n on 7/10/22. -// - -import Foundation - -struct UserSettings: Codable { - var haptics: Bool = true - var sound: Bool = true - var numberOfLives: Int = 25 -}
--- a/GeoQuiz/ProfileModalView.swift Wed Oct 12 11:47:29 2022 +0200 +++ b/GeoQuiz/ProfileModalView.swift Wed Oct 19 07:56:33 2022 +0200 @@ -6,15 +6,97 @@ // import SwiftUI +import PhotosUI struct ProfileModalView: View { + @ObservedObject var user: User + @ObservedObject var storeKitRC: StoreKitRC + + @Environment(\.dismiss) var dismiss + + @State private var showingEditModalView = false + var body: some View { - Text("Hello, World!") + NavigationView { + Form { + Section { + HStack(spacing: 20) { + UserImage(uiImage: user.data.uiImage) + + VStack(alignment: .leading, spacing: 8) { + Text(user.data.username) + .font(.title) + .fontWeight(.semibold) + + if storeKitRC.isActive { + Text("Premium user 猸愶笍") + .foregroundColor(.secondary) + } + } + } + } + + Section { + VStack(alignment: .leading) { + Text("Game 1") + Capsule() + .frame(height: 6) + } + + VStack(alignment: .leading) { + Text("Game 1") + Capsule() + .frame(height: 6) + } + VStack(alignment: .leading) { + Text("Game 1") + Capsule() + .frame(height: 6) + } + VStack(alignment: .leading) { + Text("Game 1") + Capsule() + .frame(height: 6) + } + } header: { + Text("Progress") + } + + Section { + ForEach(1..<10) { _ in + Text("Hello") + } + } header: { + Text("Recent games") + } + } + .navigationTitle("Profile") + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .cancellationAction) { + Button { + dismiss() + } label: { + Label("Exit", systemImage: "multiply") + } + } + + ToolbarItem(placement: .navigationBarTrailing) { + Button("Edit") { + showingEditModalView = true + } + } + } + + .sheet(isPresented: $showingEditModalView) { + ProfileEditModalView(user: user) + } + } } } struct ProfileView_Previews: PreviewProvider { static var previews: some View { - ProfileModalView() + ProfileModalView(user: User(), storeKitRC: StoreKitRC()) } }
--- a/GeoQuiz/SettingsModalView.swift Wed Oct 12 11:47:29 2022 +0200 +++ b/GeoQuiz/SettingsModalView.swift Wed Oct 19 07:56:33 2022 +0200 @@ -8,8 +8,8 @@ import SwiftUI struct SettingsModalView: View { + @ObservedObject var user: User @Environment(\.dismiss) var dismiss - @StateObject var user = User() var lives: [Int] { var lives = [Int]() @@ -24,7 +24,7 @@ NavigationView { Form { Section { - Picker("鉂わ笍 Lives", selection: $user.settings.numberOfLives) { + Picker("鉂わ笍 Lives", selection: $user.data.numberOfLives) { ForEach(lives, id: \.self) { numberOfLives in Text("\(numberOfLives)") .tag(numberOfLives) @@ -37,8 +37,8 @@ } Section { - Toggle("Haptics", isOn: $user.settings.haptics) - Toggle("Sound effects", isOn: $user.settings.sound) + Toggle("Haptics", isOn: $user.data.haptics) + Toggle("Sound effects", isOn: $user.data.sound) } header: { Text("Effects") } @@ -84,6 +84,6 @@ struct SettingsModalView_Previews: PreviewProvider { static var previews: some View { - SettingsModalView() + SettingsModalView(user: User()) } }