diff --git a/Sources/AllInApp/AllIn/AllIn.entitlements b/Sources/AllInApp/AllIn/AllIn.entitlements new file mode 100644 index 0000000..0f06eb8 --- /dev/null +++ b/Sources/AllInApp/AllIn/AllIn.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.alldev.AllIn + + + diff --git a/Sources/AllInApp/AllIn/AppState.swift b/Sources/AllInApp/AllIn/AppState.swift index a276067..40ba358 100644 --- a/Sources/AllInApp/AllIn/AppState.swift +++ b/Sources/AllInApp/AllIn/AppState.swift @@ -15,7 +15,7 @@ class AppStateContainer: ObservableObject { var notificationState: NotificationService = NotificationService() @Published var user: User? - @AppStorage("authenticationRefresh") var authenticationRefresh: String? + @AppStorage("authenticationRefresh", store: UserDefaults(suiteName: "group.alldev.AllIn")!) var authenticationRefresh: String? } class LoggedState: ObservableObject { diff --git a/Sources/AllInApp/AllIn/Services/AuthService.swift b/Sources/AllInApp/AllIn/Services/AuthService.swift index 1ba93af..671c7d0 100644 --- a/Sources/AllInApp/AllIn/Services/AuthService.swift +++ b/Sources/AllInApp/AllIn/Services/AuthService.swift @@ -10,6 +10,7 @@ import Model import DependencyInjection import Api import StubLib +import WidgetKit class AuthService: IAuthService { @@ -114,6 +115,7 @@ class AuthService: IAuthService { let user = User.mapUser(from: userJson) { AppStateContainer.shared.user = user AppStateContainer.shared.loggedState.connectedUser = true + WidgetCenter.shared.reloadAllTimelines() self.initManagerVM(token: token) } } else { @@ -140,6 +142,7 @@ class AuthService: IAuthService { let user = User.mapUser(from: userJson) { completion(httpResponse.statusCode) AppStateContainer.shared.user = user + WidgetCenter.shared.reloadAllTimelines() } } else { completion(httpResponse.statusCode) @@ -157,6 +160,8 @@ class AuthService: IAuthService { public func logout() { AppStateContainer.shared.authenticationRefresh = nil AppStateContainer.shared.loggedState.connectedUser = false + AppStateContainer.shared.notificationState.removeAllNotifications() + WidgetCenter.shared.reloadAllTimelines() } } diff --git a/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift index c9054f2..543196b 100644 --- a/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/DetailsViewModel.swift @@ -9,6 +9,7 @@ import Foundation import SwiftUI import DependencyInjection import Model +import WidgetKit class DetailsViewModel: ObservableObject { @@ -42,6 +43,8 @@ class DetailsViewModel: ObservableObject { switch statusCode { case 201: AppStateContainer.shared.user?.nbCoins -= stake + WidgetCenter.shared.reloadAllTimelines() + self.getItem(withId: self.id) default: break diff --git a/Sources/AllInApp/AllIn/Views/LoginView.swift b/Sources/AllInApp/AllIn/Views/LoginView.swift index 7873f19..e417a6b 100644 --- a/Sources/AllInApp/AllIn/Views/LoginView.swift +++ b/Sources/AllInApp/AllIn/Views/LoginView.swift @@ -14,6 +14,7 @@ struct LoginView: View { case password } + @AppStorage("test") var test: String? @StateObject private var viewModel = LoginViewModel() @FocusState private var focusedField: Field? @State private var isPasswordVisible = true @@ -97,6 +98,7 @@ struct LoginView: View { Button(action: { viewModel.login() + test = "REtoutt" }) { Text("Se connecter") .textStyle(weight: .bold, color: .white, size: 17) diff --git a/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj b/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj index 59d7330..bbccc8f 100644 --- a/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj +++ b/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj @@ -79,6 +79,16 @@ ECB7BC702B336E28002A6654 /* RegisterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB7BC6F2B336E28002A6654 /* RegisterViewModel.swift */; }; ECCD244A2B4DE8010071FA9E /* Api in Frameworks */ = {isa = PBXBuildFile; productRef = ECCD24492B4DE8010071FA9E /* Api */; }; ECED90B52B6D9CEC00F50937 /* DailyGiftPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECED90B42B6D9CEC00F50937 /* DailyGiftPage.swift */; }; + ECF872662B9266C000F9D240 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECF872652B9266C000F9D240 /* WidgetKit.framework */; }; + ECF872682B9266C000F9D240 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECF872672B9266C000F9D240 /* SwiftUI.framework */; }; + ECF8726B2B9266C000F9D240 /* AllInWidgetsBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF8726A2B9266C000F9D240 /* AllInWidgetsBundle.swift */; }; + ECF8726D2B9266C000F9D240 /* AllInWidgetsLiveActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF8726C2B9266C000F9D240 /* AllInWidgetsLiveActivity.swift */; }; + ECF8726F2B9266C000F9D240 /* AllInCoinsWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF8726E2B9266C000F9D240 /* AllInCoinsWidget.swift */; }; + ECF872722B9266C100F9D240 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ECF872712B9266C100F9D240 /* Assets.xcassets */; }; + ECF872742B9266C100F9D240 /* AllInWidgets.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = ECF872702B9266C000F9D240 /* AllInWidgets.intentdefinition */; }; + ECF872752B9266C100F9D240 /* AllInWidgets.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = ECF872702B9266C000F9D240 /* AllInWidgets.intentdefinition */; }; + ECF872782B9266C100F9D240 /* AllInWidgetsExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = ECF872642B9266C000F9D240 /* AllInWidgetsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + ECF872822B92696C00F9D240 /* Provider.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF872812B92696C00F9D240 /* Provider.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -96,6 +106,13 @@ remoteGlobalIDString = EC6B96972B24B4CC00FC1C58; remoteInfo = AllIn; }; + ECF872762B9266C100F9D240 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = EC6B96902B24B4CC00FC1C58 /* Project object */; + proxyType = 1; + remoteGlobalIDString = ECF872632B9266C000F9D240; + remoteInfo = AllInWidgetsExtension; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -110,6 +127,17 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; + ECF872792B9266C100F9D240 /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + ECF872782B9266C100F9D240 /* AllInWidgetsExtension.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -188,6 +216,18 @@ ECB7BC6B2B2F43EE002A6654 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = ""; }; ECB7BC6F2B336E28002A6654 /* RegisterViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterViewModel.swift; sourceTree = ""; }; ECED90B42B6D9CEC00F50937 /* DailyGiftPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyGiftPage.swift; sourceTree = ""; }; + ECF872642B9266C000F9D240 /* AllInWidgetsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = AllInWidgetsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + ECF872652B9266C000F9D240 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; + ECF872672B9266C000F9D240 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; + ECF8726A2B9266C000F9D240 /* AllInWidgetsBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllInWidgetsBundle.swift; sourceTree = ""; }; + ECF8726C2B9266C000F9D240 /* AllInWidgetsLiveActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllInWidgetsLiveActivity.swift; sourceTree = ""; }; + ECF8726E2B9266C000F9D240 /* AllInCoinsWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllInCoinsWidget.swift; sourceTree = ""; }; + ECF872702B9266C000F9D240 /* AllInWidgets.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = AllInWidgets.intentdefinition; sourceTree = ""; }; + ECF872712B9266C100F9D240 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + ECF872732B9266C100F9D240 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + ECF872812B92696C00F9D240 /* Provider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Provider.swift; sourceTree = ""; }; + ECF872852B93B9D900F9D240 /* AllIn.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AllIn.entitlements; sourceTree = ""; }; + ECF872862B93BA7D00F9D240 /* AllInWidgetsExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AllInWidgetsExtension.entitlements; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -215,6 +255,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + ECF872612B9266C000F9D240 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ECF872682B9266C000F9D240 /* SwiftUI.framework in Frameworks */, + ECF872662B9266C000F9D240 /* WidgetKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -229,9 +278,11 @@ EC6B968F2B24B4CC00FC1C58 = { isa = PBXGroup; children = ( + ECF872862B93BA7D00F9D240 /* AllInWidgetsExtension.entitlements */, EC6B969A2B24B4CC00FC1C58 /* AllIn */, EC6B96AB2B24B4CC00FC1C58 /* AllInTests */, EC6B96B52B24B4CC00FC1C58 /* AllInUITests */, + ECF872692B9266C000F9D240 /* AllInWidgets */, EC6B96992B24B4CC00FC1C58 /* Products */, ECB3572D2B3CA3BD00045D41 /* Frameworks */, ); @@ -243,6 +294,7 @@ EC6B96982B24B4CC00FC1C58 /* AllIn.app */, EC6B96A82B24B4CC00FC1C58 /* AllInTests.xctest */, EC6B96B22B24B4CC00FC1C58 /* AllInUITests.xctest */, + ECF872642B9266C000F9D240 /* AllInWidgetsExtension.appex */, ); name = Products; sourceTree = ""; @@ -250,6 +302,7 @@ EC6B969A2B24B4CC00FC1C58 /* AllIn */ = { isa = PBXGroup; children = ( + ECF872852B93B9D900F9D240 /* AllIn.entitlements */, EC7EF7462B87E3470022B5D9 /* QuickActions */, ECB7BC662B2F1AAD002A6654 /* ViewModels */, EC6B96D62B24BEBD00FC1C58 /* Components */, @@ -390,6 +443,8 @@ 122278B72B4BDE1100E632AA /* DependencyInjection.framework */, ECB357302B3CA69300045D41 /* DependencyInjection.framework */, ECB3572E2B3CA3C300045D41 /* DependencyInjection.framework */, + ECF872652B9266C000F9D240 /* WidgetKit.framework */, + ECF872672B9266C000F9D240 /* SwiftUI.framework */, ); name = Frameworks; sourceTree = ""; @@ -411,6 +466,20 @@ path = ViewModels; sourceTree = ""; }; + ECF872692B9266C000F9D240 /* AllInWidgets */ = { + isa = PBXGroup; + children = ( + ECF8726A2B9266C000F9D240 /* AllInWidgetsBundle.swift */, + ECF8726C2B9266C000F9D240 /* AllInWidgetsLiveActivity.swift */, + ECF8726E2B9266C000F9D240 /* AllInCoinsWidget.swift */, + ECF872812B92696C00F9D240 /* Provider.swift */, + ECF872702B9266C000F9D240 /* AllInWidgets.intentdefinition */, + ECF872712B9266C100F9D240 /* Assets.xcassets */, + ECF872732B9266C100F9D240 /* Info.plist */, + ); + path = AllInWidgets; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -422,10 +491,12 @@ EC6B96952B24B4CC00FC1C58 /* Frameworks */, EC6B96962B24B4CC00FC1C58 /* Resources */, ECB357332B3CA69300045D41 /* Embed Frameworks */, + ECF872792B9266C100F9D240 /* Embed Foundation Extensions */, ); buildRules = ( ); dependencies = ( + ECF872772B9266C100F9D240 /* PBXTargetDependency */, ); name = AllIn; packageProductDependencies = ( @@ -473,6 +544,23 @@ productReference = EC6B96B22B24B4CC00FC1C58 /* AllInUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; + ECF872632B9266C000F9D240 /* AllInWidgetsExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = ECF8727C2B9266C100F9D240 /* Build configuration list for PBXNativeTarget "AllInWidgetsExtension" */; + buildPhases = ( + ECF872602B9266C000F9D240 /* Sources */, + ECF872612B9266C000F9D240 /* Frameworks */, + ECF872622B9266C000F9D240 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AllInWidgetsExtension; + productName = AllInWidgetsExtension; + productReference = ECF872642B9266C000F9D240 /* AllInWidgetsExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -494,6 +582,9 @@ CreatedOnToolsVersion = 14.3.1; TestTargetID = EC6B96972B24B4CC00FC1C58; }; + ECF872632B9266C000F9D240 = { + CreatedOnToolsVersion = 14.3.1; + }; }; }; buildConfigurationList = EC6B96932B24B4CC00FC1C58 /* Build configuration list for PBXProject "AllInApp" */; @@ -514,6 +605,7 @@ EC6B96972B24B4CC00FC1C58 /* AllIn */, EC6B96A72B24B4CC00FC1C58 /* AllInTests */, EC6B96B12B24B4CC00FC1C58 /* AllInUITests */, + ECF872632B9266C000F9D240 /* AllInWidgetsExtension */, ); }; /* End PBXProject section */ @@ -543,6 +635,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + ECF872622B9266C000F9D240 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ECF872722B9266C100F9D240 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -600,6 +700,7 @@ ECB7BC682B2F1ADF002A6654 /* LoginViewModel.swift in Sources */, 1244EF622B4EC67000374ABF /* ReviewCard.swift in Sources */, EC6B96D52B24BE0E00FC1C58 /* MainView.swift in Sources */, + ECF872752B9266C100F9D240 /* AllInWidgets.intentdefinition in Sources */, EC650A562B279D68003AFCAD /* WinModal.swift in Sources */, EC6B96D12B24BAE800FC1C58 /* AuthService.swift in Sources */, 123590B62B5537E200F7AEBD /* ResultBanner.swift in Sources */, @@ -632,6 +733,18 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + ECF872602B9266C000F9D240 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ECF8726B2B9266C000F9D240 /* AllInWidgetsBundle.swift in Sources */, + ECF872742B9266C100F9D240 /* AllInWidgets.intentdefinition in Sources */, + ECF8726F2B9266C000F9D240 /* AllInCoinsWidget.swift in Sources */, + ECF8726D2B9266C000F9D240 /* AllInWidgetsLiveActivity.swift in Sources */, + ECF872822B92696C00F9D240 /* Provider.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -645,6 +758,11 @@ target = EC6B96972B24B4CC00FC1C58 /* AllIn */; targetProxy = EC6B96B32B24B4CC00FC1C58 /* PBXContainerItemProxy */; }; + ECF872772B9266C100F9D240 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = ECF872632B9266C000F9D240 /* AllInWidgetsExtension */; + targetProxy = ECF872762B9266C100F9D240 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -765,12 +883,14 @@ EC6B96BD2B24B4CC00FC1C58 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = AllIn/AllIn.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"AllIn/Preview Content\""; - DEVELOPMENT_TEAM = 35KQ5BDC64; + DEVELOPMENT_TEAM = P39ZK4GA2T; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = "All In"; @@ -797,12 +917,14 @@ EC6B96BE2B24B4CC00FC1C58 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = AllIn/AllIn.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"AllIn/Preview Content\""; - DEVELOPMENT_TEAM = 35KQ5BDC64; + DEVELOPMENT_TEAM = P39ZK4GA2T; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = "All In"; @@ -898,6 +1020,62 @@ }; name = Release; }; + ECF8727A2B9266C100F9D240 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = AllInWidgetsExtension.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = P39ZK4GA2T; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = AllInWidgets/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = AllInWidgets; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.alldev.AllIn.AllInWidgets; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + ECF8727B2B9266C100F9D240 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = AllInWidgetsExtension.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = P39ZK4GA2T; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = AllInWidgets/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = AllInWidgets; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.alldev.AllIn.AllInWidgets; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -937,6 +1115,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + ECF8727C2B9266C100F9D240 /* Build configuration list for PBXNativeTarget "AllInWidgetsExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + ECF8727A2B9266C100F9D240 /* Debug */, + ECF8727B2B9266C100F9D240 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCSwiftPackageProductDependency section */ diff --git a/Sources/AllInApp/AllInWidgets/AllInCoinsWidget.swift b/Sources/AllInApp/AllInWidgets/AllInCoinsWidget.swift new file mode 100644 index 0000000..c311959 --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/AllInCoinsWidget.swift @@ -0,0 +1,214 @@ +// +// AllInCoinsWidgets.swift +// AllInCoinsWidgets +// +// Created by Emre on 01/03/2024. +// + +import WidgetKit +import SwiftUI + +struct AllInCoinsWidgetEntryView : View { + var user: Provider.Entry + + @Environment(\.widgetFamily) var family + + var body: some View { + switch family { + case .systemSmall: + SmallSizedWidget() + case .systemMedium: + MediumSizedWidget() + case .accessoryRectangular: + LockScreenRectangularWidget() + case .accessoryInline: + LockScreenInlineWidget() + case .accessoryCircular: + LockScreenCircularWidget() + default: + Text("Not implemented") + } + } + + @ViewBuilder + func LockScreenInlineWidget() -> some View { + if user.connected { + Text("💸 " + user.coins.abbreviated()) + .bold() + .font(.headline) + .foregroundColor(.white) + + } else { + Text("💸 Connexion") + .bold() + .font(.headline) + .foregroundColor(.white) + } + + } + + @ViewBuilder + func LockScreenCircularWidget() -> some View { + if user.connected { + Gauge(value: Float(user.coins) / 10000) { + Text(user.coins.abbreviated()) + } + .gaugeStyle(.accessoryCircular) + } else { + ZStack { + Image("launchScreenImage") + .resizable() + .aspectRatio(contentMode: .fill) + + VStack { + Text("Vide") + Text("All In") + } + } + } + } + + @ViewBuilder + func LockScreenRectangularWidget() -> some View { + VStack(alignment: .leading) { + HStack { + Image("allcoinIcon") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 20, height: 20) + + if user.connected { + VStack(alignment: .leading) { + Text(user.coins.abbreviated()) + .fontWeight(.bold) + .font(.headline) + .foregroundColor(.white) + + Text(user.username.description.capitalized + ", venez jouez !") + .font(.caption2) + .foregroundColor(.white) + } + } else { + Text("Connexion") + .font(.headline) + .foregroundColor(.white) + } + } + + Text("All In") + .font(.callout) + .fontWeight(.semibold) + } + } + + @ViewBuilder + func SmallSizedWidget() -> some View { + ZStack { + Image("launchScreenImage") + .resizable() + .aspectRatio(contentMode: .fill) + + VStack { + HStack { + Image("allcoinWhiteIcon") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 30, height: 30) + + if user.connected { + VStack(alignment: .leading) { + Text(user.coins.abbreviated()) + .fontWeight(.bold) + .font(.headline) + .foregroundColor(.white) + + Text(user.username.description.capitalized + ", venez jouez !") + .font(.caption2) + .foregroundColor(.white) + } + } else { + Text("Connexion") + .font(.headline) + .fontWeight(.bold) + .foregroundColor(.white) + } + } + } + } + } + + @ViewBuilder + func MediumSizedWidget() -> some View { + ZStack { + Rectangle() + .fill(LinearGradient(gradient: Gradient(colors: [Color("PinkAccentColor"), Color("PurpleAccentColor"), Color("BlueAccentColor")]), startPoint: .top, endPoint: .bottom)) + + VStack { + HStack { + Image("allcoinWhiteIcon") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 45, height: 45) + + if user.connected { + VStack(alignment: .leading) { + Text(user.coins.abbreviated()) + .fontWeight(.bold) + .font(.title) + .foregroundColor(.white) + + Text(user.username.description.capitalized + ", venez jouez !") + .font(.caption) + .foregroundColor(.white) + } + } else { + Text("Connexion") + .font(.title) + .fontWeight(.bold) + .foregroundColor(.white) + } + } + } + } + } +} + +struct AllInCoinsWidget: Widget { + let kind: String = "AllInCoinsWidgets" + + var body: some WidgetConfiguration { + IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in + AllInCoinsWidgetEntryView(user: entry) + } + .configurationDisplayName("All Coins") + .description("Visualiser rapidement votre nombre de all coins restants.") + .supportedFamilies([.systemSmall, .systemMedium, .accessoryRectangular, .accessoryInline, .accessoryCircular]) + + } +} + +struct AllInCoinsWidget_Previews: PreviewProvider { + static var previews: some View { + AllInCoinsWidgetEntryView(user: User(date: Date(), coins: 1000, username: "test", connected: false)) + .previewContext(WidgetPreviewContext(family: .systemSmall)) + + AllInCoinsWidgetEntryView(user: User(date: Date(), coins: 1000, username: "test", connected: true)) + .previewContext(WidgetPreviewContext(family: .systemMedium)) + } +} + +extension Int { + func abbreviated() -> String { + if self < 1000 { + return "\(self)" + } + let abbreviations = ["", "K", "M", "B", "T"] + var num = Double(self) + var index = 0 + while num >= 1000 && index < abbreviations.count - 1 { + num /= 1000 + index += 1 + } + return String(format: "%.1f%@", num, abbreviations[index]) + } +} diff --git a/Sources/AllInApp/AllInWidgets/AllInWidgets.intentdefinition b/Sources/AllInApp/AllInWidgets/AllInWidgets.intentdefinition new file mode 100644 index 0000000..bdb4045 --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/AllInWidgets.intentdefinition @@ -0,0 +1,59 @@ + + + + + INEnums + + INIntentDefinitionModelVersion + 1.2 + INIntentDefinitionNamespace + 88xZPY + INIntentDefinitionSystemVersion + 20A294 + INIntentDefinitionToolsBuildVersion + 12A6144 + INIntentDefinitionToolsVersion + 12.0 + INIntents + + + INIntentCategory + information + INIntentDescriptionID + tVvJ9c + INIntentEligibleForWidgets + + INIntentIneligibleForSuggestions + + INIntentName + Configuration + INIntentResponse + + INIntentResponseCodes + + + INIntentResponseCodeName + success + INIntentResponseCodeSuccess + + + + INIntentResponseCodeName + failure + + + + INIntentTitle + Configuration + INIntentTitleID + gpCwrM + INIntentType + Custom + INIntentVerb + View + + + INTypes + + + diff --git a/Sources/AllInApp/AllInWidgets/AllInWidgetsBundle.swift b/Sources/AllInApp/AllInWidgets/AllInWidgetsBundle.swift new file mode 100644 index 0000000..dd3827d --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/AllInWidgetsBundle.swift @@ -0,0 +1,17 @@ +// +// AllInWidgetsBundle.swift +// AllInWidgets +// +// Created by Emre on 01/03/2024. +// + +import WidgetKit +import SwiftUI + +@main +struct AllInWidgetsBundle: WidgetBundle { + var body: some Widget { + AllInCoinsWidget() + AllInWidgetsLiveActivity() + } +} diff --git a/Sources/AllInApp/AllInWidgets/AllInWidgetsLiveActivity.swift b/Sources/AllInApp/AllInWidgets/AllInWidgetsLiveActivity.swift new file mode 100644 index 0000000..9311fa5 --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/AllInWidgetsLiveActivity.swift @@ -0,0 +1,77 @@ +// +// AllInWidgetsLiveActivity.swift +// AllInWidgets +// +// Created by Emre on 01/03/2024. +// + +import ActivityKit +import WidgetKit +import SwiftUI + +struct AllInWidgetsAttributes: ActivityAttributes { + public struct ContentState: Codable, Hashable { + // Dynamic stateful properties about your activity go here! + var value: Int + } + + // Fixed non-changing properties about your activity go here! + var name: String +} + +struct AllInWidgetsLiveActivity: Widget { + var body: some WidgetConfiguration { + ActivityConfiguration(for: AllInWidgetsAttributes.self) { context in + // Lock screen/banner UI goes here + VStack { + Text("Hello") + } + .activityBackgroundTint(Color.cyan) + .activitySystemActionForegroundColor(Color.black) + + } dynamicIsland: { context in + DynamicIsland { + // Expanded UI goes here. Compose the expanded UI through + // various regions, like leading/trailing/center/bottom + DynamicIslandExpandedRegion(.leading) { + Text("Leading") + } + DynamicIslandExpandedRegion(.trailing) { + Text("Trailing") + } + DynamicIslandExpandedRegion(.bottom) { + Text("Bottom") + // more content + } + } compactLeading: { + Text("L") + } compactTrailing: { + Text("T") + } minimal: { + Text("Min") + } + .widgetURL(URL(string: "http://www.apple.com")) + .keylineTint(Color.red) + } + } +} + +struct AllInWidgetsLiveActivity_Previews: PreviewProvider { + static let attributes = AllInWidgetsAttributes(name: "Me") + static let contentState = AllInWidgetsAttributes.ContentState(value: 3) + + static var previews: some View { + attributes + .previewContext(contentState, viewKind: .dynamicIsland(.compact)) + .previewDisplayName("Island Compact") + attributes + .previewContext(contentState, viewKind: .dynamicIsland(.expanded)) + .previewDisplayName("Island Expanded") + attributes + .previewContext(contentState, viewKind: .dynamicIsland(.minimal)) + .previewDisplayName("Minimal") + attributes + .previewContext(contentState, viewKind: .content) + .previewDisplayName("Notification") + } +} diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/AccentColor.colorset/Contents.json b/Sources/AllInApp/AllInWidgets/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..a5ad3f1 --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFB", + "green" : "0x7B", + "red" : "0x7F" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/AppIcon.appiconset/Contents.json b/Sources/AllInApp/AllInWidgets/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..f1a93eb --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,14 @@ +{ + "images" : [ + { + "filename" : "Logo.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/AppIcon.appiconset/Logo.png b/Sources/AllInApp/AllInWidgets/Assets.xcassets/AppIcon.appiconset/Logo.png new file mode 100644 index 0000000..d503a96 Binary files /dev/null and b/Sources/AllInApp/AllInWidgets/Assets.xcassets/AppIcon.appiconset/Logo.png differ diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/BlueAccentColor.colorset/Contents.json b/Sources/AllInApp/AllInWidgets/Assets.xcassets/BlueAccentColor.colorset/Contents.json new file mode 100644 index 0000000..595b3fb --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/Assets.xcassets/BlueAccentColor.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.933", + "green" : "0.624", + "red" : "0.098" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.933", + "green" : "0.624", + "red" : "0.098" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/Contents.json b/Sources/AllInApp/AllInWidgets/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/PinkAccentColor.colorset/Contents.json b/Sources/AllInApp/AllInWidgets/Assets.xcassets/PinkAccentColor.colorset/Contents.json new file mode 100644 index 0000000..1af07a4 --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/Assets.xcassets/PinkAccentColor.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.537", + "green" : "0.165", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.537", + "green" : "0.165", + "red" : "1.000" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/PurpleAccentColor.colorset/Contents.json b/Sources/AllInApp/AllInWidgets/Assets.xcassets/PurpleAccentColor.colorset/Contents.json new file mode 100644 index 0000000..2f0fe01 --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/Assets.xcassets/PurpleAccentColor.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.953", + "green" : "0.490", + "red" : "0.667" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.953", + "green" : "0.490", + "red" : "0.667" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/WidgetBackground.colorset/Contents.json b/Sources/AllInApp/AllInWidgets/Assets.xcassets/WidgetBackground.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/Assets.xcassets/WidgetBackground.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/allcoinIcon.imageset/Contents.json b/Sources/AllInApp/AllInWidgets/Assets.xcassets/allcoinIcon.imageset/Contents.json new file mode 100644 index 0000000..07a60a4 --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/Assets.xcassets/allcoinIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "allcoin.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/allcoinIcon.imageset/allcoin.png b/Sources/AllInApp/AllInWidgets/Assets.xcassets/allcoinIcon.imageset/allcoin.png new file mode 100644 index 0000000..8f13bd2 Binary files /dev/null and b/Sources/AllInApp/AllInWidgets/Assets.xcassets/allcoinIcon.imageset/allcoin.png differ diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/allcoinWhiteIcon.imageset/Contents.json b/Sources/AllInApp/AllInWidgets/Assets.xcassets/allcoinWhiteIcon.imageset/Contents.json new file mode 100644 index 0000000..0159b50 --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/Assets.xcassets/allcoinWhiteIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "allcoinWhite.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/allcoinWhiteIcon.imageset/allcoinWhite.png b/Sources/AllInApp/AllInWidgets/Assets.xcassets/allcoinWhiteIcon.imageset/allcoinWhite.png new file mode 100644 index 0000000..128a9dc Binary files /dev/null and b/Sources/AllInApp/AllInWidgets/Assets.xcassets/allcoinWhiteIcon.imageset/allcoinWhite.png differ diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/launchScreenImage.imageset/Contents.json b/Sources/AllInApp/AllInWidgets/Assets.xcassets/launchScreenImage.imageset/Contents.json new file mode 100644 index 0000000..78fcdbe --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/Assets.xcassets/launchScreenImage.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "launchScreen.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/AllInApp/AllInWidgets/Assets.xcassets/launchScreenImage.imageset/launchScreen.png b/Sources/AllInApp/AllInWidgets/Assets.xcassets/launchScreenImage.imageset/launchScreen.png new file mode 100644 index 0000000..dfdd829 Binary files /dev/null and b/Sources/AllInApp/AllInWidgets/Assets.xcassets/launchScreenImage.imageset/launchScreen.png differ diff --git a/Sources/AllInApp/AllInWidgets/Info.plist b/Sources/AllInApp/AllInWidgets/Info.plist new file mode 100644 index 0000000..0f118fb --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/Info.plist @@ -0,0 +1,11 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.widgetkit-extension + + + diff --git a/Sources/AllInApp/AllInWidgets/Provider.swift b/Sources/AllInApp/AllInWidgets/Provider.swift new file mode 100644 index 0000000..362b938 --- /dev/null +++ b/Sources/AllInApp/AllInWidgets/Provider.swift @@ -0,0 +1,78 @@ +// +// Provider.swift +// AllInWidgetsExtension +// +// Created by Emre on 01/03/2024. +// + +import WidgetKit +import Intents + +let allInApi = "https://codefirst.iut.uca.fr/containers/AllDev-api/" + +struct Provider: IntentTimelineProvider { + + func placeholder(in context: Context) -> User { + User(date: Date()) + } + + func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (User) -> ()) { + var entry = User(date: Date()) + entry.connected = true + entry.username = "toto" + entry.coins = 50000 + completion(entry) + } + + func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline) -> ()) { + let currentDate = Date() + + Task { + if var userData = try? await fetchData() { + userData.date = currentDate + let nextUpdate = Calendar.current.date(byAdding: .minute, value: 5, to: currentDate)! + let timeline = Timeline(entries: [userData], policy: .after(nextUpdate)) + completion(timeline) + } + } + } + + func fetchData() async throws -> User { + let defaults = UserDefaults(suiteName: "group.alldev.AllIn") + + guard let token = defaults?.string(forKey: "authenticationRefresh") else { + return User() + } + + let url = URL(string: allInApi + "users/token")! + var request = URLRequest(url: url) + + request.httpMethod = "GET" + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") + + let (data, response) = try await URLSession.shared.data(for: request) + + if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 { + if let userData = try? JSONDecoder().decode(User.self, from: data) { + var updatedUser = userData + updatedUser.connected = true + return updatedUser + } + } + return User() + } + +} + +struct User: TimelineEntry, Codable { + var date: Date = .init() + var coins: Int = 0 + var username: String = "" + var connected: Bool = false + + enum CodingKeys: String, CodingKey { + case coins = "nbCoins" + case username = "username" + } +} diff --git a/Sources/AllInApp/AllInWidgetsExtension.entitlements b/Sources/AllInApp/AllInWidgetsExtension.entitlements new file mode 100644 index 0000000..0f06eb8 --- /dev/null +++ b/Sources/AllInApp/AllInWidgetsExtension.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.alldev.AllIn + + +