Compare commits

..

No commits in common. 'master' and 'auth_manage' have entirely different histories.

@ -1,20 +0,0 @@
kind: pipeline
type: docker
name: Swift-ALLIN
trigger:
event:
- push
steps:
- name: build
image: swift:latest
commands:
- cd Sources/Model
- swift build
- name: test
image: swift:latest
commands:
- cd Sources/Model
- swift test

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 354 KiB

@ -1,91 +1,3 @@
<div align="center"> # Swift
<img src="Documentation/Images/Banner-AllIn.png" /> Client IOS
---
&nbsp; ![Swift](https://img.shields.io/badge/Swift-F05138.svg?style=for-the-badge&logo=Swift&logoColor=white)
&nbsp; ![iOS](https://img.shields.io/badge/iOS-000000.svg?style=for-the-badge&logo=Apple&logoColor=white)
---
[Présentation](#apple---all-in) | [Répartition du dépôt](#répartition-du-gitlab) | [Structures](#structures) | [Technologies](#technologies) | [Outils](#outils) | [Wiki](https://codefirst.iut.uca.fr/git/AllDev/Gestion_de_projet/wiki)
</div>
### Apple - ALL IN!
**Contexte** : Application Swift et SwiftUI pour le projet universitaire de troisième année (B.U.T Informatique de Clermont-Ferrand) intitulé *All In*.
</br>
**Description** : Ce dépôt contient l'ensemble du code pour la partie client iOS de l'application *ALL IN*.
</br>
# Répartition du dépot
[**Sources**](Sources) : **Code de l'application**
[**Documentation**](Documentation) : **Documentation de l'application**
# Structures
- MVVM
<div align = center>
<img src="https://codefirst.iut.uca.fr/git/AllDev/Gestion_de_projet/raw/branch/master/Documentation/Diagrammes/AllInMVVM.png" width="600" />
</div>
# Fonctionnement
- ### Comment lancer le projet ?
:information_source: *Assurez-vous d'avoir un Mac à disposition*
Tout d'abord si ce n'est pas fait cloner le dépôt de la branche **master/main**, pour cela copier le lien URL du dépôt git :
<div align = center>
![Comment cloner](Documentation/Images/HowToClone.png)
</div>
Sur votre Mac, ouvrez l'IDE **Xcode** (disponible via l'App Store), puis cloner le dépôt en utilisant l'URL copiée précédemment :
<div align = center>
<img src="Documentation/Images/WelcomeToXcode.png" width="500" >
</div>
Vous serez alors redirigé par l'IDE et pourrez lancer l'application sur l'appareil de votre choix :
<div align = center>
<img src="Documentation/Images/LaunchApp.png" width="900" >
</div>
*Si vous souhaitez lancer l'application sur votre appareil personnel, il sera nécessaire de renseigner votre compte iCloud dans l'IDE !*
# Technologies
<img src="" />
Pour réaliser l'interface visuelle, nous avons opté pour **SwiftUI** du fait qu'elle permet de réaliser des interfaces utilisateurs complexes de manière élégante. Le framework est récent, mis à jour régulièrement, et facile à prendre en main pour le développement.
# Outils
Pour la partie API, nous avons utilisé plusieurs outils :
- UserDefaults
Pour stocker le token localement, nous utilisons l'outil fourni par SwiftUI qui est UserDefaults, afin de réaliser une authentification automatique lorsque le client ouvre l'application, en récupérant son token lors de la précédente connexion.
<div align="center">
© AllDev - Apple
</div>

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:StubLib">
</FileRef>
<FileRef
location = "group:Api">
</FileRef>
<FileRef
location = "group:AllInApp/AllInApp.xcodeproj">
</FileRef>
<FileRef
location = "group:DependencyInjection/DependencyInjection.xcodeproj">
</FileRef>
<FileRef
location = "group:Model">
</FileRef>
</Workspace>

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array/>
</dict>
</plist>

@ -1,39 +0,0 @@
//
// AllInApp.swift
// AllIn
//
// Created by Emre on 19/09/2023.
//
import SwiftUI
import DependencyInjection
import Model
@main
struct AllInApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@Environment(\.scenePhase) var phase
let DI = DependencyInjection.shared
init() {
DI.addSingleton(IAuthService.self, AuthService())
}
var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
AppStateContainer.shared.notificationState.scheduleNotifications()
}
.onChange(of: phase) { newPhase in
switch newPhase {
case .background, .inactive:
UIApplication.shared.shortcutItems = QuickAction.allShortcutItems
default:
break
}
}
}
}
}

@ -1,27 +0,0 @@
//
// AppState.swift
// AllIn
//
// Created by Emre on 17/12/2023.
//
import SwiftUI
import Model
class AppStateContainer: ObservableObject {
static let shared = AppStateContainer()
let loggedState: LoggedState = LoggedState()
var onlineStatus: OnlineStatus = OnlineStatus()
var notificationState: NotificationService = NotificationService()
@Published var user: User?
@AppStorage("authenticationRefresh", store: UserDefaults(suiteName: "group.alldev.AllIn")!) var authenticationRefresh: String?
}
class LoggedState: ObservableObject {
@Published var connectedUser: Bool = false
}
class OnlineStatus: ObservableObject {
@Published var isOnline: Bool = true
}

@ -1,38 +0,0 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x24",
"green" : "0x24",
"red" : "0x24"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x24",
"green" : "0x24",
"red" : "0x24"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,38 +0,0 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xEC",
"green" : "0xE8",
"red" : "0x00"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xEC",
"green" : "0xE8",
"red" : "0x00"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,38 +0,0 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xC5",
"green" : "0x66",
"red" : "0x8A"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xC5",
"green" : "0x66",
"red" : "0x8A"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

@ -1,38 +0,0 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xE9",
"green" : "0xDE",
"red" : "0xC4"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xE9",
"green" : "0xDE",
"red" : "0xC4"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "allcoinWhite.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "Group 107 (1).png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 986 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "Group 179.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 832 B

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "Group 210.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "chevronDown.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "chevronRight.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "chevronUp.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "Exclude (1).png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "defaultUser.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "football.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "friends.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "gear.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "GiftEarn.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "Gift.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "globe.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "globePurple.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "launchScreen.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "Group 280.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "lock.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "lockPurple.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "Mask group (3).png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 MiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "background.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "money.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "paintbrush.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "PinkAllCoin.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 693 B

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "PinkBadge.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1008 B

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "pinkFlame.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "UserPink.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 843 B

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "Trophy.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 975 B

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "questionMarkGrey.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "questionMark.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "Trophy.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

@ -1,22 +0,0 @@
{
"images" : [
{
"filename" : "threeLines 1.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "threeLines.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "videoGame.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,21 +0,0 @@
{
"images" : [
{
"filename" : "WelcomeBackground.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -1,36 +0,0 @@
//
// AllcoinsCount.swift
// AllIn
//
// Created by Lucas on 28/09/2023.
//
import SwiftUI
struct AllcoinsCapsule: View {
var gains: Int
var body: some View {
Text("Vous remportez")
.foregroundColor(.white)
HStack{
Text(gains.description)
.textStyle(weight: .bold, color: .white, size: 60)
Image("allcoinWhiteIcon")
.resizable()
.frame(width: 40, height:40)
.scaledToFit()
}
.padding([.leading,.trailing],30)
.padding([.top,.bottom],10)
.background(.white.opacity(0.09))
.cornerRadius(999, corners: .allCorners)
.clipShape(Capsule())
.overlay(RoundedRectangle(cornerRadius: 999).stroke(.white, lineWidth: 1.5))
}
}
struct AllcoinsCapsule_Previews: PreviewProvider {
static var previews: some View {
AllcoinsCapsule(gains: 100)
}
}

@ -1,37 +0,0 @@
//
// AllcoinsCounter.swift
// AllIn
//
// Created by Emre on 20/09/2023.
//
import SwiftUI
struct AllcoinsCounter: View {
var backgroundColor: Color = .white
var foregroundColor: Color = AllInColors.primaryColor
@ObservedObject var appStateContainer = AppStateContainer.shared
var body: some View {
HStack(alignment: .center) {
Text(String(appStateContainer.user!.nbCoins))
.contentTransition(.numericText())
.fontWeight(.black)
.foregroundColor(foregroundColor)
Image("allcoinIcon")
.resizable()
.frame(width: 17, height: 17, alignment: .leading)
}
.frame(width: 90, height: 40)
.background(backgroundColor)
.cornerRadius(9999, corners: [.topLeft, .bottomLeft])
}
}
struct AllcoinsCounter_Previews: PreviewProvider {
static var previews: some View {
AllcoinsCounter()
}
}

@ -1,86 +0,0 @@
//
// BetCard.swift
// AllIn
//
// Created by Lucas on 24/09/2023.
//
import SwiftUI
import Model
struct BetCard: View {
var bet: Bet
@State var showDetails: Bool = false
@State var showParticipate: Bool = false
var body: some View {
VStack(spacing: 0) {
VStack(alignment: .leading,spacing: 2){
HStack{
Spacer()
Text("bet_proposed_by_format \(bet.author.capitalized)")
.font(.system(size: 10))
.foregroundColor(AllInColors.grey800Color)
}
Text(bet.theme)
.font(.system(size: 15))
.foregroundColor(AllInColors.grey800Color)
Text(bet.phrase)
.font(.system(size: 20))
.fontWeight(.bold)
HStack{
Text("bet_starting")
.font(.system(size: 15))
.foregroundColor(AllInColors.grey800Color)
TextCapsule(date: bet.endRegisterDate)
Spacer()
}
}
.frame(width: .infinity)
.padding(.all,15)
.background(AllInColors.componentBackgroundColor).cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0)
VStack(alignment: .leading,spacing: 2){
HStack{
Spacer()
UsersPreview(users: [])
Text("bet_players_waiting_format \(bet.invited.count.description)")
.font(.system(size: 15))
.foregroundColor(AllInColors.grey800Color)
.fontWeight(.medium)
Spacer()
}
.padding(0)
ParticipateButton(isOpen: $showDetails, isParticapatedOpen: $showParticipate, bet: bet)
.padding(.top, 5)
}
.frame(width: .infinity)
.padding(.all,8)
.background(AllInColors.underComponentBackgroundColor)
.cornerRadius(20, corners: [.bottomLeft,.bottomRight])
.border(width: 1, edges: [.top], color: AllInColors.delimiterGrey)
}
.onTapGesture {
showDetails.toggle()
}
.fullScreenCover(isPresented: $showDetails) {
DetailsView(isModalPresented: $showDetails, isModalParticipated: $showParticipate, id: bet.id)
}
}
}
struct BetCard_Previews: PreviewProvider {
static var previews: some View {
BetCard(bet: BinaryBet(theme: "Football - Finale de la Ligue des Champions",
phrase: "Le gagnant de la finale sera l'équipe avec le plus de tirs au but.",
endRegisterDate: Date().addingTimeInterval(86400),
endBetDate: Date().addingTimeInterval(172800),
isPrivate: false,
status: .inProgress,
invited: [],
author: "Imri"))
.preferredColorScheme(.dark)
}
}

@ -1,47 +0,0 @@
//
// BetLineLoading.swift
// AllIn
//
// Created by Lucas Delanier on 19/01/2024.
//
import SwiftUI
import Model
struct BetLineLoading: View {
@State var showInfos: Bool = false
var bet: BetDetail
var value: CGFloat {
let totalParticipations = bet.participations.count
let numberOfYes = bet.participations.filter { $0.answer.uppercased() == "YES" }.count
let numberOfNo = bet.participations.filter { $0.answer.uppercased() == "NO" }.count
if(numberOfNo == 0 && numberOfYes == 0){
return 0.5
}
return totalParticipations > 0 ? CGFloat(numberOfYes) / CGFloat(totalParticipations) : 0.0
}
var yesParticipations: [Participation] {
bet.participations.filter { $0.answer.uppercased() == "YES" }
}
var noParticipations: [Participation] {
bet.participations.filter { $0.answer.uppercased() == "NO" }
}
var body: some View {
switch bet.bet {
case is BinaryBet:
BinaryBetLine(bet: bet)
case is CustomBet:
CustomBetLine(bet: bet)
default:
BinaryBetLine(bet: bet)
}
}
}

@ -1,168 +0,0 @@
//
// BinaryBetLine.swift
// AllIn
//
// Created by Lucas Delanier on 10/06/2024.
//
import SwiftUI
import Model
struct BinaryBetLine: View {
@State var showInfos: Bool = false
var bet: BetDetail
var value: CGFloat {
let totalParticipations = bet.participations.count
let numberOfYes = bet.participations.filter { $0.answer.uppercased() == "YES" }.count
let numberOfNo = bet.participations.filter { $0.answer.uppercased() == "NO" }.count
if(numberOfNo == 0 && numberOfYes == 0){
return 0.5
}
return totalParticipations > 0 ? CGFloat(numberOfYes) / CGFloat(totalParticipations) : 0.0
}
var yesParticipations: [Participation] {
bet.participations.filter { $0.answer.uppercased() == "YES" }
}
var noParticipations: [Participation] {
bet.participations.filter { $0.answer.uppercased() == "NO" }
}
var body: some View {
VStack(alignment: .leading, spacing: 0) {
HStack(spacing: 5) {
Text("OUI")
.font(.system(size: 25))
.fontWeight(.bold)
.foregroundColor(AllInColors.blue200)
Spacer()
Text("NON")
.font(.system(size: 25))
.fontWeight(.bold)
.foregroundColor(AllInColors.pink100)
}
GeometryReader { geometry in
ZStack(alignment: .leading) {
HStack{
Spacer()
Rectangle()
.frame(width: min(CGFloat(1-self.value) * geometry.size.width, geometry.size.width-20), height: 17)
.foregroundStyle(AllInColors.PinkBetGradiant).cornerRadius(999)
}
HStack(spacing: 0) {
Rectangle()
.frame(width: min(CGFloat(self.value) * geometry.size.width, geometry.size.width-20), height: 17)
.foregroundStyle(AllInColors.BlueBetGradiant)
.cornerRadius(999)
Image("loadingHeartIcon")
.resizable()
.frame(width: 29, height: 32)
.padding(.leading, -10)
}
}
.padding(.bottom, 5)
}
.frame(height: 40)
HStack {
Spacer()
Text("bet_status_details_drawer")
.textStyle(weight: .medium, color: AllInColors.primaryTextColor, size: 10)
Image(showInfos ? "chevronUpIcon" : "chevronDownIcon")
.resizable()
.frame(width: 10, height: 7)
.scaledToFill()
}
.onTapGesture {
withAnimation {
showInfos.toggle()
}
}
.padding(.bottom, 5)
.padding(.trailing, 5)
if showInfos {
VStack(spacing: 1) {
HStack(spacing: 5) {
Image("blueAllCoinIcon")
.resizable()
.frame(width:12, height: 12)
Text(yesParticipations.reduce(0, {x,y in x + y.stake}).description)
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundColor(AllInColors.blue200)
Spacer()
Text(noParticipations.reduce(0, {x,y in x + y.stake}).description)
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundColor(AllInColors.pink100)
Image("pinkAllCoinIcon")
.resizable()
.frame(width: 12, height: 12)
}
HStack(spacing: 5){
Image("bluePersonIcon")
.resizable()
.frame(width: 12, height: 12)
Text(yesParticipations.count.description)
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundColor(AllInColors.blue200)
Spacer()
Text(noParticipations.count.description)
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundColor(AllInColors.pink100)
Image("pinkPersonIcon")
.resizable()
.frame(width: 12, height: 12)
}
HStack(spacing: 5){
Image("blueBadgeIcon")
.resizable()
.frame(width: 12, height: 12)
Text(yesParticipations.max(by: { $0.stake < $1.stake })?.stake.description ?? "0")
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundColor(AllInColors.blue200)
Spacer()
Text(noParticipations.max(by: { $0.stake < $1.stake })?.stake.description ?? "0")
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundColor(AllInColors.pink100)
Image("pinkBadgeIcon")
.resizable()
.frame(width: 12, height: 12)
}
HStack(spacing: 5){
Image("blueTrophyIcon")
.resizable()
.frame(width: 12, height: 12)
Text("1.2")
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundColor(AllInColors.blue200)
Spacer()
Text("1.2")
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundColor(AllInColors.pink100)
Image("pinkTrophyIcon")
.resizable()
.frame(width:12, height: 12)
}
}
}
}
}
}

@ -1,63 +0,0 @@
//
// ChoiceCapsule.swift
// AllIn
//
// Created by Lucas on 26/09/2023.
//
import SwiftUI
import Model
struct ChoiceCapsule: View {
let filter: BetFilter
@State var pressed = false
@ObservedObject var viewModel: BetViewModel
var label: String {
switch filter {
case .isPublic:
return String(localized: "bet_public")
case .isInvitation:
return String(localized: "bet_invitation")
case .inProgress:
return String(localized: "bet_current")
case .isFinished:
return String(localized: "bet_finished")
default:
return "NaN"
}
}
var body: some View {
Group {
if(pressed) {
Text(label)
.textStyle(weight: .semibold, color: .white, size: 15)
.padding([.leading,.trailing],13.8)
.padding([.top,.bottom], 7)
.background(AllInColors.lightPurpleColor)
.clipShape(Capsule())
} else {
Text(label)
.textStyle(weight: .regular, color: AllInColors.grey800Color, size: 15)
.padding([.leading,.trailing], 15)
.padding([.top,.bottom], 7)
.background(AllInColors.underComponentBackgroundColor)
.clipShape(Capsule())
.overlay(
RoundedRectangle(cornerRadius: 20)
.stroke(AllInColors.delimiterGrey, lineWidth: 1)
)
}
}
.onTapGesture() {
pressed.toggle()
if(pressed) {
viewModel.filters.insert(filter)
} else {
viewModel.filters.remove(filter)
}
}
}
}

@ -1,43 +0,0 @@
//
// ChoiceFinalAnswerCell.swift
// AllIn
//
// Created by Lucas Delanier on 29/01/2024.
//
import Foundation
import SwiftUI
import Model
struct ChoiceFinalAnswerCell: View {
var selected = false
var answer: AnswerDetail
var rawColor = AllInColors.blueAccentColor
var body: some View {
ZStack {
HStack {
Spacer()
Text(answer.response)
.textStyle(weight: .bold, color: selected ? .white : rawColor, size: 40)
.padding(.vertical, 10)
Spacer()
}
HStack {
Spacer()
OddCapsule(
backgroundColor: selected ? .white : AllInColors.purpleAccentColor,
foregroundColor: selected ? AllInColors.purpleAccentColor : .white,
odd: answer.odds
)
.padding(.trailing, 20)
.scaleEffect(0.9)
}
}
.background(selected ? AllInColors.purpleAccentColor : .white)
.cornerRadius(17)
.scaleEffect(selected ? 1.02 : 1)
.animation(.easeInOut(duration: 0.3), value: selected)
}
}

@ -1,38 +0,0 @@
//
// ConfidentialityButton.swift
// AllIn
//
// Created by Emre on 29/09/2023.
//
import SwiftUI
struct ConfidentialityButton: View {
var image: String
var text: String
var selected: Bool
var body: some View {
HStack() {
Image(selected ? image + "Icon" : image + "PurpleIcon")
.resizable()
.scaledToFit()
.padding(.vertical, 12)
Text(text)
.font(.system(size: 17))
.fontWeight(.bold)
.foregroundColor(selected ? .white : AllInColors.lightPurpleColor)
}
.frame(width: 110, height: 45)
.background(selected ? AllInColors.lightPurpleColor : AllInColors.componentBackgroundColor)
.cornerRadius(10)
}
}
struct ConfidentialityButton_Previews: PreviewProvider {
static var previews: some View {
ConfidentialityButton(image: "lock", text: "Privé", selected: true)
}
}

@ -1,141 +0,0 @@
//
// CustomBetLine.swift
// AllIn
//
// Created by Lucas Delanier on 10/06/2024.
//
import SwiftUI
import Model
struct CustomBetLine: View {
@State var showInfos: [String: Bool] = [:]
var bet: BetDetail
var participationsForAnswer: [String: [Participation]] {
Dictionary(grouping: bet.participations, by: { $0.answer.uppercased() })
}
var sortedAnswers: [AnswerDetail] {
bet.answers.sorted { $0.totalParticipants > $1.totalParticipants }
}
func getTextStyle(for answer: AnswerDetail) -> Font.Weight {
return answer == sortedAnswers.first ? .bold : .light
}
func getColor(for answer: AnswerDetail) -> Color {
return answer == sortedAnswers.first ? AllInColors.pinkAccentColor : AllInColors.blueAccentColor
}
func getGradiant(for answer: AnswerDetail) -> LinearGradient {
return answer == sortedAnswers.first ? AllInColors.PinkBetGradiant : AllInColors.BlueBetLineGradiant
}
func getFlameImage(for answer: AnswerDetail) -> String {
return answer == sortedAnswers.first ? "pinkFlameIcon" : "blueFlameIcon"
}
var body: some View {
VStack(alignment: .leading, spacing: 0) {
ForEach(sortedAnswers, id: \.response) { answer in
let participations = participationsForAnswer[answer.response.uppercased()] ?? []
let totalParticipations = bet.participations.count
let percentage = totalParticipations > 0 ? CGFloat(participations.count) / CGFloat(totalParticipations) : 0.0
VStack {
HStack {
Text(answer.response)
.font(.system(size: 15))
.fontWeight(getTextStyle(for: answer))
.foregroundColor(getColor(for: answer))
Spacer()
}
GeometryReader { geometry in
ZStack(alignment: .leading) {
HStack(spacing: 0) {
Rectangle()
.frame(width: min(percentage * geometry.size.width, geometry.size.width-20), height: 17)
.foregroundStyle(getGradiant(for: answer))
.cornerRadius(999, corners: [.topLeft, .bottomLeft])
Image(getFlameImage(for: answer))
.resizable()
.frame(width: 29, height: 32)
.padding(.leading, -6)
Text("\(Int(percentage * 100))%")
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundStyle(getColor(for: answer))
.padding(.leading, 2)
}
}
.padding(.bottom, 5)
}
.frame(height: 40)
HStack {
Spacer()
Text("bet_status_details_drawer")
.textStyle(weight: .medium, color: AllInColors.primaryTextColor, size: 10)
Image(showInfos[answer.response] ?? false ? "chevronUpIcon" : "chevronDownIcon")
.resizable()
.frame(width: 10, height: 7)
.scaledToFill()
}
.onTapGesture {
withAnimation {
showInfos[answer.response, default: false].toggle()
}
}
.padding(.trailing, 5)
if showInfos[answer.response] ?? false {
HStack{
VStack(alignment: .leading,spacing: 1) {
HStack(spacing: 5) {
Image(answer == sortedAnswers.first ? "pinkAllCoinIcon" : "blueAllCoinIcon")
.resizable()
.frame(width: 12, height: 12)
Text(participations.reduce(0, { x, y in x + y.stake }).description)
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundColor(getColor(for: answer))
}
HStack(spacing: 5) {
Image(answer == sortedAnswers.first ? "pinkPersonIcon" : "bluePersonIcon")
.resizable()
.frame(width: 12, height: 12)
Text(participations.count.description)
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundColor(getColor(for: answer))
}
HStack(spacing: 5) {
Image(answer == sortedAnswers.first ? "pinkBadgeIcon" : "blueBadgeIcon")
.resizable()
.frame(width: 12, height: 12)
Text(participations.max(by: { $0.stake < $1.stake })?.stake.description ?? "0")
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundColor(getColor(for: answer))
}
HStack(spacing: 5) {
Image(answer == sortedAnswers.first ? "pinkTrophyIcon" : "blueTrophyIcon")
.resizable()
.frame(width: 12, height: 12)
Text(String(format: "%.2f", answer.odds))
.font(.system(size: 15))
.fontWeight(.bold)
.foregroundColor(getColor(for: answer))
}
}
Spacer()
}
}
}
}
}
}
}

@ -1,66 +0,0 @@
//
// DropDownMenu.swift
// AllIn
//
// Created by Emre on 19/10/2023.
//
import SwiftUI
import Model
struct DropDownAnswerMenu: View {
@State var expand = false
@Binding var selectedAnswer: AnswerDetail
var answers: [AnswerDetail]
var body: some View {
VStack(spacing: 0, content: {
Button(action: { withTransaction(Transaction(animation: nil)) { self.expand.toggle() } }) {
HStack{
Text(selectedAnswer.response)
.textStyle(weight: .bold, color: AllInColors.blueAccentColor, size: 20)
Text("\(selectedAnswer.odds, specifier: "%.2f")")
.textStyle(weight: .bold, color: AllInColors.lightPurpleColor, size: 10)
Spacer()
Image(expand ? "chevronUpIcon" : "chevronDownIcon").resizable().frame(width: 15, height: 10).scaledToFill()
}
.padding([.leading, .trailing], 15)
.frame(height: 43)
}
if expand {
Rectangle()
.frame(height: 1)
.foregroundColor(AllInColors.delimiterGrey)
.padding(.bottom, 18)
VStack(spacing: 0) {
ForEach(answers) { (answer: AnswerDetail) in
if answer != selectedAnswer {
Button(action: {
self.selectedAnswer = answer
self.expand.toggle()}
) {
HStack{
Text(answer.response)
.textStyle(weight: .bold, color: AllInColors.blueAccentColor, size: 20)
Text("\(answer.odds, specifier: "%.2f")")
.textStyle(weight: .bold, color: AllInColors.lightPurpleColor, size: 10)
Spacer()
}
}
.padding(.bottom, 15)
}
}
}
.padding([.leading, .trailing], 15)
}
})
.background(AllInColors.componentBackgroundColor)
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 8, style: .continuous)
.stroke(AllInColors.veryLightPurpleColor, lineWidth: 0.4)
)
}
}

@ -1,86 +0,0 @@
//
// DropDownFriends.swift
// AllIn
//
// Created by Emre on 16/12/2023.
//
import SwiftUI
import Model
struct DropDownFriends: View {
@Binding var selectedItems: Set<String>
@State var expand = false
var friends: [User]
var body: some View {
VStack(spacing: 0, content: {
Button(action: { self.expand.toggle() }) {
HStack(spacing: 3){
Text(friends.count.description)
.textStyle(weight: .bold, color: AllInColors.primaryTextColor, size: 15)
Text("bet_creation_friends_available_format")
.textStyle(weight: .regular, color: AllInColors.grey800Color, size: 15)
Spacer()
Image(expand ? "chevronUpIcon" : "chevronDownIcon").resizable().frame(width: 15, height: 7).scaledToFill()
}
.padding([.leading, .trailing], 15)
.padding(.top, 5)
.frame(height: 43)
}
if expand {
Rectangle()
.frame(height: 1)
.foregroundColor(AllInColors.delimiterGrey)
ScrollView(.vertical) {
VStack(spacing: 0) {
ForEach(friends, id: \.self) { (friend: User) in
HStack {
Circle()
.fill(selectedItems.contains(friend.id) ? AllInColors.lightPurpleColor : Color.clear)
.overlay(
Circle()
.stroke(selectedItems.contains(friend.id) ? Color.clear : AllInColors.skyBlueColor, lineWidth: 1)
)
.frame(width: 15, height: 15)
.padding(.trailing, 5)
UserInfo(username: friend.username, value: friend.nbCoins)
.contentShape(Rectangle())
}
.padding([.leading, .trailing], 15)
.padding([.top, .bottom], 5)
.overlay(
selectedItems.contains(friend.id) ?
Rectangle()
.fill(AllInColors.lightPurpleColor.opacity(0.13))
: nil
)
.opacity(1.0)
.onTapGesture {
if selectedItems.contains(friend.id) {
selectedItems.remove(friend.id)
} else {
selectedItems.insert(friend.id)
}
}
Rectangle()
.frame(height: 1)
.foregroundColor(AllInColors.delimiterGrey)
}
}
}
.frame(height: 180)
}
})
.frame(width: 345)
.background(AllInColors.componentBackgroundColor)
.cornerRadius(10)
.overlay(
RoundedRectangle(cornerRadius: 10, style: .continuous)
.stroke(AllInColors.veryLightPurpleColor, lineWidth: 0.4)
)
}
}

@ -1,75 +0,0 @@
//
// DropDownMenu.swift
// AllIn
//
// Created by Emre on 19/10/2023.
//
import SwiftUI
struct DropDownMenu: View {
@State var expand = false
@Binding var selectedOption: Int
var options: [(Int, String, String)]
var body: some View {
VStack(spacing: 0, content: {
Button(action: { self.expand.toggle() }) {
HStack{
Image(options[selectedOption].1)
.resizable()
.scaledToFit()
.frame(width: 15, height: 15)
Text(options[selectedOption].2)
.textStyle(weight: .bold, color: AllInColors.lightPurpleColor, size: 15)
Spacer()
Image(expand ? "chevronUpIcon" : "chevronDownIcon").resizable().frame(width: 15, height: 10).scaledToFill()
}
.padding([.leading, .trailing], 15)
.frame(height: 43)
}
if expand {
Rectangle()
.frame(height: 1)
.foregroundColor(AllInColors.delimiterGrey)
.padding(.bottom, 18)
VStack(spacing: 0) {
ForEach(0..<options.count, id: \.self) { index in
if options[index].0 != selectedOption {
Button(action: {self.selectedOption = options[index].0
self.expand.toggle()}) {
HStack{
Image(options[index].1)
.resizable()
.scaledToFit()
.frame(width: 15, height: 15)
Text(options[index].2)
.textStyle(weight: .bold, color: AllInColors.lightPurpleColor, size: 15)
Spacer()
}
}
.padding(.bottom, 15)
}
}
}
.padding([.leading, .trailing], 15)
}
})
.frame(width: 345)
.background(AllInColors.componentBackgroundColor)
.cornerRadius(10)
}
}
struct DropDownMenu_Previews: PreviewProvider {
static var previews: some View {
DropDownMenu(selectedOption: .constant(0), options: [
(0, "questionMarkIcon", "Oui / Non"),
(1, "footballIcon", "Pari sportif"),
(2, "paintbrushIcon", "Réponses personnalisées")
])
.preferredColorScheme(.dark)
}
}

@ -1,27 +0,0 @@
//
// EmptyInfo.swift
// AllIn
//
// Created by Lucas Delanier on 29/05/2024.
//
import SwiftUI
struct EmptyInfo: View {
let emoji: String
let title: String
let explain: String
var body: some View {
VStack{
Text(emoji).font(.system(size: 120))
Text(title).textStyle(weight: .bold, color: AllInColors.primaryTextColor , size: 15)
explain.isEmpty ? nil : Text(explain).textStyle(weight: .light, color: .gray, size: 12)
}.opacity(0.55).padding(.horizontal, 20).multilineTextAlignment(.center)
}
}
struct EmptyInfo_Previews: PreviewProvider {
static var previews: some View {
EmptyInfo(emoji:"👥", title: "Vous navez pas encore damis", explain: "Ajoutez les depuis cet écran")
}
}

@ -1,59 +0,0 @@
//
// Friend.swift
// AllIn
//
// Created by Emre on 27/09/2023.
//
import SwiftUI
import Model
struct Friend: View {
var user: User
let isRequest: Bool
@ObservedObject var viewModel: FriendsViewModel
var StatusValues: (String, Color, Color) {
switch user.friendStatus {
case .friend:
return isRequest ? (String(localized: "generic_decline"), AllInColors.grey400Color, AllInColors.componentBackgroundColor) : (String(localized: "generic_delete"), AllInColors.grey400Color, AllInColors.componentBackgroundColor)
case .notFriend:
return isRequest ? (String(localized: "generic_acccept"), .white, AllInColors.lightPurpleColor) : (String(localized: "generic_add"), .white, AllInColors.lightPurpleColor)
case .requested:
return (String(localized: "friends_request_sent"), AllInColors.grey400Color, AllInColors.componentBackgroundColor)
default:
return ("NaN", AllInColors.grey400Color, AllInColors.componentBackgroundColor)
}
}
var body: some View {
HStack{
UserPicture(picture: user.image,username: user.username, size: 45)
Text(user.username)
.fontWeight(.medium)
.padding(.leading, 5)
.font(.system(size: 18))
.lineLimit(1)
Spacer()
Button(StatusValues.0) {
viewModel.toggleFriendStatus(for: user, isRequest: isRequest)
}
.minimumScaleFactor(0.3)
.lineLimit(2)
.frame(width: 90, height: 30)
.foregroundColor(StatusValues.1)
.font(.system(size: 14))
.background(StatusValues.2)
.cornerRadius(5)
if(isRequest){
Button{
viewModel.declineRequest(username: user.username)
}label: {
Image(systemName: "xmark").foregroundColor(.gray)
}.padding([.leading], 25)
}
}
.padding([.trailing,.leading], 25)
}
}

@ -1,117 +0,0 @@
//
// Menu.swift
// AllIn
//
// Created by Emre on 21/09/2023.
//
import SwiftUI
import DependencyInjection
struct Menu: View {
@Inject var authService: IAuthService
let parameters: [(String, String, String, String)] = [
("videoGameImage", String(localized: "drawer_create_a_bet"), String(localized: "drawer_create_a_bet_subtitle"), "CreationBet"),
("globeImage", String(localized: "drawer_public_bets"), String(localized: "drawer_public_bets_subtitle"), "Bet"),
("moneyImage", String(localized: "drawer_current_bets"), String(localized: "drawer_current_bets_subtitle"), "Current"),
("eyesImage", String(localized: "drawer_bet_history"), String(localized: "drawer_bet_history_subtitle"),"Historic"),
("friendsImage", String(localized: "drawer_friends"), String(localized: "drawer_friends_subtitle"), "Friends"),
("rankingImage", String(localized: "drawer_ranking"), String(localized: "drawer_ranking_subtitle"), "Ranking"),
]
var body: some View {
VStack(alignment: .leading, spacing: 10) {
HStack() {
Spacer()
VStack(){
UserPicture(picture: AppStateContainer.shared.user?.image, username: (AppStateContainer.shared.user?.username)!,size: 100)
Text(AppStateContainer.shared.user?.username.capitalized ?? "")
.fontWeight(.medium)
.font(.system(size: 17))
.foregroundColor(.white)
}
Spacer()
}
.padding(.bottom, 10)
HStack(spacing: 30) {
Spacer()
VStack(){
Text(AppStateContainer.shared.user?.bestWin ?? 0, format: .number)
.fontWeight(.heavy)
.font(.system(size: 15))
.foregroundColor(.white)
Text(String(localized: "drawer_bets"))
.fontWeight(.regular)
.font(.system(size: 12))
.foregroundColor(AllInColors.grey600Color)
}
VStack(){
Text(AppStateContainer.shared.user!.bestWin, format: .number)
.fontWeight(.heavy)
.font(.system(size: 15))
.foregroundColor(.white)
Text(String(localized: "drawer_best_win"))
.fontWeight(.regular)
.font(.system(size: 12))
.foregroundColor(AllInColors.grey600Color)
}
VStack(){
Text(AppStateContainer.shared.user!.nbFriends, format: .number)
.fontWeight(.heavy)
.font(.system(size: 15))
.foregroundColor(.white)
Text(String(localized: "drawer_nb_friends"))
.fontWeight(.regular)
.font(.system(size: 12))
.foregroundColor(AllInColors.grey600Color)
}
Spacer()
}
.padding(.bottom, 15)
ForEach(0..<parameters.count, id: \.self) { index in
NavigationLink(destination: MainView(page: parameters[index].3).navigationBarBackButtonHidden(true)) {
ParameterMenu(image: parameters[index].0, title: parameters[index].1, description: parameters[index].2)
.padding([.leading, .trailing], 13)
}
}
HStack {
Spacer()
Button {
authService.logout()
} label: {
Text("generic_logout")
.foregroundColor(.white)
}
Spacer()
}
Spacer()
NavigationLink(destination: MainView(page: "Profile")
.navigationBarBackButtonHidden(true))
{
Image("gearIcon")
.resizable()
.frame(width: 30, height: 30)
.padding([.leading,.bottom], 20)
}
}
.frame(maxWidth: .infinity,alignment: .leading)
.background(AllInColors.primaryColor)
.edgesIgnoringSafeArea(.bottom)
.onAppear {
authService.refreshAuthentication()
}
}
}
struct Menu_Previews: PreviewProvider {
static var previews: some View {
Menu()
}
}

@ -1,33 +0,0 @@
//
// OddCapsule.swift
// AllIn
//
// Created by Lucas Delanier on 03/02/2024.
//
import Foundation
import SwiftUI
struct OddCapsule: View {
var backgroundColor: Color = AllInColors.purpleAccentColor
var foregroundColor: Color = AllInColors.whiteColor
var odd: Float = 0.0
var body: some View {
HStack(alignment: .center) {
Text("x\(odd, specifier: "%.2f")")
.fontWeight(.bold)
.foregroundColor(foregroundColor)
}
.padding(.horizontal, 10)
.padding(.vertical,5)
.background(backgroundColor)
.cornerRadius(9999)
}
}
struct OddCapsule_Previews: PreviewProvider {
static var previews: some View {
OddCapsule()
}
}

@ -1,49 +0,0 @@
//
// ParameterMenu.swift
// AllIn
//
// Created by Emre on 21/09/2023.
//
import SwiftUI
struct ParameterMenu: View {
var image: String
var title: String
var description: String
var body: some View {
HStack {
Image(image)
.resizable()
.frame(width: 28, height: 28)
VStack(alignment: .leading){
Text(title)
.textStyle(weight: .bold, color: .white, size: 14)
Text(description)
.textStyle(weight: .regular, color: AllInColors.grey600Color, size: 9)
.lineLimit(1)
}
Spacer()
Image("chevronRightIcon")
.resizable()
.frame(width: 10, height: 18)
}
.padding([.leading,.trailing], 10)
.padding([.top,.bottom], 15)
.background(AllInColors.grey50Color)
.overlay(
RoundedRectangle(cornerRadius: 12, style: .continuous)
.stroke(AllInColors.grey100Color, lineWidth: 3)
)
.clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
}
}
struct ParameterMenu_Previews: PreviewProvider {
static var previews: some View {
ParameterMenu(image: "eyesImage", title: "HISTORIQUE DES BETS", description: "Consultez vos paris en cours et terminés.")
}
}

@ -1,72 +0,0 @@
//
// ParticipateButton.swift
// AllIn
//
// Created by Lucas Delanier on 15/01/2024.
//
import SwiftUI
import Model
struct ParticipateButton: View {
@Binding var isOpen : Bool
@Binding var isParticapatedOpen: Bool
var bet: Bet?
var isDisabled: Bool {
guard bet?.author != AppStateContainer.shared.user?.username else { return true }
if let betType = bet?.status {
switch betType {
case .inProgress:
return false
default:
return true
}
} else {
return true
}
}
var body: some View {
Button {
isOpen = true
isParticapatedOpen = true
} label: {
Text("bet_participate")
.font(.system(size: 27))
.fontWeight(.semibold)
.frame(maxWidth: .infinity).padding(10)
.multilineTextAlignment(.center)
.overlay {
switch isDisabled {
case true:
AllInColors.grey700Color.frame(width: 170)
.mask(
Text("bet_participate")
.font(.system(size: 27))
.fontWeight(.semibold)
.frame(maxWidth: .infinity).padding(10)
)
case false:
AllInColors.primaryGradient.frame(width: 170)
.mask(
Text("bet_participate")
.font(.system(size: 27))
.fontWeight(.semibold)
.frame(maxWidth: .infinity).padding(10)
)
}
}
.accentColor(AllInColors.componentBackgroundColor)
.background(isDisabled ? AllInColors.delimiterGrey.opacity(0.5):AllInColors.whiteColor)
.buttonStyle(.borderedProminent).cornerRadius(4.0)
.overlay(
RoundedRectangle(cornerRadius: 12).stroke(AllInColors.delimiterGrey, lineWidth: 1)
)
}
.disabled(isDisabled)
}
}

@ -1,120 +0,0 @@
//
// ParticipationModal.swift
// AllIn
//
// Created by Lucas Delanier on 16/01/2024.
//
import SwiftUI
import Model
struct ParticipationModal: View {
@Binding var selectedAnswer: AnswerDetail
@Binding var mise: String
var phrase: String
var answers: [AnswerDetail]
var participationAddedCallback: () -> Void
var checkAndSetError: () -> Bool
var possibleGain: Int {
if let stake = Float(mise) {
return Int(round(stake * selectedAnswer.odds))
} else {
return 0
}
}
var body: some View {
GeometryReader { geometry in
VStack(alignment: .leading){
HStack{
Spacer()
Rectangle()
.foregroundStyle(AllInColors.lightGrey300Color)
.frame(maxWidth: 80, maxHeight: 5)
.cornerRadius(999)
Spacer()
}
.padding(10)
HStack{
Text("bet_status_place_your_bets")
.font(.system(size: 18))
.foregroundColor(AllInColors.primaryTextColor)
.fontWeight(.semibold)
Spacer()
AllcoinsCounter(backgroundColor: AllInColors.lightPurpleColor, foregroundColor: .white)
}
.padding(.leading, 15)
VStack(alignment: .leading){
Text(phrase)
.font(.system(size: 13))
.foregroundColor(AllInColors.primaryTextColor)
.fontWeight(.light)
DropDownAnswerMenu(selectedAnswer: $selectedAnswer, answers: answers)
TextField("", text: $mise, prompt: Text("generic_stake")
.foregroundColor(AllInColors.lightGrey300Color)
.font(.system(size: 16))
.fontWeight(.bold))
.padding()
.keyboardType(.numberPad)
.background(
RoundedRectangle(cornerRadius: 9)
.fill(AllInColors.lightGrey200Color)
.frame(height: 40)
)
.frame(height: 40)
.foregroundColor(.black)
.overlay(
RoundedRectangle(cornerRadius: 8, style: .continuous)
.stroke(AllInColors.delimiterGrey, lineWidth: 1)
)
.padding(.bottom, 5)
}
.padding(15)
Spacer()
VStack{
HStack{
Text("participation_possible_winnings")
.font(.system(size: 13))
.foregroundColor(AllInColors.primaryTextColor)
.fontWeight(.medium)
Spacer()
Text(possibleGain.description)
.font(.system(size: 13))
.foregroundColor(AllInColors.primaryTextColor)
.fontWeight(.bold)
Image("allcoinIcon")
.resizable()
.frame(width: 11, height: 12)
}
.padding(.top, 10)
.padding(.bottom, 0)
Button {
participationAddedCallback()
} label: {
Text("Miser")
.font(.system(size: 23))
.foregroundColor(AllInColors.whiteColor)
.fontWeight(.bold)
.frame(maxWidth: .infinity)
.padding(.vertical, 3)
}
.buttonStyle(.borderedProminent)
.tint(AllInColors.lightPurpleColor)
.disabled(checkAndSetError())
.padding(.bottom, 5)
}
.padding(.horizontal, 10)
.background(AllInColors.whiteColor)
.border(width: 1, edges: [.top], color: AllInColors.delimiterGrey)
}
.background(AllInColors.underComponentBackgroundColor)
}
}
}

@ -1,35 +0,0 @@
//
// RankingRow.swift
// AllIn
//
// Created by Emre on 27/09/2023.
//
import SwiftUI
struct RankingRow: View {
var number: Int
var image: String?
var pseudo: String
var allCoins: Int
var body: some View {
HStack(){
Text(number.description)
.textStyle(weight: .bold, color: AllInColors.lightPurpleColor, size: 18)
UserInfo(username: pseudo, picture: image, value: allCoins)
}
.padding(10)
.padding(.horizontal, 5)
.background(AllInColors.componentBackgroundColor)
.cornerRadius(8)
.frame(maxWidth: 750)
}
}
struct RankingRow_Previews: PreviewProvider {
static var previews: some View {
RankingRow(number: 3, image: "defaultUserImage", pseudo: "Lucas", allCoins: 541)
}
}

@ -1,123 +0,0 @@
//
// RecapBetCard.swift
// AllIn
//
// Created by Lucas on 28/09/2023.
//
import SwiftUI
import Model
struct RecapBetCard: View {
var betResult: BetResultDetail
@GestureState private var longPressTap = false
@State private var isPressed = false
@State var showDetails: Bool = false
@State var showPartipated: Bool = false
var body: some View {
VStack(spacing: 0){
VStack(alignment: .leading,spacing: 2){
HStack{
Spacer()
Text("bet_proposed_by_format \(betResult.bet.author)")
.font(.system(size: 10))
.foregroundColor(AllInColors.grey800Color)
}
Text(betResult.bet.theme)
.font(.system(size: 15))
.foregroundColor(AllInColors.grey800Color)
Text(betResult.bet.phrase)
.font(.system(size: 20))
.fontWeight(.bold)
HStack{
Text("bet_ends")
.font(.system(size: 15))
.foregroundColor(AllInColors.grey800Color)
TextCapsule(date: betResult.bet.endBetDate)
Spacer()
}
}
.frame(width: .infinity)
.padding(.all,15)
.background(AllInColors.componentBackgroundColor).cornerRadius(20, corners: [.topLeft,.topRight])
.padding(.bottom,0)
VStack(alignment: .leading,spacing: 6){
HStack{
Text("Mise")
.textStyle(weight: .regular, color: AllInColors.grey800Color, size: 15)
Spacer()
Text(betResult.participation.stake.description)
.textStyle(weight: .regular, color: AllInColors.grey800Color, size: 15)
Image("Allcoins")
.resizable()
.frame(width: 10,height: 10)
.overlay {
AllInColors.grey800Color.frame(width: 10)
.mask(
Image("Allcoins").resizable().frame(width: 10,height: 10)
)
}
}
HStack{
Text("Gains")
.textStyle(weight: .medium, color: AllInColors.lightPurpleColor, size: 15)
Spacer()
Text(betResult.amount.description)
.font(.system(size: 15))
.fontWeight(.medium)
.overlay {
AllInColors.primaryGradient.frame(width: 50)
.mask(
Text(betResult.amount.description).font(.system(size: 15)).fontWeight(.medium)
)
}
.padding(0)
Image("Allcoins").resizable().frame(width: 10,height: 10).overlay {
AllInColors.primaryGradient.frame(width: 10)
.mask(
Image("Allcoins").resizable().frame(width: 10,height: 10)
)
}
}
HStack{
Text("Côte totale").font(.system(size: 15)).fontWeight(.medium)
Spacer()
// TODO bind le odd
Text("1,0")
.textStyle(weight: .bold, color: .white, size: 18)
.padding([.leading,.trailing],10)
.padding([.top,.bottom],5)
.background(AllInColors.primaryGradient)
.cornerRadius(8, corners: .allCorners)
}
.padding([.bottom],10)
}
.frame(width: .infinity)
.padding([.top,.bottom],8)
.padding([.leading,.trailing],15)
.background(AllInColors.underComponentBackgroundColor)
.cornerRadius(20, corners: [.bottomLeft,.bottomRight])
.padding(.bottom,0).border(width: 1, edges: [.top], color: AllInColors.delimiterGrey)
}
.scaleEffect(longPressTap ? 0.97 : 1.0)
.animation(.easeInOut, value: longPressTap)
.onTapGesture {
showDetails.toggle()
}.fullScreenCover(isPresented: $showDetails) {
DetailsView(isModalPresented: $showDetails, isModalParticipated: $showPartipated, id: betResult.bet.id)
}
.gesture(
LongPressGesture(minimumDuration: 0.5)
.updating($longPressTap) { value, state, _ in
state = value
}
)
}
}

@ -1,39 +0,0 @@
//
// ResultBanner.swift
// AllIn
//
// Created by Lucas Delanier on 15/01/2024.
//
import SwiftUI
import Model
struct ResultBanner: View {
var finalAnswer: Participation
var odds: Float
var body: some View {
VStack{
HStack{
Image(systemName: "trophy.fill").resizable().frame(maxWidth: 70, maxHeight: 60).foregroundColor(AllInColors.blueGrey800Color)
Text(finalAnswer.answer).font(.system(size: 70)).fontWeight(.bold).foregroundStyle(AllInColors.blueGrey800Color)
}.frame(height: 80)
HStack(spacing: 20){
HStack{
Image("blueAllCoinIcon").resizable().frame(maxWidth: 12, maxHeight: 12)
Text(finalAnswer.stake.description).font(.system(size: 16)).fontWeight(.semibold).foregroundStyle(AllInColors.blueGrey800Color)
}
HStack{
Image("bluePersonIcon").resizable().frame(maxWidth: 15, maxHeight: 12)
Text(finalAnswer.username).font(.system(size: 16)).fontWeight(.semibold).foregroundStyle(AllInColors.blueGrey800Color)
}
HStack{
Image("blueTrophyIcon").resizable().frame(maxWidth: 15, maxHeight: 12)
Text("\(odds, specifier: "%.2f")").font(.system(size: 16)).fontWeight(.semibold).foregroundStyle(AllInColors.blueGrey800Color)
}
}
}
.frame(maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/)
.padding(.vertical, 20).background(AllInColors.winBannerBackground)
.border(width: 2, edges: [.top,.bottom], color: AllInColors.blueAccentColor.opacity(0.2))
}
}

@ -1,113 +0,0 @@
//
// BetCard.swift
// AllIn
//
// Created by Lucas on 24/09/2023.
//
import SwiftUI
import Model
struct ReviewCard: View {
@State var showDetails: Bool = false
@State var showPartipated: Bool = false
var bet: Bet
var amount: Int
var isWin: Bool
var body: some View {
VStack(spacing: 0){
VStack(alignment: .leading,spacing: 2){
HStack{
Spacer()
Text("bet_proposed_by_format \(bet.author)")
.font(.system(size: 10))
.foregroundColor(AllInColors.grey800Color)
}
Text(bet.theme).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color)
Text(bet.phrase).font(.system(size: 20)).fontWeight(.bold)
HStack{
Text("bet_ends").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color)
TextCapsule(date: bet.endBetDate)
Spacer()
}
}
.frame(width: .infinity)
.padding(.all,15)
.background(AllInColors.componentBackgroundColor)
.cornerRadius(20, corners: [.topLeft,.topRight]).padding(.bottom,0)
VStack(alignment: .center,spacing:0){
HStack(){
Spacer()
if bet.status == .finished {
Text(amount.description)
.foregroundColor(.white)
.font(.system(size: 25))
.fontWeight(.bold)
Image("allcoinWhiteIcon")
.resizable()
.frame(width: 18, height: 20)
}
switch bet.status {
case .waiting, .inProgress:
Text("bet_status_stake")
.foregroundColor(.white)
.font(.system(size: 25))
.fontWeight(.bold)
case .closing:
Text("bet_status_finished")
.foregroundColor(.white)
.font(.system(size: 25))
.fontWeight(.bold)
case .finished:
Text(isWin ? "Gagnés!" : "Perdus!")
.foregroundColor(.white)
.font(.system(size: 25))
.fontWeight(.bold)
case .cancelled:
Text("cancelled")
.foregroundColor(.white)
.font(.system(size: 25))
.fontWeight(.bold)
}
Spacer()
}
.frame(width: .infinity)
.padding(.all,10)
}
.frame(width: .infinity)
.padding(.all,2)
.background(backgroundColor())
.cornerRadius(20, corners: [.bottomLeft,.bottomRight])
}
.onTapGesture {
showDetails.toggle()
}.fullScreenCover(isPresented: $showDetails) {
DetailsView(isModalPresented: $showDetails, isModalParticipated: $showPartipated, id: bet.id)
}
}
private func backgroundColor() -> some View {
Group {
if bet.status == .finished && isWin {
AllInColors.primaryGradient
} else {
switch bet.status {
case .inProgress, .waiting, .closing:
AllInColors.grey50Color
case .finished:
Color.black
case .cancelled:
Color.red
}
}
}
}
}

@ -1,63 +0,0 @@
//
// TextCapsule.swift
// AllIn
//
// Created by Lucas on 24/09/2023.
//
import SwiftUI
struct TextCapsule: View {
var date: Date
private var formattedDate: String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MMM"
return dateFormatter.string(from: date)
}
private var formattedTime: String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
return dateFormatter.string(from: date)
}
var body: some View {
HStack {
Text(formattedDate)
.font(.system(size: 15))
.foregroundColor(AllInColors.lightPurpleColor)
.fontWeight(.bold)
.padding([.leading, .trailing], 10)
.padding([.top, .bottom], 5)
.background(AllInColors.underComponentBackgroundColor)
.clipShape(Capsule())
.overlay(
RoundedRectangle(cornerRadius: 20)
.stroke(AllInColors.delimiterGrey, lineWidth: 1)
)
Text(formattedTime)
.font(.system(size: 15))
.foregroundColor(AllInColors.lightPurpleColor)
.fontWeight(.bold)
.padding([.leading, .trailing], 10)
.padding([.top, .bottom], 5)
.background(AllInColors.underComponentBackgroundColor)
.clipShape(Capsule())
.overlay(
RoundedRectangle(cornerRadius: 20)
.stroke(AllInColors.delimiterGrey, lineWidth: 1)
)
Spacer()
}
}
}
struct TextCapsule_Previews: PreviewProvider {
static var previews: some View {
TextCapsule(date: Date())
}
}

@ -1,85 +0,0 @@
//
// TrendingBetCard.swift
// AllIn
//
// Created by Lucas on 21/09/2023.
//
import SwiftUI
import Model
struct TrendingBetCard: View {
var bet: Bet
@State var showDetails: Bool = false
@State var showParticipate: Bool = false
var body: some View {
VStack(alignment: .leading) {
HStack {
Image("FireIcon")
.resizable()
.frame(width: 15, height: 15, alignment: .leading)
Text("bet_popular")
.textStyle(weight: .medium, color: AllInColors.pinkAccentColor, size: 17)
}
.padding([.leading, .top], 10)
Text(bet.theme)
.textStyle(weight: .heavy, color: .white, size: 17)
.frame(height: 47)
.multilineTextAlignment(.leading)
.padding([.leading, .trailing], 33)
Spacer()
GeometryReader { geometry in
HStack(alignment: .center, spacing: 0) {
Text("12")
.textStyle(weight: .bold, color: AllInColors.pinkAccentColor, size: 14)
Text("bet_players_format")
.textStyle(weight: .regular, color: .white, size: 14)
.padding([.leading], 2)
Text("2.35k")
.textStyle(weight: .bold, color: AllInColors.pinkAccentColor, size: 14)
.padding([.leading], 10)
Text("bet_points_at_stake_format")
.textStyle(weight: .regular, color: .white, size: 14)
.padding([.leading], 2)
}
.padding([.leading, .bottom, .trailing], 10)
.frame(width: geometry.size.width, height: geometry.size.height, alignment: .bottom)
}
}
.frame(height: 127, alignment: .topLeading)
.background(AllInColors.primaryColor)
.overlay(
RoundedRectangle(cornerRadius: 20, style: .continuous)
.stroke(AllInColors.primaryGradient, lineWidth: 5)
)
.clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous))
.onTapGesture {
showDetails.toggle()
}
.fullScreenCover(isPresented: $showDetails) {
DetailsView(isModalPresented: $showDetails, isModalParticipated: $showParticipate, id: bet.id)
}
}
}
struct TrendingBetCard_Previews: PreviewProvider {
static var previews: some View {
TrendingBetCard(bet: BinaryBet(theme: "Football - Finale de la Ligue des Champions",
phrase: "Le gagnant de la finale sera l'équipe avec le plus de tirs au but.",
endRegisterDate: Date().addingTimeInterval(86400),
endBetDate: Date().addingTimeInterval(172800),
isPrivate: true,
status: .inProgress,
invited: [],
author: "Imri"))
}
}

@ -1,34 +0,0 @@
//
// UserInfo.swift
// AllIn
//
// Created by Emre on 16/12/2023.
//
import SwiftUI
import Model
struct UserInfo: View {
var username: String
var picture: String?
var value: Int
var body: some View {
HStack {
UserPicture(picture: picture, username: username, size: 35)
.padding(.trailing, 7)
Text(username)
.font(.system(size: 15))
.foregroundStyle(AllInColors.primaryTextColor)
.fontWeight(.semibold)
Spacer()
Text(value.description)
.font(.system(size: 18))
.foregroundStyle(AllInColors.lightPurpleColor)
.fontWeight(.bold)
.padding(.trailing, 4)
Image("PurpleAllCoin")
.resizable()
.frame(width: 15, height: 16)
}
}
}

@ -1,30 +0,0 @@
//
// UsersPreview.swift
// AllIn
//
// Created by Lucas on 24/09/2023.
//
import SwiftUI
import Model
struct UsersPreview: View {
var users: [User]?
var body: some View {
if users != nil {
HStack(spacing: -20){
ForEach(users!.prefix(4)) { user in
Image("defaultUserImage")
.resizable()
.frame(width: 35, height: 35)
}
}
}
}
}
struct UsersPreview_Previews: PreviewProvider {
static var previews: some View {
UsersPreview()
}
}

@ -1,93 +0,0 @@
//
// WinModal.swift
// AllIn
//
// Created by Lucas on 27/09/2023.
//
import SwiftUI
import Model
struct WinModal: View {
@Environment(\.dismiss) var dismiss
var betResult: BetResultDetail
@State var xOffset: CGFloat = 0
var body: some View {
ZStack{
GeometryReader { geometry in
let size = geometry.size.width / 20
InfiniteScroller(contentWidth: geometry.size.width) {
Image("marquee").resizable().scaledToFit()
}
VStack {
ZStack(alignment: .topLeading){
HStack{
Spacer()
Image("allinIcon").resizable().frame(width: 35, height: 35)
Spacer()
}
Image("crossIcon").resizable().frame(width: 25, height: 25).onTapGesture {
dismiss()
}
}
HStack{
Text("FÉLICITATIONS").font(.system(size: 20)).foregroundColor(.white).fontWeight(.semibold).italic()
Text(AppStateContainer.shared.user?.username ?? "").padding(.top,9).font(.system(size: 33)).fontWeight(.heavy).foregroundColor(.white)
}
.rotationEffect(.degrees(-4))
.padding(.top,40)
Spacer()
AllcoinsCapsule(gains: betResult.amount)
Spacer()
RecapBetCard(betResult: betResult)
Spacer()
}
.padding([.all],20)
}
}.background(
Image("modalBackgroundImage")
.resizable()
.edgesIgnoringSafeArea(.all)
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
)
}
}
struct InfiniteScroller<Content: View>: View {
var contentWidth: CGFloat
var content: (() -> Content)
@State
var xOffset: CGFloat = -800
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 0) {
content()
content()
content()
}
.offset(x: xOffset, y: 0).opacity(0.3)
}
.disabled(true)
.onAppear {
withAnimation(
.linear(duration: 25)
.repeatForever(autoreverses: false)
) {
xOffset = +contentWidth
}
}
.frame(width: 1300, height: 1300)
.padding(.leading, -400)
.rotationEffect(.degrees(30))
.opacity(0.1)
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save