From dc5ec440bd464fc6555dc98fc4909e19a184bfbb Mon Sep 17 00:00:00 2001 From: 10dine Date: Fri, 20 Dec 2024 00:55:57 -0500 Subject: [PATCH] refact: various clean up --- src/client/lib/main.dart | 4 + src/client/lib/models/game.dart | 8 +- src/client/lib/pages/home.dart | 79 +++++++++++++++++-- src/client/lib/pages/score.dart | 9 --- src/client/lib/pages/settings.dart | 16 +++- .../lib/widgets/leaderboard_entry_pill.dart | 2 +- 6 files changed, 96 insertions(+), 22 deletions(-) diff --git a/src/client/lib/main.dart b/src/client/lib/main.dart index 773d294..0438c59 100644 --- a/src/client/lib/main.dart +++ b/src/client/lib/main.dart @@ -15,6 +15,9 @@ import 'routes.dart'; final ValueNotifier themeNotifier = ValueNotifier(ThemeMode.system); List cameras = []; bool soundEnabled = true; +bool globeEnabled = true; +const String globeLight = 'assets/2k_earth-day.jpg'; +const String globeDark = 'assets/2k_earth-night.jpg'; enum RoomState { none, wait, owner, joiner } final ValueNotifier roomState = ValueNotifier(RoomState.none); @@ -75,6 +78,7 @@ class _SplashScreenState extends State { await Future.delayed(Duration(seconds: 2)); // Optional delay for better UX final prefs = await SharedPreferences.getInstance(); String? sessionId = prefs.getString('x-auth-token'); + globeEnabled = prefs.getBool('globeEnabled') ?? true; if (sessionId != null) { currentUser = User(username: prefs.getString('username'), sessionId: prefs.getString('sessionId')); diff --git a/src/client/lib/models/game.dart b/src/client/lib/models/game.dart index 77fa5ae..188a3d1 100644 --- a/src/client/lib/models/game.dart +++ b/src/client/lib/models/game.dart @@ -56,8 +56,12 @@ class Game{ //TODO: when backend is sending back generalized locations of users send //back a map of usernames and coordinates - List getPlayers(){ - return playerInfo.keys.toList(); + List getPlayers(){ + return playerInfo.entries.map((e) => e.value['username']).toList(); + } + + int getNumPlayers(){ + return playerInfo.length; } //TODO: when backend is update with round logic and multiplayer customization diff --git a/src/client/lib/pages/home.dart b/src/client/lib/pages/home.dart index 4867ea6..aed0b2c 100644 --- a/src/client/lib/pages/home.dart +++ b/src/client/lib/pages/home.dart @@ -1,17 +1,18 @@ import 'dart:async'; - -import 'package:direction_guesser/widgets/leaderboard_card.dart'; import 'package:direction_guesser/widgets/points_pill.dart'; import 'package:direction_guesser/widgets/permissions_denied_card.dart'; import 'package:direction_guesser/widgets/missing_device_card.dart'; import 'package:direction_guesser/controllers/user_services.dart'; import 'package:direction_guesser/controllers/game_services.dart'; +import 'package:flutter_earth_globe/globe_coordinates.dart'; +import 'package:flutter_earth_globe/point.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:geolocator/geolocator.dart'; import 'package:flutter_earth_globe/flutter_earth_globe.dart'; import 'package:flutter_earth_globe/flutter_earth_globe_controller.dart'; +import 'dart:math'; import '../main.dart'; import '../widgets/text_entry_pill.dart'; @@ -32,28 +33,35 @@ class _HomePageState extends State { ValueNotifier permissionState = ValueNotifier(PermissionsState.okay); late AppLifecycleListener lifecycleListener; + String globeMode = globeDark; late FlutterEarthGlobeController globeController = FlutterEarthGlobeController( isRotating: true, rotationSpeed: 0.05, - surface: Image.asset('assets/2k_earth-night.jpg').image); + surface: Image.asset(globeMode).image); String roomCode = ""; int playersInRoom = 0; + final random = Random(); + @override initState() { super.initState(); + // + globeMode = themeNotifier.value == ThemeMode.dark ? globeDark : globeLight; globeController = FlutterEarthGlobeController( isRotating: true, rotationSpeed: 0.05, - surface: Image.asset('assets/2k_earth-night.jpg').image, + surface: Image.asset(globeMode).image, background: Image.asset('assets/2k_stars.jpg').image ); lifecycleListener = AppLifecycleListener(onRestart: checkSensors); checkSensors(); } + @override + void _logout() async { bool success = await context.read().logoutUser(); if (success) { @@ -67,7 +75,10 @@ class _HomePageState extends State { void _getLobbyInfo() async { final prefs = await SharedPreferences.getInstance(); String lobbyName = prefs.getString('currentLobby') ?? ""; - await context.read().getLobbyInfo(); + Map currentLobbyInfo = await context.read().getLobbyInfo(); + currentGame.setLobbyUserInfo(currentLobbyInfo); + playersInRoom = currentGame.getPlayers().length; + //addUsersToGlobe(); setState(() {}); } @@ -136,6 +147,7 @@ class _HomePageState extends State { } } + //TODO: Refact/ Move all sensors to separate page and check on app start and on game begin void checkSensors() async { await Geolocator.checkPermission().then((permission) { if (permission == LocationPermission.deniedForever || @@ -155,6 +167,53 @@ class _HomePageState extends State { }); } + //Add users to globe + //TODO: When Backend is capable of sending general location data of user change + // now adds randomly + void addUsersToGlobe() { + List currentPoints = globeController.points; + List users = currentGame.getPlayers(); + //games starts and users are added + if (users.length == 0) { + for (String user in users) { + globeController.addPoint( + Point( + id: user, + label: user, + isLabelVisible: true, + coordinates: GlobeCoordinates(-90 + (random.nextDouble() * 180), -180 + (random.nextDouble() * 360)), + labelTextStyle: TextStyle(color: Colors.white)), + ); + } + } else { + //remove users that are no longer in the room + for (Point point in currentPoints) { + if (!users.contains(point.label)) { + globeController.removePoint(point.id); + } + } + //add users that are not in the room + for (String user in users) { + bool found = false; + for (Point point in currentPoints) { + if (point.label == user) { + found = true; + } + } + if (!found) { + globeController.addPoint( + Point( + id: user, + label: user, + isLabelVisible: true, + coordinates: GlobeCoordinates(-90 + (random.nextDouble() * 180), -180 + (random.nextDouble() * 360)), + labelTextStyle: TextStyle(color: Colors.white)), + ); + } + } + } + } + @override Widget build(BuildContext context) { return Container( @@ -200,13 +259,13 @@ class _HomePageState extends State { body: Stack( children: [ SafeArea( - child: FlutterEarthGlobe( + child: globeEnabled ? FlutterEarthGlobe( controller: globeController, radius: 60, //TODO: temporary fix globe is not centered //will need to inspect widget tree to see why alignment: Alignment(0, -0.4), - )), + ) : Container()), Padding( padding: EdgeInsets.all(8), child: Column( @@ -215,6 +274,8 @@ class _HomePageState extends State { SizedBox(height: 64), PointsPill(points: 15827), SizedBox(height: 32), + if (!globeEnabled) + Image.asset('assets/logo.png', height: 200), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -245,7 +306,9 @@ class _HomePageState extends State { FilledButton.tonal( onPressed: () => { Navigator.pushNamed( - context, '/settings') + context, '/settings').then((_) => { + setState(() {}) + }) }, child: Icon( Icons.settings_rounded, diff --git a/src/client/lib/pages/score.dart b/src/client/lib/pages/score.dart index 9dd8743..d145d61 100644 --- a/src/client/lib/pages/score.dart +++ b/src/client/lib/pages/score.dart @@ -25,12 +25,6 @@ class _ScorePageState extends State { setState(() {}); } - void _getLobbyInfo() async { - Map lobbyInfo = await context.read().getLobbyInfo(); - currentGame.setLobbyUserInfo(lobbyInfo); - setState(() {}); - } - void _getScore() async { SharedPreferences prefs = await SharedPreferences.getInstance(); setState(() { @@ -126,9 +120,6 @@ class _ScorePageState extends State { SizedBox(height: 16), FilledButton( onPressed: () { - if(currentGame.isMultiplayer) { - _getLobbyInfo(); - } currentGame.incrementRound(); if (currentGame.roundNumber >= currentGame.totalRounds) { if (currentGame.isMultiplayer) { diff --git a/src/client/lib/pages/settings.dart b/src/client/lib/pages/settings.dart index 55c0ea4..a6e589c 100644 --- a/src/client/lib/pages/settings.dart +++ b/src/client/lib/pages/settings.dart @@ -54,7 +54,7 @@ class _SettingsPageState extends State { mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox(height: 128), + SizedBox(height: 98), SizedBox( height: 280, width: 280, @@ -86,6 +86,18 @@ class _SettingsPageState extends State { Text("Dark Mode", style: mediumStyle) ]), Spacer(), + Row(children: [ + Switch( + value: globeEnabled, + onChanged: (bool value) { + setState(() { + globeEnabled = value; + }); + }), + SizedBox(width: 8), + Text("Enable 3d Globe", style: mediumStyle) + ]), + Spacer(), Row(children: [ Switch( value: soundEnabled, @@ -103,7 +115,7 @@ class _SettingsPageState extends State { Spacer(), FilledButton.tonal( onPressed: () { - Navigator.pushNamed(context, '/home'); + Navigator.pop(context); }, child: Icon( Icons.arrow_back_rounded, diff --git a/src/client/lib/widgets/leaderboard_entry_pill.dart b/src/client/lib/widgets/leaderboard_entry_pill.dart index f47d20b..9f999ee 100644 --- a/src/client/lib/widgets/leaderboard_entry_pill.dart +++ b/src/client/lib/widgets/leaderboard_entry_pill.dart @@ -107,7 +107,7 @@ class LeaderboardEntryPill extends StatelessWidget { ]), Column(children: [ Padding( - padding: EdgeInsets.symmetric(horizontal: 8), + padding: EdgeInsets.symmetric(horizontal: 24), child: Text( formatter.format(score), style: TextStyle(