Auto-sync: 20260312_140000
This commit is contained in:
parent
50f67320a5
commit
384a9d7bd7
4 changed files with 204 additions and 99 deletions
137
ios/Podfile.lock
137
ios/Podfile.lock
|
|
@ -1190,6 +1190,10 @@ PODS:
|
||||||
- abseil/xcprivacy (1.20240722.0)
|
- abseil/xcprivacy (1.20240722.0)
|
||||||
- app_links (7.0.0):
|
- app_links (7.0.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- AppCheckCore (11.2.0):
|
||||||
|
- GoogleUtilities/Environment (~> 8.0)
|
||||||
|
- GoogleUtilities/UserDefaults (~> 8.0)
|
||||||
|
- PromisesObjC (~> 2.4)
|
||||||
- audioplayers_darwin (0.0.1):
|
- audioplayers_darwin (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- BoringSSL-GRPC (0.0.37):
|
- BoringSSL-GRPC (0.0.37):
|
||||||
|
|
@ -1199,32 +1203,60 @@ PODS:
|
||||||
- BoringSSL-GRPC/Interface (= 0.0.37)
|
- BoringSSL-GRPC/Interface (= 0.0.37)
|
||||||
- BoringSSL-GRPC/Interface (0.0.37)
|
- BoringSSL-GRPC/Interface (0.0.37)
|
||||||
- cloud_firestore (6.1.2):
|
- cloud_firestore (6.1.2):
|
||||||
- Firebase/Firestore (= 12.8.0)
|
- Firebase/Firestore (= 12.9.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- Firebase/CoreOnly (12.8.0):
|
- Firebase/Auth (12.9.0):
|
||||||
- FirebaseCore (~> 12.8.0)
|
|
||||||
- Firebase/Firestore (12.8.0):
|
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseFirestore (~> 12.8.0)
|
- FirebaseAuth (~> 12.9.0)
|
||||||
- firebase_core (4.4.0):
|
- Firebase/CoreOnly (12.9.0):
|
||||||
- Firebase/CoreOnly (= 12.8.0)
|
- FirebaseCore (~> 12.9.0)
|
||||||
|
- Firebase/Firestore (12.9.0):
|
||||||
|
- Firebase/CoreOnly
|
||||||
|
- FirebaseFirestore (~> 12.9.0)
|
||||||
|
- firebase_app_check (0.4.1-5):
|
||||||
|
- Firebase/CoreOnly (~> 12.9.0)
|
||||||
|
- firebase_core
|
||||||
|
- FirebaseAppCheck (~> 12.9.0)
|
||||||
- Flutter
|
- Flutter
|
||||||
- FirebaseAppCheckInterop (12.8.0)
|
- firebase_auth (6.1.4):
|
||||||
- FirebaseCore (12.8.0):
|
- Firebase/Auth (= 12.9.0)
|
||||||
- FirebaseCoreInternal (~> 12.8.0)
|
- firebase_core
|
||||||
|
- Flutter
|
||||||
|
- firebase_core (4.5.0):
|
||||||
|
- Firebase/CoreOnly (= 12.9.0)
|
||||||
|
- Flutter
|
||||||
|
- FirebaseAppCheck (12.9.0):
|
||||||
|
- AppCheckCore (~> 11.0)
|
||||||
|
- FirebaseAppCheckInterop (~> 12.9.0)
|
||||||
|
- FirebaseCore (~> 12.9.0)
|
||||||
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
|
- GoogleUtilities/UserDefaults (~> 8.1)
|
||||||
|
- FirebaseAppCheckInterop (12.9.0)
|
||||||
|
- FirebaseAuth (12.9.0):
|
||||||
|
- FirebaseAppCheckInterop (~> 12.9.0)
|
||||||
|
- FirebaseAuthInterop (~> 12.9.0)
|
||||||
|
- FirebaseCore (~> 12.9.0)
|
||||||
|
- FirebaseCoreExtension (~> 12.9.0)
|
||||||
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
|
- GTMSessionFetcher/Core (< 6.0, >= 3.4)
|
||||||
|
- RecaptchaInterop (~> 101.0)
|
||||||
|
- FirebaseAuthInterop (12.9.0)
|
||||||
|
- FirebaseCore (12.9.0):
|
||||||
|
- FirebaseCoreInternal (~> 12.9.0)
|
||||||
- GoogleUtilities/Environment (~> 8.1)
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
- GoogleUtilities/Logger (~> 8.1)
|
- GoogleUtilities/Logger (~> 8.1)
|
||||||
- FirebaseCoreExtension (12.8.0):
|
- FirebaseCoreExtension (12.9.0):
|
||||||
- FirebaseCore (~> 12.8.0)
|
- FirebaseCore (~> 12.9.0)
|
||||||
- FirebaseCoreInternal (12.8.0):
|
- FirebaseCoreInternal (12.9.0):
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
- FirebaseFirestore (12.8.0):
|
- FirebaseFirestore (12.9.0):
|
||||||
- FirebaseCore (~> 12.8.0)
|
- FirebaseCore (~> 12.9.0)
|
||||||
- FirebaseCoreExtension (~> 12.8.0)
|
- FirebaseCoreExtension (~> 12.9.0)
|
||||||
- FirebaseFirestoreInternal (~> 12.8.0)
|
- FirebaseFirestoreInternal (~> 12.9.0)
|
||||||
- FirebaseSharedSwift (~> 12.8.0)
|
- FirebaseSharedSwift (~> 12.9.0)
|
||||||
- FirebaseFirestoreInternal (12.8.0):
|
- FirebaseFirestoreInternal (12.9.0):
|
||||||
- abseil/algorithm (~> 1.20240722.0)
|
- abseil/algorithm (~> 1.20240722.0)
|
||||||
- abseil/base (~> 1.20240722.0)
|
- abseil/base (~> 1.20240722.0)
|
||||||
- abseil/container/flat_hash_map (~> 1.20240722.0)
|
- abseil/container/flat_hash_map (~> 1.20240722.0)
|
||||||
|
|
@ -1233,22 +1265,38 @@ PODS:
|
||||||
- abseil/strings/strings (~> 1.20240722.0)
|
- abseil/strings/strings (~> 1.20240722.0)
|
||||||
- abseil/time (~> 1.20240722.0)
|
- abseil/time (~> 1.20240722.0)
|
||||||
- abseil/types (~> 1.20240722.0)
|
- abseil/types (~> 1.20240722.0)
|
||||||
- FirebaseAppCheckInterop (~> 12.8.0)
|
- FirebaseAppCheckInterop (~> 12.9.0)
|
||||||
- FirebaseCore (~> 12.8.0)
|
- FirebaseCore (~> 12.9.0)
|
||||||
- "gRPC-C++ (~> 1.69.0)"
|
- "gRPC-C++ (~> 1.69.0)"
|
||||||
- gRPC-Core (~> 1.69.0)
|
- gRPC-Core (~> 1.69.0)
|
||||||
- leveldb-library (~> 1.22)
|
- leveldb-library (~> 1.22)
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- FirebaseSharedSwift (12.8.0)
|
- FirebaseSharedSwift (12.9.0)
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
|
- GoogleUtilities/AppDelegateSwizzler (8.1.0):
|
||||||
|
- GoogleUtilities/Environment
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- GoogleUtilities/Network
|
||||||
|
- GoogleUtilities/Privacy
|
||||||
- GoogleUtilities/Environment (8.1.0):
|
- GoogleUtilities/Environment (8.1.0):
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- GoogleUtilities/Logger (8.1.0):
|
- GoogleUtilities/Logger (8.1.0):
|
||||||
- GoogleUtilities/Environment
|
- GoogleUtilities/Environment
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
|
- GoogleUtilities/Network (8.1.0):
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- "GoogleUtilities/NSData+zlib"
|
||||||
|
- GoogleUtilities/Privacy
|
||||||
|
- GoogleUtilities/Reachability
|
||||||
- "GoogleUtilities/NSData+zlib (8.1.0)":
|
- "GoogleUtilities/NSData+zlib (8.1.0)":
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- GoogleUtilities/Privacy (8.1.0)
|
- GoogleUtilities/Privacy (8.1.0)
|
||||||
|
- GoogleUtilities/Reachability (8.1.0):
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- GoogleUtilities/Privacy
|
||||||
|
- GoogleUtilities/UserDefaults (8.1.0):
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- GoogleUtilities/Privacy
|
||||||
- "gRPC-C++ (1.69.0)":
|
- "gRPC-C++ (1.69.0)":
|
||||||
- "gRPC-C++/Implementation (= 1.69.0)"
|
- "gRPC-C++/Implementation (= 1.69.0)"
|
||||||
- "gRPC-C++/Interface (= 1.69.0)"
|
- "gRPC-C++/Interface (= 1.69.0)"
|
||||||
|
|
@ -1341,12 +1389,15 @@ PODS:
|
||||||
- gRPC-Core/Privacy (= 1.69.0)
|
- gRPC-Core/Privacy (= 1.69.0)
|
||||||
- gRPC-Core/Interface (1.69.0)
|
- gRPC-Core/Interface (1.69.0)
|
||||||
- gRPC-Core/Privacy (1.69.0)
|
- gRPC-Core/Privacy (1.69.0)
|
||||||
|
- GTMSessionFetcher/Core (5.1.0)
|
||||||
- leveldb-library (1.22.6)
|
- leveldb-library (1.22.6)
|
||||||
- nanopb (3.30910.0):
|
- nanopb (3.30910.0):
|
||||||
- nanopb/decode (= 3.30910.0)
|
- nanopb/decode (= 3.30910.0)
|
||||||
- nanopb/encode (= 3.30910.0)
|
- nanopb/encode (= 3.30910.0)
|
||||||
- nanopb/decode (3.30910.0)
|
- nanopb/decode (3.30910.0)
|
||||||
- nanopb/encode (3.30910.0)
|
- nanopb/encode (3.30910.0)
|
||||||
|
- PromisesObjC (2.4.0)
|
||||||
|
- RecaptchaInterop (101.0.0)
|
||||||
- share_plus (0.0.1):
|
- share_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- shared_preferences_foundation (0.0.1):
|
- shared_preferences_foundation (0.0.1):
|
||||||
|
|
@ -1357,6 +1408,8 @@ DEPENDENCIES:
|
||||||
- app_links (from `.symlinks/plugins/app_links/ios`)
|
- app_links (from `.symlinks/plugins/app_links/ios`)
|
||||||
- audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/ios`)
|
- audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/ios`)
|
||||||
- cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`)
|
- cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`)
|
||||||
|
- firebase_app_check (from `.symlinks/plugins/firebase_app_check/ios`)
|
||||||
|
- firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
|
||||||
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
|
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||||
|
|
@ -1365,9 +1418,13 @@ DEPENDENCIES:
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- abseil
|
- abseil
|
||||||
|
- AppCheckCore
|
||||||
- BoringSSL-GRPC
|
- BoringSSL-GRPC
|
||||||
- Firebase
|
- Firebase
|
||||||
|
- FirebaseAppCheck
|
||||||
- FirebaseAppCheckInterop
|
- FirebaseAppCheckInterop
|
||||||
|
- FirebaseAuth
|
||||||
|
- FirebaseAuthInterop
|
||||||
- FirebaseCore
|
- FirebaseCore
|
||||||
- FirebaseCoreExtension
|
- FirebaseCoreExtension
|
||||||
- FirebaseCoreInternal
|
- FirebaseCoreInternal
|
||||||
|
|
@ -1377,8 +1434,11 @@ SPEC REPOS:
|
||||||
- GoogleUtilities
|
- GoogleUtilities
|
||||||
- "gRPC-C++"
|
- "gRPC-C++"
|
||||||
- gRPC-Core
|
- gRPC-Core
|
||||||
|
- GTMSessionFetcher
|
||||||
- leveldb-library
|
- leveldb-library
|
||||||
- nanopb
|
- nanopb
|
||||||
|
- PromisesObjC
|
||||||
|
- RecaptchaInterop
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
app_links:
|
app_links:
|
||||||
|
|
@ -1387,6 +1447,10 @@ EXTERNAL SOURCES:
|
||||||
:path: ".symlinks/plugins/audioplayers_darwin/ios"
|
:path: ".symlinks/plugins/audioplayers_darwin/ios"
|
||||||
cloud_firestore:
|
cloud_firestore:
|
||||||
:path: ".symlinks/plugins/cloud_firestore/ios"
|
:path: ".symlinks/plugins/cloud_firestore/ios"
|
||||||
|
firebase_app_check:
|
||||||
|
:path: ".symlinks/plugins/firebase_app_check/ios"
|
||||||
|
firebase_auth:
|
||||||
|
:path: ".symlinks/plugins/firebase_auth/ios"
|
||||||
firebase_core:
|
firebase_core:
|
||||||
:path: ".symlinks/plugins/firebase_core/ios"
|
:path: ".symlinks/plugins/firebase_core/ios"
|
||||||
Flutter:
|
Flutter:
|
||||||
|
|
@ -1399,24 +1463,33 @@ EXTERNAL SOURCES:
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
abseil: a05cc83bf02079535e17169a73c5be5ba47f714b
|
abseil: a05cc83bf02079535e17169a73c5be5ba47f714b
|
||||||
app_links: a754cbec3c255bd4bbb4d236ecc06f28cd9a7ce8
|
app_links: a754cbec3c255bd4bbb4d236ecc06f28cd9a7ce8
|
||||||
|
AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f
|
||||||
audioplayers_darwin: ccf9c770ee768abb07e26d90af093f7bab1c12ab
|
audioplayers_darwin: ccf9c770ee768abb07e26d90af093f7bab1c12ab
|
||||||
BoringSSL-GRPC: dded2a44897e45f28f08ae87a55ee4bcd19bc508
|
BoringSSL-GRPC: dded2a44897e45f28f08ae87a55ee4bcd19bc508
|
||||||
cloud_firestore: 4bd00c3464706d9e09dabac0bb8e9610456109f5
|
cloud_firestore: 81f6c428ecee874dc3808afe0e0c48a87beb5bdf
|
||||||
Firebase: 9a58fdbc9d8655ed7b79a19cf9690bb007d3d46d
|
Firebase: 065f2bb395062046623036d8e6dc857bc2521d56
|
||||||
firebase_core: ee30637e6744af8e0c12a6a1e8a9718506ec2398
|
firebase_app_check: 33f1df6830ec8ebadee0db0120956c44a65c7213
|
||||||
FirebaseAppCheckInterop: ba3dc604a89815379e61ec2365101608d365cf7d
|
firebase_auth: fecf9fe293464b52063f5f2a7110e63ff2ab3403
|
||||||
FirebaseCore: 0dbad74bda10b8fb9ca34ad8f375fb9dd3ebef7c
|
firebase_core: afac1aac13c931e0401c7e74ed1276112030efab
|
||||||
FirebaseCoreExtension: 6605938d51f765d8b18bfcafd2085276a252bee2
|
FirebaseAppCheck: 94dae4d9bb682bdef85a778b0c1024a4613f1e89
|
||||||
FirebaseCoreInternal: fe5fa466aeb314787093a7dce9f0beeaad5a2a21
|
FirebaseAppCheckInterop: 4bade10286cc977e516f75d2d8312cbdfa534789
|
||||||
FirebaseFirestore: 67f23000ca238ccbab79127ed59636a9a2689e74
|
FirebaseAuth: 3a39f6436c21ebfd7919b698228b4f89ff94c23b
|
||||||
FirebaseFirestoreInternal: a0e7382af3d208898dcd1d4d52d8a7870632e881
|
FirebaseAuthInterop: f8f6ff72dc24621906497fbe5cf3c42ee815e59c
|
||||||
FirebaseSharedSwift: f57ed48f4542b2d7eb4738f4f23ba443f78b3780
|
FirebaseCore: 428912f751178b06bef0a1793effeb4a5e09a9b8
|
||||||
|
FirebaseCoreExtension: e911052d59cd0da237a45d706fc0f81654f035c1
|
||||||
|
FirebaseCoreInternal: b321eafae5362113bc182956fafc9922cfc77b72
|
||||||
|
FirebaseFirestore: d8b76ca1feb4ca0b0f078c45f7d1bd8014a49ef1
|
||||||
|
FirebaseFirestoreInternal: 02341a9ba87f6309227b04685022a5e16307bbf7
|
||||||
|
FirebaseSharedSwift: 9d2fa84a46676302b89dbd5e6e62bce2fe376909
|
||||||
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
||||||
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
||||||
"gRPC-C++": cc207623316fb041a7a3e774c252cf68a058b9e8
|
"gRPC-C++": cc207623316fb041a7a3e774c252cf68a058b9e8
|
||||||
gRPC-Core: 860978b7db482de8b4f5e10677216309b5ff6330
|
gRPC-Core: 860978b7db482de8b4f5e10677216309b5ff6330
|
||||||
|
GTMSessionFetcher: b8ab00db932816e14b0a0664a08cb73dda6d164b
|
||||||
leveldb-library: cc8b8f8e013647a295ad3f8cd2ddf49a6f19be19
|
leveldb-library: cc8b8f8e013647a295ad3f8cd2ddf49a6f19be19
|
||||||
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||||
|
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||||
|
RecaptchaInterop: 11e0b637842dfb48308d242afc3f448062325aba
|
||||||
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
||||||
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
|
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -912,10 +912,10 @@ class _HomeScreenState extends State<HomeScreen> with WidgetsBindingObserver {
|
||||||
final docs = snapshot.data!.docs;
|
final docs = snapshot.data!.docs;
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
physics: const BouncingScrollPhysics(),
|
physics: const BouncingScrollPhysics(),
|
||||||
|
itemCount: docs.length, // <--- ECCO LA RIGA MAGICA AGGIUNTA!
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
var data = docs[index].data() as Map<String, dynamic>;
|
var data = docs[index].data() as Map<String, dynamic>;
|
||||||
|
|
||||||
// Ora controlliamo se l'ID del documento su Firebase è uguale al nostro ID segreto!
|
|
||||||
String? myUid = FirebaseAuth.instance.currentUser?.uid;
|
String? myUid = FirebaseAuth.instance.currentUser?.uid;
|
||||||
bool isMe = docs[index].id == myUid;
|
bool isMe = docs[index].id == myUid;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -411,7 +411,7 @@ class _NeonActionButton extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (themeType == AppThemeType.doodle) {
|
if (themeType == AppThemeType.doodle) {
|
||||||
double tilt = (label == "UNISCITI") ? -0.015 : 0.02;
|
double tilt = (label == "UNISCITI" || label == "ANNULLA") ? -0.015 : 0.02;
|
||||||
return Transform.rotate(
|
return Transform.rotate(
|
||||||
angle: tilt,
|
angle: tilt,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
|
|
@ -428,7 +428,13 @@ class _NeonActionButton extends StatelessWidget {
|
||||||
boxShadow: [BoxShadow(color: theme.text.withOpacity(0.9), offset: const Offset(4, 4), blurRadius: 0)],
|
boxShadow: [BoxShadow(color: theme.text.withOpacity(0.9), offset: const Offset(4, 4), blurRadius: 0)],
|
||||||
),
|
),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(label, style: _getTextStyle(themeType, const TextStyle(fontSize: 20, fontWeight: FontWeight.w900, letterSpacing: 3.0, color: Colors.white))),
|
child: FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||||
|
child: Text(label, style: _getTextStyle(themeType, const TextStyle(fontSize: 20, fontWeight: FontWeight.w900, letterSpacing: 3.0, color: Colors.white))),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -449,7 +455,13 @@ class _NeonActionButton extends StatelessWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(label, style: _getTextStyle(themeType, const TextStyle(fontSize: 16, fontWeight: FontWeight.w900, letterSpacing: 2.0, color: Colors.white, shadows: [Shadow(color: Colors.black, blurRadius: 2, offset: Offset(1, 1))]))),
|
child: FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||||
|
child: Text(label, style: _getTextStyle(themeType, const TextStyle(fontSize: 16, fontWeight: FontWeight.w900, letterSpacing: 2.0, color: Colors.white, shadows: [Shadow(color: Colors.black, blurRadius: 2, offset: Offset(1, 1))]))),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -512,7 +524,6 @@ class _CyberBorderPainter extends CustomPainter {
|
||||||
bool shouldRepaint(covariant _CyberBorderPainter oldDelegate) => oldDelegate.animationValue != animationValue;
|
bool shouldRepaint(covariant _CyberBorderPainter oldDelegate) => oldDelegate.animationValue != animationValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NUOVO: Aggiunto WidgetsBindingObserver per intercettare l'app in background
|
|
||||||
class LobbyScreen extends StatefulWidget {
|
class LobbyScreen extends StatefulWidget {
|
||||||
final String? initialRoomCode;
|
final String? initialRoomCode;
|
||||||
|
|
||||||
|
|
@ -530,17 +541,20 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
String? _myRoomCode;
|
String? _myRoomCode;
|
||||||
String _playerName = '';
|
String _playerName = '';
|
||||||
|
|
||||||
|
// Variabile per gestire l'effetto "sipario"
|
||||||
|
bool _isCreatingRoom = false;
|
||||||
|
|
||||||
int _selectedRadius = 4;
|
int _selectedRadius = 4;
|
||||||
ArenaShape _selectedShape = ArenaShape.classic;
|
ArenaShape _selectedShape = ArenaShape.classic;
|
||||||
bool _isTimeMode = true;
|
bool _isTimeMode = true;
|
||||||
bool _isPublicRoom = true;
|
bool _isPublicRoom = true;
|
||||||
|
|
||||||
bool _roomStarted = false; // Flag per capire se il gioco è effettivamente iniziato
|
bool _roomStarted = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
WidgetsBinding.instance.addObserver(this); // Attiviamo la sentinella
|
WidgetsBinding.instance.addObserver(this);
|
||||||
_codeController = TextEditingController();
|
_codeController = TextEditingController();
|
||||||
_playerName = StorageService.instance.playerName;
|
_playerName = StorageService.instance.playerName;
|
||||||
|
|
||||||
|
|
@ -553,13 +567,12 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
WidgetsBinding.instance.removeObserver(this); // Rimuoviamo la sentinella
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
_cleanupGhostRoom(); // Se l'utente chiude la schermata, spazziamo via la stanza
|
_cleanupGhostRoom();
|
||||||
_codeController.dispose();
|
_codeController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intercetta quando l'app viene messa in background o chiusa!
|
|
||||||
@override
|
@override
|
||||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||||
if (state == AppLifecycleState.paused || state == AppLifecycleState.detached) {
|
if (state == AppLifecycleState.paused || state == AppLifecycleState.detached) {
|
||||||
|
|
@ -567,11 +580,10 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// La funzione "Spazzino"
|
|
||||||
void _cleanupGhostRoom() {
|
void _cleanupGhostRoom() {
|
||||||
if (_myRoomCode != null && !_roomStarted) {
|
if (_myRoomCode != null && !_roomStarted) {
|
||||||
FirebaseFirestore.instance.collection('games').doc(_myRoomCode).delete();
|
FirebaseFirestore.instance.collection('games').doc(_myRoomCode).delete();
|
||||||
_myRoomCode = null; // Evitiamo che venga chiamata due volte
|
_myRoomCode = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -692,7 +704,7 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
if (snapshot.hasData && snapshot.data!.exists) {
|
if (snapshot.hasData && snapshot.data!.exists) {
|
||||||
var data = snapshot.data!.data() as Map<String, dynamic>;
|
var data = snapshot.data!.data() as Map<String, dynamic>;
|
||||||
if (data['status'] == 'playing') {
|
if (data['status'] == 'playing') {
|
||||||
_roomStarted = true; // Il gioco è iniziato, non dobbiamo più cancellare la stanza!
|
_roomStarted = true;
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
context.read<GameController>().startNewGame(_selectedRadius, isOnline: true, roomCode: code, isHost: true, shape: _selectedShape, timeMode: _isTimeMode);
|
context.read<GameController>().startNewGame(_selectedRadius, isOnline: true, roomCode: code, isHost: true, shape: _selectedShape, timeMode: _isTimeMode);
|
||||||
|
|
@ -701,12 +713,11 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NUOVO: PopScope intercetta lo swipe indietro e il tasto back di Android
|
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: false,
|
canPop: false,
|
||||||
onPopInvoked: (didPop) {
|
onPopInvoked: (didPop) {
|
||||||
if (didPop) return;
|
if (didPop) return;
|
||||||
_cleanupGhostRoom(); // Spazza via la stanza se l'utente striscia per tornare indietro
|
_cleanupGhostRoom();
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
child: Dialog(
|
child: Dialog(
|
||||||
|
|
@ -719,7 +730,7 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_cleanupGhostRoom(); // Spazza via la stanza se clicca ANNULLA
|
_cleanupGhostRoom();
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
child: Text("ANNULLA", style: _getTextStyle(themeType, TextStyle(color: Colors.red, fontWeight: FontWeight.w900, fontSize: 20, letterSpacing: 2.0, shadows: themeType == AppThemeType.doodle ? [] : [const Shadow(color: Colors.black, blurRadius: 2)]))),
|
child: Text("ANNULLA", style: _getTextStyle(themeType, TextStyle(color: Colors.red, fontWeight: FontWeight.w900, fontSize: 20, letterSpacing: 2.0, shadows: themeType == AppThemeType.doodle ? [] : [const Shadow(color: Colors.black, blurRadius: 2)]))),
|
||||||
|
|
@ -746,9 +757,9 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
if (themeType == AppThemeType.cyberpunk) bgImage = 'assets/images/cyber_bg.jpg';
|
if (themeType == AppThemeType.cyberpunk) bgImage = 'assets/images/cyber_bg.jpg';
|
||||||
|
|
||||||
bool isChaosUnlocked = true;
|
bool isChaosUnlocked = true;
|
||||||
|
|
||||||
Color doodlePenColor = const Color(0xFF00008B);
|
Color doodlePenColor = const Color(0xFF00008B);
|
||||||
|
|
||||||
|
// --- PANNELLO IMPOSTAZIONI STANZA ---
|
||||||
Widget hostPanel = Transform.rotate(
|
Widget hostPanel = Transform.rotate(
|
||||||
angle: themeType == AppThemeType.doodle ? 0.01 : 0,
|
angle: themeType == AppThemeType.doodle ? 0.01 : 0,
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|
@ -823,7 +834,9 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
|
|
||||||
Widget uiContent = SafeArea(
|
Widget uiContent = SafeArea(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
|
physics: const BouncingScrollPhysics(),
|
||||||
|
// Padding inferiore aumentato a 60 per evitare il taglio dei pulsanti
|
||||||
|
padding: EdgeInsets.only(left: 20.0, right: 20.0, top: 10.0, bottom: MediaQuery.of(context).padding.bottom + 60.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -850,49 +863,76 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
hostPanel,
|
|
||||||
const SizedBox(height: 15),
|
|
||||||
_NeonActionButton(label: "CREA PARTITA", color: theme.playerRed, onTap: _createRoom, theme: theme, themeType: themeType),
|
|
||||||
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Expanded(child: Divider(color: theme.text.withOpacity(0.4), thickness: themeType == AppThemeType.doodle ? 2 : 1.0)),
|
|
||||||
Padding(padding: const EdgeInsets.symmetric(horizontal: 10), child: Text("OPPURE", style: _getTextStyle(themeType, TextStyle(color: themeType == AppThemeType.doodle ? theme.text : theme.text.withOpacity(0.5), fontWeight: FontWeight.bold, letterSpacing: 2.0, fontSize: 13)))),
|
|
||||||
Expanded(child: Divider(color: theme.text.withOpacity(0.4), thickness: themeType == AppThemeType.doodle ? 2 : 1.0)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
Transform.rotate(
|
// --- L'EFFETTO SIPARIO CON ANIMATED SIZE ---
|
||||||
angle: themeType == AppThemeType.doodle ? 0.02 : 0,
|
AnimatedSize(
|
||||||
child: Container(
|
duration: const Duration(milliseconds: 300),
|
||||||
decoration: themeType == AppThemeType.doodle ? BoxDecoration(
|
curve: Curves.easeInOut,
|
||||||
color: Colors.white,
|
alignment: Alignment.topCenter,
|
||||||
borderRadius: const BorderRadius.only(topLeft: Radius.circular(20), bottomRight: Radius.circular(20), topRight: Radius.circular(5), bottomLeft: Radius.circular(5)),
|
child: _isCreatingRoom
|
||||||
border: Border.all(color: theme.text, width: 2.5),
|
? Column( // MENU CREAZIONE (Aperto)
|
||||||
boxShadow: [BoxShadow(color: theme.text.withOpacity(0.8), offset: const Offset(5, 5), blurRadius: 0)],
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
) : BoxDecoration(
|
children: [
|
||||||
boxShadow: [BoxShadow(color: theme.playerBlue.withOpacity(0.15), blurRadius: 15, spreadRadius: 1)]
|
hostPanel,
|
||||||
),
|
const SizedBox(height: 15),
|
||||||
child: TextField(
|
Row(
|
||||||
controller: _codeController, textCapitalization: TextCapitalization.characters, textAlign: TextAlign.center, maxLength: 5,
|
children: [
|
||||||
style: _getTextStyle(themeType, TextStyle(fontSize: 28, fontWeight: FontWeight.w900, color: theme.text, letterSpacing: 12, shadows: themeType == AppThemeType.doodle ? [] : [Shadow(color: theme.playerBlue.withOpacity(0.5), blurRadius: 8)])),
|
Expanded( // Entrambi in un Expanded "liscio" si dividono il 50% di spazio
|
||||||
decoration: InputDecoration(
|
child: _NeonActionButton(label: "AVVIA", color: theme.playerRed, onTap: _createRoom, theme: theme, themeType: themeType),
|
||||||
contentPadding: const EdgeInsets.symmetric(vertical: 12),
|
),
|
||||||
hintText: "CODICE", hintStyle: _getTextStyle(themeType, TextStyle(color: theme.text.withOpacity(0.3), letterSpacing: 10, fontSize: 20)), counterText: "",
|
const SizedBox(width: 10),
|
||||||
filled: themeType != AppThemeType.doodle,
|
Expanded( // Entrambi in un Expanded "liscio" si dividono il 50% di spazio
|
||||||
fillColor: themeType == AppThemeType.cyberpunk ? Colors.black.withOpacity(0.85) : theme.text.withOpacity(0.05),
|
child: _NeonActionButton(label: "ANNULLA", color: Colors.grey.shade600, onTap: () => setState(() => _isCreatingRoom = false), theme: theme, themeType: themeType),
|
||||||
enabledBorder: themeType == AppThemeType.doodle ? InputBorder.none : OutlineInputBorder(borderSide: BorderSide(color: theme.gridLine.withOpacity(0.5), width: 2.0), borderRadius: BorderRadius.circular(15)),
|
),
|
||||||
focusedBorder: themeType == AppThemeType.doodle ? InputBorder.none : OutlineInputBorder(borderSide: BorderSide(color: theme.playerBlue, width: 3.0), borderRadius: BorderRadius.circular(15)),
|
],
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
|
)
|
||||||
|
: Column( // MENU BASE (Chiuso)
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
_NeonActionButton(label: "CREA PARTITA", color: theme.playerRed, onTap: () { FocusScope.of(context).unfocus(); setState(() => _isCreatingRoom = true); }, theme: theme, themeType: themeType),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(child: Divider(color: theme.text.withOpacity(0.4), thickness: themeType == AppThemeType.doodle ? 2 : 1.0)),
|
||||||
|
Padding(padding: const EdgeInsets.symmetric(horizontal: 10), child: Text("OPPURE", style: _getTextStyle(themeType, TextStyle(color: themeType == AppThemeType.doodle ? theme.text : theme.text.withOpacity(0.5), fontWeight: FontWeight.bold, letterSpacing: 2.0, fontSize: 13)))),
|
||||||
|
Expanded(child: Divider(color: theme.text.withOpacity(0.4), thickness: themeType == AppThemeType.doodle ? 2 : 1.0)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
|
Transform.rotate(
|
||||||
|
angle: themeType == AppThemeType.doodle ? 0.02 : 0,
|
||||||
|
child: Container(
|
||||||
|
decoration: themeType == AppThemeType.doodle ? BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: const BorderRadius.only(topLeft: Radius.circular(20), bottomRight: Radius.circular(20), topRight: Radius.circular(5), bottomLeft: Radius.circular(5)),
|
||||||
|
border: Border.all(color: theme.text, width: 2.5),
|
||||||
|
boxShadow: [BoxShadow(color: theme.text.withOpacity(0.8), offset: const Offset(5, 5), blurRadius: 0)],
|
||||||
|
) : BoxDecoration(
|
||||||
|
boxShadow: [BoxShadow(color: theme.playerBlue.withOpacity(0.15), blurRadius: 15, spreadRadius: 1)]
|
||||||
|
),
|
||||||
|
child: TextField(
|
||||||
|
controller: _codeController, textCapitalization: TextCapitalization.characters, textAlign: TextAlign.center, maxLength: 5,
|
||||||
|
style: _getTextStyle(themeType, TextStyle(fontSize: 28, fontWeight: FontWeight.w900, color: theme.text, letterSpacing: 12, shadows: themeType == AppThemeType.doodle ? [] : [Shadow(color: theme.playerBlue.withOpacity(0.5), blurRadius: 8)])),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
hintText: "CODICE", hintStyle: _getTextStyle(themeType, TextStyle(color: theme.text.withOpacity(0.3), letterSpacing: 10, fontSize: 20)), counterText: "",
|
||||||
|
filled: themeType != AppThemeType.doodle,
|
||||||
|
fillColor: themeType == AppThemeType.cyberpunk ? Colors.black.withOpacity(0.85) : theme.text.withOpacity(0.05),
|
||||||
|
enabledBorder: themeType == AppThemeType.doodle ? InputBorder.none : OutlineInputBorder(borderSide: BorderSide(color: theme.gridLine.withOpacity(0.5), width: 2.0), borderRadius: BorderRadius.circular(15)),
|
||||||
|
focusedBorder: themeType == AppThemeType.doodle ? InputBorder.none : OutlineInputBorder(borderSide: BorderSide(color: theme.playerBlue, width: 3.0), borderRadius: BorderRadius.circular(15)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 15),
|
||||||
|
_NeonActionButton(label: "UNISCITI", color: theme.playerBlue, onTap: () => _joinRoomByCode(_codeController.text), theme: theme, themeType: themeType),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 15),
|
|
||||||
_NeonActionButton(label: "UNISCITI", color: theme.playerBlue, onTap: () => _joinRoomByCode(_codeController.text), theme: theme, themeType: themeType),
|
|
||||||
|
|
||||||
const SizedBox(height: 25),
|
const SizedBox(height: 25),
|
||||||
Row(
|
Row(
|
||||||
|
|
@ -919,20 +959,14 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
DateTime now = DateTime.now(); // Tempo attuale
|
DateTime now = DateTime.now();
|
||||||
String? myUid = FirebaseAuth.instance.currentUser?.uid;
|
String? myUid = FirebaseAuth.instance.currentUser?.uid;
|
||||||
|
|
||||||
// FILTRO LOCALE E SCADENZA (15 MINUTI)
|
|
||||||
var docs = snapshot.data!.docs.where((doc) {
|
var docs = snapshot.data!.docs.where((doc) {
|
||||||
var data = doc.data() as Map<String, dynamic>;
|
var data = doc.data() as Map<String, dynamic>;
|
||||||
|
|
||||||
// 1. Deve essere pubblica
|
|
||||||
if (data['isPublic'] != true) return false;
|
if (data['isPublic'] != true) return false;
|
||||||
|
|
||||||
// 2. Non devo vedere la mia stessa stanza
|
|
||||||
if (data['hostUid'] != null && data['hostUid'] == myUid) return false;
|
if (data['hostUid'] != null && data['hostUid'] == myUid) return false;
|
||||||
|
|
||||||
// 3. Non deve essere una "Stanza Fantasma" (più vecchia di 15 minuti)
|
|
||||||
Timestamp? createdAt = data['createdAt'] as Timestamp?;
|
Timestamp? createdAt = data['createdAt'] as Timestamp?;
|
||||||
if (createdAt != null) {
|
if (createdAt != null) {
|
||||||
int ageInMinutes = now.difference(createdAt.toDate()).inMinutes;
|
int ageInMinutes = now.difference(createdAt.toDate()).inMinutes;
|
||||||
|
|
@ -941,7 +975,7 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true; // Se passa i test, mostrala!
|
return true;
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
if (docs.isEmpty) {
|
if (docs.isEmpty) {
|
||||||
|
|
@ -951,7 +985,6 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ordiniamo le stanze valide dalla più recente
|
|
||||||
docs.sort((a, b) {
|
docs.sort((a, b) {
|
||||||
Timestamp? tA = (a.data() as Map<String, dynamic>)['createdAt'] as Timestamp?;
|
Timestamp? tA = (a.data() as Map<String, dynamic>)['createdAt'] as Timestamp?;
|
||||||
Timestamp? tB = (b.data() as Map<String, dynamic>)['createdAt'] as Timestamp?;
|
Timestamp? tB = (b.data() as Map<String, dynamic>)['createdAt'] as Timestamp?;
|
||||||
|
|
@ -972,7 +1005,6 @@ class _LobbyScreenState extends State<LobbyScreen> with WidgetsBindingObserver {
|
||||||
String shapeStr = data['shape'] ?? 'classic';
|
String shapeStr = data['shape'] ?? 'classic';
|
||||||
bool time = data['timeMode'] ?? true;
|
bool time = data['timeMode'] ?? true;
|
||||||
|
|
||||||
// Formattazione del nome della forma
|
|
||||||
String prettyShape = "Rombo";
|
String prettyShape = "Rombo";
|
||||||
if (shapeStr == 'cross') prettyShape = "Croce";
|
if (shapeStr == 'cross') prettyShape = "Croce";
|
||||||
else if (shapeStr == 'donut') prettyShape = "Buco";
|
else if (shapeStr == 'donut') prettyShape = "Buco";
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
name: tetraq
|
name: tetraq
|
||||||
description: A new Flutter project.
|
description: A new Flutter project.
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
version: 1.1.3+5
|
version: 1.1.4+6
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.10.7
|
sdk: ^3.10.7
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue