Compare commits
No commits in common. 'master' and 'V2' have entirely different histories.
Before Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 354 KiB |
@ -1,91 +1,3 @@
|
|||||||
<div align="center">
|
# Swift
|
||||||
|
|
||||||
<img src="Documentation/Images/Banner-AllIn.png" />
|
Client IOS
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
[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>
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
</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,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>
|
|
@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// AppDelegate.swift
|
||||||
|
// AllIn
|
||||||
|
//
|
||||||
|
// Created by Emre on 17/12/2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
|
|
||||||
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationWillResignActive(_ application: UIApplication) {
|
||||||
|
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationDidEnterBackground(_ application: UIApplication) {
|
||||||
|
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||||
|
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||||
|
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||||
|
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationWillTerminate(_ application: UIApplication) {
|
||||||
|
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"colors" : [
|
|
||||||
{
|
|
||||||
"color" : {
|
|
||||||
"color-space" : "srgb",
|
|
||||||
"components" : {
|
|
||||||
"alpha" : "1.000",
|
|
||||||
"blue" : "0xF8",
|
|
||||||
"green" : "0x99",
|
|
||||||
"red" : "0x23"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"idiom" : "universal"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "dark"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"color" : {
|
|
||||||
"color-space" : "srgb",
|
|
||||||
"components" : {
|
|
||||||
"alpha" : "1.000",
|
|
||||||
"blue" : "0xF8",
|
|
||||||
"green" : "0x99",
|
|
||||||
"red" : "0x23"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"idiom" : "universal"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
|
@ -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" : "0x8A",
|
|
||||||
"green" : "0x2B",
|
|
||||||
"red" : "0xFE"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"idiom" : "universal"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "dark"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"color" : {
|
|
||||||
"color-space" : "srgb",
|
|
||||||
"components" : {
|
|
||||||
"alpha" : "1.000",
|
|
||||||
"blue" : "0x8A",
|
|
||||||
"green" : "0x2B",
|
|
||||||
"red" : "0xFE"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"idiom" : "universal"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"colors" : [
|
|
||||||
{
|
|
||||||
"color" : {
|
|
||||||
"color-space" : "srgb",
|
|
||||||
"components" : {
|
|
||||||
"alpha" : "1.000",
|
|
||||||
"blue" : "0xA8",
|
|
||||||
"green" : "0x49",
|
|
||||||
"red" : "0xC2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"idiom" : "universal"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "dark"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"color" : {
|
|
||||||
"color-space" : "srgb",
|
|
||||||
"components" : {
|
|
||||||
"alpha" : "1.000",
|
|
||||||
"blue" : "0xA8",
|
|
||||||
"green" : "0x49",
|
|
||||||
"red" : "0xC2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"filename" : "Vector (3).png",
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "3x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 1.1 KiB |
@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"colors" : [
|
|
||||||
{
|
|
||||||
"color" : {
|
|
||||||
"color-space" : "srgb",
|
|
||||||
"components" : {
|
|
||||||
"alpha" : "1.000",
|
|
||||||
"blue" : "0x3C",
|
|
||||||
"green" : "0x3C",
|
|
||||||
"red" : "0x3C"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"idiom" : "universal"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "dark"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"color" : {
|
|
||||||
"color-space" : "srgb",
|
|
||||||
"components" : {
|
|
||||||
"alpha" : "1.000",
|
|
||||||
"blue" : "0xFF",
|
|
||||||
"green" : "0xFF",
|
|
||||||
"red" : "0xFF"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"idiom" : "universal"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"colors" : [
|
|
||||||
{
|
|
||||||
"color" : {
|
|
||||||
"color-space" : "srgb",
|
|
||||||
"components" : {
|
|
||||||
"alpha" : "1.000",
|
|
||||||
"blue" : "0xFF",
|
|
||||||
"green" : "0xE8",
|
|
||||||
"red" : "0xD1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"idiom" : "universal"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"appearances" : [
|
|
||||||
{
|
|
||||||
"appearance" : "luminosity",
|
|
||||||
"value" : "dark"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"color" : {
|
|
||||||
"color-space" : "srgb",
|
|
||||||
"components" : {
|
|
||||||
"alpha" : "1.000",
|
|
||||||
"blue" : "0xFF",
|
|
||||||
"green" : "0xE8",
|
|
||||||
"red" : "0xD1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"idiom" : "universal"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"filename" : "allCoinBlack.png",
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "3x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 1.1 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
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 681 B |
@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"filename" : "Vector.png",
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "3x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 986 B |
@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"filename" : "blueFlame.png",
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"scale" : "3x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
|
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
|
|
||||||
}
|
|
||||||
}
|
|
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
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 2.2 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
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 1.5 KiB |
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
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
|
|
||||||
}
|
|
||||||
}
|
|
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
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 39 KiB |
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 3.5 KiB |
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 5.0 MiB |
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
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
|
|
||||||
}
|
|
||||||
}
|
|
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
|
|
||||||
}
|
|
||||||
}
|
|
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
|
|
||||||
}
|
|
||||||
}
|
|
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
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 975 B |
@ -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,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,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,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,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,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,58 +0,0 @@
|
|||||||
//
|
|
||||||
// userPicture.swift
|
|
||||||
// AllIn
|
|
||||||
//
|
|
||||||
// Created by Lucas Delanier on 04/06/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
struct UserPicture: View {
|
|
||||||
var picture: String?
|
|
||||||
var username: String
|
|
||||||
var size: CGFloat
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
ZStack {
|
|
||||||
if let pictureURL = picture {
|
|
||||||
userImage(url: pictureURL)
|
|
||||||
} else {
|
|
||||||
placeholderImage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainActor private func userImage(url: String) -> some View {
|
|
||||||
AsyncCachedImage(url: URL(string: url)) { image in
|
|
||||||
image
|
|
||||||
.resizable()
|
|
||||||
.frame(width: size, height: size)
|
|
||||||
.clipShape(Circle())
|
|
||||||
} placeholder: {
|
|
||||||
placeholderImage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private var placeholderImage: some View {
|
|
||||||
Circle()
|
|
||||||
.foregroundColor(.gray)
|
|
||||||
.frame(width: size, height: size)
|
|
||||||
.overlay(
|
|
||||||
Text(username.prefix(2).uppercased())
|
|
||||||
.fontWeight(.medium)
|
|
||||||
.foregroundStyle(.white)
|
|
||||||
.font(.system(size: fontSize(for: size)))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func fontSize(for diameter: CGFloat) -> CGFloat {
|
|
||||||
let fontScaleFactor: CGFloat = 0.45
|
|
||||||
return diameter * fontScaleFactor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct UserPicture_Previews: PreviewProvider {
|
|
||||||
static var previews: some View {
|
|
||||||
UserPicture(picture: nil, username: "Lucas", size: 100)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
//
|
|
||||||
// Delegates.swift
|
|
||||||
// AllIn
|
|
||||||
//
|
|
||||||
// Created by Emre on 22/02/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
class AppDelegate: NSObject, UIApplicationDelegate {
|
|
||||||
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
|
|
||||||
if let selectedAction = options.shortcutItem {
|
|
||||||
QuickAction.selectedAction = selectedAction
|
|
||||||
}
|
|
||||||
let sceneConfiguration = UISceneConfiguration(name: "Quick Action Scene", sessionRole: connectingSceneSession.role)
|
|
||||||
sceneConfiguration.delegateClass = QuickActionSceneDelegate.self
|
|
||||||
return sceneConfiguration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class QuickActionSceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|
||||||
func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
|
|
||||||
QuickAction.selectedAction = shortcutItem
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
//
|
|
||||||
// QuickAction.swift
|
|
||||||
// AllIn
|
|
||||||
//
|
|
||||||
// Created by Emre on 22/02/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
enum QuickAction {
|
|
||||||
static var selectedAction: UIApplicationShortcutItem?
|
|
||||||
|
|
||||||
static var homeuserInfo: [String : NSSecureCoding] {
|
|
||||||
["name" : "Bet" as NSSecureCoding]
|
|
||||||
}
|
|
||||||
|
|
||||||
static var createuserInfo: [String : NSSecureCoding] {
|
|
||||||
["name" : "CreationBet" as NSSecureCoding]
|
|
||||||
}
|
|
||||||
|
|
||||||
static var frienduserInfo: [String : NSSecureCoding] {
|
|
||||||
["name" : "Friends" as NSSecureCoding]
|
|
||||||
}
|
|
||||||
|
|
||||||
static var rankuserInfo: [String : NSSecureCoding] {
|
|
||||||
["name" : "Ranking" as NSSecureCoding]
|
|
||||||
}
|
|
||||||
|
|
||||||
static var allShortcutItems: [UIApplicationShortcutItem] = {
|
|
||||||
var shortcuts: [UIApplicationShortcutItem] = []
|
|
||||||
|
|
||||||
if AppStateContainer.shared.loggedState.connectedUser {
|
|
||||||
shortcuts.append(UIApplicationShortcutItem(type: "home", localizedTitle: "Coins : " + String(AppStateContainer.shared.user?.nbCoins ?? 0), localizedSubtitle: "", icon: UIApplicationShortcutIcon(templateImageName: "allCoinBlackIcon"), userInfo: homeuserInfo))
|
|
||||||
}
|
|
||||||
|
|
||||||
shortcuts.append(contentsOf: [
|
|
||||||
UIApplicationShortcutItem(type: "create", localizedTitle: "Créer un pari", localizedSubtitle: "", icon: UIApplicationShortcutIcon(systemImageName: "pencil.circle"), userInfo: createuserInfo),
|
|
||||||
UIApplicationShortcutItem(type: "friend", localizedTitle: "Voir mes amis", localizedSubtitle: "", icon: UIApplicationShortcutIcon(systemImageName: "person.2.square.stack"), userInfo: frienduserInfo),
|
|
||||||
UIApplicationShortcutItem(type: "ranking", localizedTitle: "Classement", localizedSubtitle: "Où en suis-je ?", icon: UIApplicationShortcutIcon(systemImageName: "rosette"), userInfo: rankuserInfo)
|
|
||||||
])
|
|
||||||
|
|
||||||
return shortcuts
|
|
||||||
}()
|
|
||||||
}
|
|
@ -1,194 +0,0 @@
|
|||||||
/*
|
|
||||||
Localizable.strings
|
|
||||||
AllInApp
|
|
||||||
|
|
||||||
Created by Emre on 15/05/2024.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// Core
|
|
||||||
|
|
||||||
"generic_username" = "Username";
|
|
||||||
"generic_email" = "Email";
|
|
||||||
"generic_password" = "Password";
|
|
||||||
"generic_login" = "Login";
|
|
||||||
"generic_logout" = "Logout";
|
|
||||||
"generic_already_have_account" = "Already have an account ?";
|
|
||||||
"generic_register" = "Register";
|
|
||||||
"generic_validate" = "Validate";
|
|
||||||
"generic_ok" = "OK";
|
|
||||||
"generic_error" = "Error";
|
|
||||||
"generic_in_waiting" = "In waiting";
|
|
||||||
"generic_search" = "Search";
|
|
||||||
"generic_add" = "Add";
|
|
||||||
"generic_acccept"="Accept";
|
|
||||||
"generic_decline"="Decline";
|
|
||||||
"generic_delete" = "Delete";
|
|
||||||
"generic_stake" = "Stake";
|
|
||||||
"network_error_text" = "Make sure to be properly connected to the network then try again.";
|
|
||||||
|
|
||||||
/// Bet type
|
|
||||||
|
|
||||||
"bet_type_binary" = "Yes / No";
|
|
||||||
"bet_type_match" = "Sport match";
|
|
||||||
"bet_type_custom" = "Custom answers";
|
|
||||||
|
|
||||||
/// Field error
|
|
||||||
|
|
||||||
"field_error_mandatory" = "This field is mandatory.";
|
|
||||||
"field_error_not_identical" = "The fields are not identical.";
|
|
||||||
"field_error_bad_email" = "Please enter a valid email.";
|
|
||||||
|
|
||||||
/// Drawer
|
|
||||||
|
|
||||||
"drawer_bets" = "Bets";
|
|
||||||
"drawer_best_win" = "Best win";
|
|
||||||
"drawer_nb_friends" = "Friends";
|
|
||||||
"drawer_friends" = "FRIENDS";
|
|
||||||
"drawer_friends_subtitle" = "Challenge your folks by adding them as friends.";
|
|
||||||
"drawer_public_bets" = "PARTICIPATE";
|
|
||||||
"drawer_public_bets_subtitle" = "Browse the most popular bets of the moment.";
|
|
||||||
"drawer_create_a_bet" = "NEW BET";
|
|
||||||
"drawer_create_a_bet_subtitle" = "Create a net bet and get your friends participating.";
|
|
||||||
"drawer_bet_history" = "HISTORY";
|
|
||||||
"drawer_bet_history_subtitle" = "View your current and finished bets.";
|
|
||||||
"drawer_current_bets" = "MY PARTICIPATIONS";
|
|
||||||
"drawer_current_bets_subtitle" = "Manage your bets and reward the winners.";
|
|
||||||
"drawer_ranking" = "RANKING";
|
|
||||||
"drawer_ranking_subtitle" = "Check your ranking among your friends.";
|
|
||||||
|
|
||||||
/// Welcome Page
|
|
||||||
|
|
||||||
"welcome_title" = "Welcome to,";
|
|
||||||
"welcome_subtitle" = "Collect your Allcoins and come bet with your friend to prove who\'s best.";
|
|
||||||
"welcome_join" = "Join";
|
|
||||||
|
|
||||||
/// Register Page
|
|
||||||
|
|
||||||
"register_hello" = "Hello,";
|
|
||||||
"register_hello %@" = "Hello %@,";
|
|
||||||
"register_title" = "We need this!";
|
|
||||||
"register_subtitle" = "Don\'t worry it\'s fast.";
|
|
||||||
"register_error_title" = "Error saving";
|
|
||||||
"register_error_content" = "Registration failed. Try Again.";
|
|
||||||
"register_confirm_password" = "Confirm password";
|
|
||||||
"register_already_used" = "Email or nickname already used.";
|
|
||||||
|
|
||||||
/// Login Page
|
|
||||||
|
|
||||||
"login_title" = "Welcome back !";
|
|
||||||
"login_subtitle" = "We missed you.";
|
|
||||||
"login_error_title" = "Connection error";
|
|
||||||
"login_error_content" = "Failed to login. Please try again.";
|
|
||||||
"login_no_account" = "Don't have an account ?";
|
|
||||||
"login_forgot_password" = "Forgot password ?";
|
|
||||||
"login_bad_credentials" = "Incorrect login or password.";
|
|
||||||
|
|
||||||
/// Bet Creation Page
|
|
||||||
|
|
||||||
"bet_creation_theme_tooltip" = "Usually a common name describing the overall theme of the bet for reference..";
|
|
||||||
"bet_creation_phrase_tooltip" = "Generally the question the participants will answer to.";
|
|
||||||
"bet_creation_register_tooltip" = "After this date, nobody will be able to register anymore.";
|
|
||||||
"bet_creation_bet_end_tooltip" = "After this date, the result will be announced.";
|
|
||||||
"bet_creation_privacy_tooltip" = "Determines who will be able to see the bet.";
|
|
||||||
"bet_creation_question" = "Question";
|
|
||||||
"bet_creation_answer" = "Answer";
|
|
||||||
"bet_creation_publish" = "Publish the bet";
|
|
||||||
"bet_creation_theme" = "Theme";
|
|
||||||
"bet_creation_theme_placeholder" = "Studies, sports, party…";
|
|
||||||
"bet_creation_bet_phrase" = "Bet phrase";
|
|
||||||
"bet_creation_bet_phrase_placeholder" = "Will David be missing this Monday in class ?";
|
|
||||||
"bet_creation_end_registration_date" = "Registration end date";
|
|
||||||
"bet_creation_end_bet_date" = "Bet end date";
|
|
||||||
"bet_creation_bet_privacy" = "Bet privacy";
|
|
||||||
"bet_creation_friends_available_format" = "friends available";
|
|
||||||
"bet_creation_public_bottom_text_1" = "Your BET will be visible by all the users.";
|
|
||||||
"bet_creation_public_bottom_text_2" = "Everyone will be able to join the BET.";
|
|
||||||
"bet_creation_private_bottom_text_1" = "Your BET will only be visible by your friends.";
|
|
||||||
"bet_creation_private_bottom_text_2" = "Only your friends will be able to join the BET.";
|
|
||||||
"bet_creation_bottom_text_3" = "You can invite friends at any moment during the registration period.";
|
|
||||||
"bet_creation_yes_no_bottom_text_1" = "The participants will have to respond with either YES or NO.";
|
|
||||||
"bet_creation_yes_no_bottom_text_2" = "No other answer will be accepted.";
|
|
||||||
"bet_creation_custom_bottom_text_1" = "You are going to fill in the different answers available in this bet.";
|
|
||||||
"bet_creation_custom_bottom_text_2" = "Be careful to be clear and avoid any uncertainties";
|
|
||||||
"bet_creation_error" = "Error while creating the bet.";
|
|
||||||
"bet_creation_success_message" = "Bet created !";
|
|
||||||
"bet_creation_response_title" = "Response title";
|
|
||||||
"bet_creation_max_answers %lld" = "%lld more max.";
|
|
||||||
"bet_creation_error_past_date" = "The registration end date must be later than the current date.";
|
|
||||||
"bet_creation_error_date_order" = "The betting end date must be later than the registration end date.";
|
|
||||||
|
|
||||||
/// Bet page
|
|
||||||
|
|
||||||
"bet_popular" = "Popular";
|
|
||||||
"bet_public" = "Public";
|
|
||||||
"bet_private" = "Private";
|
|
||||||
"bet_invitation" = "Invitation";
|
|
||||||
"bet_current" = "Current";
|
|
||||||
"bet_finished" = "Finished";
|
|
||||||
"bet_starting" = "Starting on";
|
|
||||||
"bet_started" = "Started on";
|
|
||||||
"bet_ends" = "Ends on";
|
|
||||||
"bet_ended" = "Ended on";
|
|
||||||
"bet_participate" = "Participate";
|
|
||||||
"bet_proposed_by_format %@" = "Proposed by %@";
|
|
||||||
"bet_proposed_by_format" = "Proposed by";
|
|
||||||
"bet_players_waiting_format %@" = "%@ players waiting";
|
|
||||||
"bet_players_format" = "players";
|
|
||||||
"bet_points_at_stake_format" = "points at stake";
|
|
||||||
|
|
||||||
/// Bet status
|
|
||||||
|
|
||||||
"bet_status_finished" = "Finished !";
|
|
||||||
"bet_status_in_progress" = "In progress…";
|
|
||||||
"bet_status_waiting" = "Waiting…";
|
|
||||||
"bet_status_unavailable" = "Status unavailable";
|
|
||||||
"bet_status_cancelled" = "Cancelled";
|
|
||||||
"bet_status_place_your_bets" = "Place your bets";
|
|
||||||
"bet_status_participants_list" = "Participants";
|
|
||||||
"bet_status_details_drawer" = "Details";
|
|
||||||
"participation_possible_winnings" = "Possible winnings";
|
|
||||||
"bet_status_stake" = "Gambled";
|
|
||||||
|
|
||||||
/// Bet history
|
|
||||||
|
|
||||||
"bet_history_current_title" = "Current";
|
|
||||||
"bet_history_title" = "History";
|
|
||||||
|
|
||||||
/// Bet confirmation
|
|
||||||
|
|
||||||
"bet_confirmation_text" = "This bet has now ended. You may now distribute the winnings by selecting the right answer.";
|
|
||||||
"bet_confirmation_choose_response" = "Please select the final answer :";
|
|
||||||
|
|
||||||
/// Ranking
|
|
||||||
|
|
||||||
"ranking_title" = "Ranking";
|
|
||||||
|
|
||||||
/// Friends
|
|
||||||
|
|
||||||
"friends_title" = "Friends";
|
|
||||||
"friends_request_sent" = "Request sent";
|
|
||||||
"friends_request"= "Friends Request";
|
|
||||||
|
|
||||||
/// Daily reward
|
|
||||||
|
|
||||||
"daily_reward_title" = "Daily reward";
|
|
||||||
"daily_reward_subtitle" = "Your daily reward is unlocked every day at 00:00 UTC and allows you to get between 10 and 150 Allcoins.";
|
|
||||||
|
|
||||||
/// Notification
|
|
||||||
|
|
||||||
"notification_title_end_bet_date" = "Who will be the winners?";
|
|
||||||
"notification_subtitle_end_bet_date %@" = "The %@ bet has reached its deadline. Go to the app to enter the winning answer.";
|
|
||||||
|
|
||||||
/// Empty Views
|
|
||||||
|
|
||||||
"empty_ranking_title" = "It's a bit empty around here";
|
|
||||||
"empty_ranking_explain" = "Add some friends to display them in the leaderboard";
|
|
||||||
"empty_bets_title"= "No bet matches your search";
|
|
||||||
"empty_friends_title" = "You don't have any friends yet";
|
|
||||||
"empty_friends_explain" = "Add them from this screen";
|
|
||||||
|
|
||||||
/// Error Messages
|
|
||||||
|
|
||||||
"error_title" = "Error: Failed to Load Content.";
|
|
||||||
"error_message" = "The content you are trying to load could not be retrieved. Please check your internet connection and try again";
|
|
@ -1,50 +0,0 @@
|
|||||||
//
|
|
||||||
// NotificationService.swift
|
|
||||||
// AllIn
|
|
||||||
//
|
|
||||||
// Created by Emre on 22/02/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UserNotifications
|
|
||||||
|
|
||||||
struct NotificationItem {
|
|
||||||
var title: String
|
|
||||||
var content: String
|
|
||||||
var interval: TimeInterval
|
|
||||||
}
|
|
||||||
|
|
||||||
class NotificationService: ObservableObject {
|
|
||||||
|
|
||||||
@Published var notifications: [NotificationItem] = []
|
|
||||||
|
|
||||||
func scheduleNotifications() {
|
|
||||||
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
|
|
||||||
if granted {
|
|
||||||
print("Permission for notifications granted.")
|
|
||||||
} else {
|
|
||||||
print("Permission for notifications denied.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadNotifications() {
|
|
||||||
for notification in notifications {
|
|
||||||
scheduleNotification(with: notification)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeAllNotifications() {
|
|
||||||
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
|
|
||||||
}
|
|
||||||
|
|
||||||
func scheduleNotification(with item: NotificationItem) {
|
|
||||||
let content = UNMutableNotificationContent()
|
|
||||||
content.title = item.title
|
|
||||||
content.body = item.content
|
|
||||||
|
|
||||||
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: item.interval, repeats: false)
|
|
||||||
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
|
|
||||||
|
|
||||||
UNUserNotificationCenter.current().add(request)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
//
|
|
||||||
// asyncCachedImage.swift
|
|
||||||
// AllIn
|
|
||||||
//
|
|
||||||
// Created by Lucas Delanier on 06/06/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
@MainActor
|
|
||||||
struct AsyncCachedImage<ImageView: View, PlaceholderView: View>: View {
|
|
||||||
// Input dependencies
|
|
||||||
var url: URL?
|
|
||||||
@ViewBuilder var content: (Image) -> ImageView
|
|
||||||
@ViewBuilder var placeholder: () -> PlaceholderView
|
|
||||||
|
|
||||||
// Downloaded image
|
|
||||||
@State var image: UIImage? = nil
|
|
||||||
|
|
||||||
init(
|
|
||||||
url: URL?,
|
|
||||||
@ViewBuilder content: @escaping (Image) -> ImageView,
|
|
||||||
@ViewBuilder placeholder: @escaping () -> PlaceholderView
|
|
||||||
) {
|
|
||||||
self.url = url
|
|
||||||
self.content = content
|
|
||||||
self.placeholder = placeholder
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
VStack {
|
|
||||||
if let uiImage = image {
|
|
||||||
content(Image(uiImage: uiImage))
|
|
||||||
} else {
|
|
||||||
placeholder()
|
|
||||||
.onAppear {
|
|
||||||
Task {
|
|
||||||
image = await downloadPhoto()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Downloads if the image is not cached already
|
|
||||||
// Otherwise returns from the cache
|
|
||||||
private func downloadPhoto() async -> UIImage? {
|
|
||||||
do {
|
|
||||||
guard let url else { return nil }
|
|
||||||
|
|
||||||
// Check if the image is cached already
|
|
||||||
if let cachedResponse = URLCache.shared.cachedResponse(for: .init(url: url)) {
|
|
||||||
return UIImage(data: cachedResponse.data)
|
|
||||||
} else {
|
|
||||||
let (data, response) = try await URLSession.shared.data(from: url)
|
|
||||||
|
|
||||||
// Save returned image data into the cache
|
|
||||||
URLCache.shared.storeCachedResponse(.init(response: response, data: data), for: .init(url: url))
|
|
||||||
|
|
||||||
guard let image = UIImage(data: data) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return image
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
print("Error downloading: \(error)")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
//
|
|
||||||
// BetEndingValidationViewModel.swift
|
|
||||||
// AllIn
|
|
||||||
//
|
|
||||||
// Created by Emre on 07/02/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import DependencyInjection
|
|
||||||
import Model
|
|
||||||
|
|
||||||
class BetEndingValidationViewModel: ObservableObject {
|
|
||||||
|
|
||||||
var id: String
|
|
||||||
@Inject var manager: Manager
|
|
||||||
@Published var selectedAnswer : String?
|
|
||||||
|
|
||||||
init(id: String) {
|
|
||||||
self.id = id
|
|
||||||
}
|
|
||||||
|
|
||||||
func post() {
|
|
||||||
if let answer = selectedAnswer {
|
|
||||||
manager.addResponse(withIdBet: id, andResponse: answer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
//
|
|
||||||
// CurrentBetViewModel.swift
|
|
||||||
// AllIn
|
|
||||||
//
|
|
||||||
// Created by Emre on 31/01/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import DependencyInjection
|
|
||||||
import Model
|
|
||||||
|
|
||||||
class CurrentBetViewModel: ObservableObject {
|
|
||||||
|
|
||||||
@Inject var manager: Manager
|
|
||||||
|
|
||||||
@Published private(set) var bets: [BetDetail] = []
|
|
||||||
|
|
||||||
init() {
|
|
||||||
getItems()
|
|
||||||
}
|
|
||||||
|
|
||||||
func getItems() {
|
|
||||||
manager.getCurrentBets(withIndex: 0, withCount: 20) { bets in
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.bets = bets
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
//
|
|
||||||
// DetailsViewModel.swift
|
|
||||||
// AllIn
|
|
||||||
//
|
|
||||||
// Created by Emre on 16/01/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import SwiftUI
|
|
||||||
import DependencyInjection
|
|
||||||
import Model
|
|
||||||
import WidgetKit
|
|
||||||
|
|
||||||
class DetailsViewModel: ObservableObject {
|
|
||||||
|
|
||||||
@Inject var manager: Manager
|
|
||||||
var id: String
|
|
||||||
@Published var selectedAnswer = AnswerDetail(response: "", totalStakes: 0, totalParticipants: 0, highestStake: 0, odds: 0)
|
|
||||||
@Published var mise: String = ""
|
|
||||||
|
|
||||||
@Published var betDetail: BetDetail?
|
|
||||||
|
|
||||||
init(id: String) {
|
|
||||||
self.id = id
|
|
||||||
getItem(withId: id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getItem(withId id: String) {
|
|
||||||
let semaphore = DispatchSemaphore(value: 0)
|
|
||||||
manager.getBet(withId: id) { bet in
|
|
||||||
self.betDetail = bet
|
|
||||||
if let firstAnswer = bet.answers.first {
|
|
||||||
self.selectedAnswer = firstAnswer
|
|
||||||
}
|
|
||||||
semaphore.signal()
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = semaphore.wait(timeout: DispatchTime.now() + .seconds(2))
|
|
||||||
|
|
||||||
if result == .timedOut {
|
|
||||||
print("The request has exceeded the deadline")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func addParticipate() {
|
|
||||||
if let stake = Int(mise) {
|
|
||||||
manager.addParticipation(withId: id, withAnswer: selectedAnswer.response, andStake: stake) { statusCode in
|
|
||||||
switch statusCode {
|
|
||||||
case 201:
|
|
||||||
AppStateContainer.shared.user?.nbCoins -= stake
|
|
||||||
WidgetCenter.shared.reloadAllTimelines()
|
|
||||||
|
|
||||||
self.getItem(withId: self.id)
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mise = ""
|
|
||||||
if let firstAnswer = betDetail!.answers.first {
|
|
||||||
self.selectedAnswer = firstAnswer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkAndSetError() -> Bool {
|
|
||||||
if let stake = Int(mise) {
|
|
||||||
if stake <= AppStateContainer.shared.user?.nbCoins ?? 0 && stake > 0 {
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
//
|
|
||||||
// HistoricBetViewModel.swift
|
|
||||||
// AllIn
|
|
||||||
//
|
|
||||||
// Created by Emre on 16/01/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import DependencyInjection
|
|
||||||
import Model
|
|
||||||
|
|
||||||
class HistoricBetViewModel: ObservableObject {
|
|
||||||
|
|
||||||
@Inject var manager: Manager
|
|
||||||
|
|
||||||
@Published private(set) var bets: [BetResultDetail] = []
|
|
||||||
|
|
||||||
init() {
|
|
||||||
getItems()
|
|
||||||
}
|
|
||||||
|
|
||||||
func getItems() {
|
|
||||||
manager.getHistoricBets(withIndex: 0, withCount: 20) { bets in
|
|
||||||
self.bets = bets
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|