diff --git a/package-lock.json b/package-lock.json index 8626e76..5bac153 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@microsoft/signalr": "^10.0.0", "@openapitools/openapi-generator-cli": "^2.30.2", "@tailwindcss/postcss": "^4.2.1", + "browser-image-compression": "^2.0.2", "postcss": "^8.5.8", "rimraf": "^6.1.3", "rxjs": "~7.8.0", @@ -5018,6 +5019,15 @@ "node": "18 || 20 || >=22" } }, + "node_modules/browser-image-compression": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/browser-image-compression/-/browser-image-compression-2.0.2.tgz", + "integrity": "sha512-pBLlQyUf6yB8SmmngrcOw3EoS4RpQ1BcylI3T9Yqn7+4nrQTXJD4sJDe5ODnJdrvNMaio5OicFo75rDyJD2Ucw==", + "license": "MIT", + "dependencies": { + "uzip": "0.20201231.0" + } + }, "node_modules/browserslist": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", @@ -9939,6 +9949,12 @@ "dev": true, "license": "MIT" }, + "node_modules/uzip": { + "version": "0.20201231.0", + "resolved": "https://registry.npmjs.org/uzip/-/uzip-0.20201231.0.tgz", + "integrity": "sha512-OZeJfZP+R0z9D6TmBgLq2LHzSSptGMGDGigGiEe0pr8UBe/7fdflgHlHBNDASTXB5jnFuxHpNaJywSg8YFeGng==", + "license": "MIT" + }, "node_modules/validate-npm-package-name": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz", diff --git a/package.json b/package.json index 43ecd12..5e0e956 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "@microsoft/signalr": "^10.0.0", "@openapitools/openapi-generator-cli": "^2.30.2", "@tailwindcss/postcss": "^4.2.1", + "browser-image-compression": "^2.0.2", "postcss": "^8.5.8", "rimraf": "^6.1.3", "rxjs": "~7.8.0", diff --git a/src/app/components/challenge-card/challenge-card.component.ts b/src/app/components/challenge-card/challenge-card.component.ts index d7591ee..dd7b2d9 100644 --- a/src/app/components/challenge-card/challenge-card.component.ts +++ b/src/app/components/challenge-card/challenge-card.component.ts @@ -1,5 +1,5 @@ import {Component, inject, input, signal, viewChild} from '@angular/core'; -import {IonicModule, ToastController} from "@ionic/angular"; +import {IonicModule, LoadingController, ToastController} from "@ionic/angular"; import {GetRandomChallengeDto, RandomchallengesService} from "../../services/api"; import {firstValueFrom} from "rxjs"; import {TooltipComponent} from "../tooltip/tooltip.component"; @@ -19,6 +19,7 @@ import {SignOnFormComponent} from "../sign-on-form/sign-on-form.component"; export class ChallengeCardComponent { private randomChallengesService = inject(RandomchallengesService); private toastCtrl = inject(ToastController); + private loadCtrl = inject(LoadingController); action = input.required(); tag = input.required(); @@ -34,8 +35,26 @@ export class ChallengeCardComponent { } async sendProof(randomChallengeId: number) { + const file = this.proof().proofForm.value.proof; + + if (!file) { + const toast = await this.toastCtrl.create({ + message: 'Aucune preuve n\'a été déposée', + duration: 2000, + color: 'danger' + }); + await toast.present(); + return; + } + + const loading = await this.loadCtrl.create({ + message: 'Chargement...', + spinner: 'lines-sharp-small' + }); + await loading.present(); + try { - await firstValueFrom(this.randomChallengesService.patchProofEndpoint(randomChallengeId, this.proof().proofForm.value.proof)); + await firstValueFrom(this.randomChallengesService.patchProofEndpoint(randomChallengeId, file)); this.isModalOpen = false; const toast = await this.toastCtrl.create({ @@ -45,6 +64,7 @@ export class ChallengeCardComponent { }); await toast.present(); } catch { + this.isModalOpen = false; const toast = await this.toastCtrl.create({ message: 'Tu as déjà déposé une preuve pour ce défi', duration: 2000, @@ -52,5 +72,6 @@ export class ChallengeCardComponent { }); await toast.present(); } + await loading.dismiss(); } } \ No newline at end of file diff --git a/src/app/components/proof-form/proof-form.component.html b/src/app/components/proof-form/proof-form.component.html index 3788e54..6f0c5b6 100644 --- a/src/app/components/proof-form/proof-form.component.html +++ b/src/app/components/proof-form/proof-form.component.html @@ -13,5 +13,5 @@ } - + \ No newline at end of file diff --git a/src/app/components/proof-form/proof-form.component.ts b/src/app/components/proof-form/proof-form.component.ts index 9aa9f8c..f158b1d 100644 --- a/src/app/components/proof-form/proof-form.component.ts +++ b/src/app/components/proof-form/proof-form.component.ts @@ -1,8 +1,9 @@ -import {Component} from '@angular/core'; +import {Component, inject} from '@angular/core'; import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from "@angular/forms"; -import {IonicModule} from "@ionic/angular"; +import {IonicModule, LoadingController} from "@ionic/angular"; import {TitlePartComponent} from "../title-part/title-part.component"; import {NgClass} from "@angular/common"; +import imageCompression from 'browser-image-compression'; @Component({ selector: 'app-proof-form', @@ -17,20 +18,39 @@ import {NgClass} from "@angular/common"; ] }) export class ProofFormComponent { + private loadCtrl = inject(LoadingController); + proofForm: FormGroup = new FormGroup({ proof: new FormControl(null, [Validators.required]), }) previewUrl: string | null = null; - onFileChange(files?: FileList | null) { + async onFileChange(files?: FileList | null) { if (!files?.length) return; + const loading = await this.loadCtrl.create({ + message: 'Compression...', + spinner: 'lines-sharp-small' + }); + await loading.present(); + const file = files[0]; - this.previewUrl = URL.createObjectURL(file); + // Compression en JPEG de l'image (moins lourd en BDD) + const options = { + maxSizeMB: 1, + maxWidthOrHeight: 1080, + useWebWorker: true, + fileType: 'image/jpeg' + } + + const compressed = await imageCompression(file, options); + + this.previewUrl = URL.createObjectURL(compressed); this.proofForm.patchValue({ - proof: file + proof: compressed }); + await loading.dismiss(); } } diff --git a/src/app/components/search-friend/search-friend.component.ts b/src/app/components/search-friend/search-friend.component.ts index 375236b..0b49b30 100644 --- a/src/app/components/search-friend/search-friend.component.ts +++ b/src/app/components/search-friend/search-friend.component.ts @@ -28,11 +28,11 @@ export class SearchFriendComponent implements OnInit { async ngOnInit() { const loading = await this.loadCtrl.create({ message: 'Chargement...', - duration: 1000, spinner: 'lines-sharp-small' }); await loading.present(); await this.fetchUsers(); + await loading.dismiss(); } async fetchUsers() { diff --git a/src/app/pages/ranking/ranking.component.ts b/src/app/pages/ranking/ranking.component.ts index e4b0137..b9575b5 100644 --- a/src/app/pages/ranking/ranking.component.ts +++ b/src/app/pages/ranking/ranking.component.ts @@ -25,7 +25,6 @@ export class RankingComponent implements OnInit { async fetchUsers() { const loading = await this.loadCtrl.create({ message: 'Chargement...', - duration: 1000, spinner: 'lines-sharp-small' }); await loading.present(); @@ -41,5 +40,6 @@ export class RankingComponent implements OnInit { }); await toast.present(); } + await loading.dismiss(); } } \ No newline at end of file