added game status
This commit is contained in:
57
lib/widgets/GameState/CheckinState.dart
Normal file
57
lib/widgets/GameState/CheckinState.dart
Normal file
@ -0,0 +1,57 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rogapp/widgets/GameState/Colors.dart';
|
||||
|
||||
class LocationVisitedWidget extends StatelessWidget {
|
||||
final int count;
|
||||
final bool minimized;
|
||||
|
||||
const LocationVisitedWidget(
|
||||
{Key? key, required this.count, this.minimized = false})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (minimized) {
|
||||
return Container(
|
||||
height: 40,
|
||||
width: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: JapaneseColors.mizu,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'$count',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: JapaneseColors.matcha,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.check_circle_outline, color: Colors.white, size: 24),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'$count チェックイン', // "X Check-ins" in Japanese
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
lib/widgets/GameState/Colors.dart
Normal file
12
lib/widgets/GameState/Colors.dart
Normal file
@ -0,0 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class JapaneseColors {
|
||||
static const Color mizu = Color(0xFFA4DDED); // Mizu (light blue)
|
||||
static const Color matcha = Color(0xFFC5E1A5);
|
||||
static const Color ume = Color(0xFFE1A8A8); // Ume (plum)
|
||||
static const Color take = Color(0xFF7B8D42); // Take (bamboo)
|
||||
static const Color sora = Color(0xFFA1CAF1);
|
||||
static const Color indigo = Color(0xFF264653); // Aizome
|
||||
static const Color sakuraPink = Color(0xFFFAD2E1); // Sakura-iro
|
||||
/// Matcha (green tea)
|
||||
}
|
||||
72
lib/widgets/GameState/ConnectionStatus.dart
Normal file
72
lib/widgets/GameState/ConnectionStatus.dart
Normal file
@ -0,0 +1,72 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rogapp/widgets/GameState/Colors.dart';
|
||||
|
||||
enum ConnectionStatus { none, mobile, wifi }
|
||||
|
||||
class ConnectionStatusIndicator extends StatelessWidget {
|
||||
final ConnectionStatus connectionStatus;
|
||||
final bool minimized;
|
||||
|
||||
const ConnectionStatusIndicator({
|
||||
Key? key,
|
||||
required this.connectionStatus,
|
||||
this.minimized = false,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Color backgroundColor;
|
||||
IconData iconData;
|
||||
String text;
|
||||
|
||||
switch (connectionStatus) {
|
||||
case ConnectionStatus.none:
|
||||
backgroundColor = JapaneseColors.ume;
|
||||
iconData = Icons.signal_cellular_off;
|
||||
text = 'No Connection';
|
||||
break;
|
||||
case ConnectionStatus.mobile:
|
||||
backgroundColor = JapaneseColors.take;
|
||||
iconData = Icons.signal_cellular_alt;
|
||||
text = 'Mobile Data';
|
||||
break;
|
||||
case ConnectionStatus.wifi:
|
||||
backgroundColor = JapaneseColors.sora;
|
||||
iconData = Icons.wifi;
|
||||
text = 'Wi-Fi';
|
||||
break;
|
||||
default:
|
||||
backgroundColor = Colors.grey; // Fallback color
|
||||
iconData = Icons.device_unknown;
|
||||
text = 'Unknown';
|
||||
}
|
||||
|
||||
return Container(
|
||||
height: minimized ? 40 : null,
|
||||
width: minimized ? 40 : null,
|
||||
padding:
|
||||
minimized ? null : EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
shape: minimized ? BoxShape.circle : BoxShape.rectangle,
|
||||
borderRadius: minimized ? null : BorderRadius.circular(10),
|
||||
),
|
||||
child: minimized
|
||||
? Center(
|
||||
child: Icon(iconData, color: Colors.white, size: 24),
|
||||
)
|
||||
: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(iconData, color: Colors.white),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
color: Colors.white, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
51
lib/widgets/GameState/DashboardWidget.dart
Normal file
51
lib/widgets/GameState/DashboardWidget.dart
Normal file
@ -0,0 +1,51 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rogapp/widgets/GameState/CheckinState.dart';
|
||||
import 'package:rogapp/widgets/GameState/game_on_off.dart';
|
||||
|
||||
class DashboardWidget extends StatelessWidget {
|
||||
final bool gameStarted;
|
||||
final int locationsVisited;
|
||||
final bool isMinimized;
|
||||
|
||||
const DashboardWidget({
|
||||
Key? key,
|
||||
required this.gameStarted,
|
||||
required this.locationsVisited,
|
||||
this.isMinimized = false,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> widgets = [
|
||||
GameStatusIndicator(gameStarted: gameStarted, minimized: isMinimized),
|
||||
SizedBox(
|
||||
height: isMinimized ? 0 : 8, width: isMinimized ? 8 : 0), // Spacing
|
||||
LocationVisitedWidget(count: locationsVisited, minimized: isMinimized),
|
||||
];
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.all(isMinimized ? 8 : 16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset: Offset(0, 3),
|
||||
),
|
||||
],
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: isMinimized
|
||||
? Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: widgets,
|
||||
)
|
||||
: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: widgets,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
55
lib/widgets/GameState/game_on_off.dart
Normal file
55
lib/widgets/GameState/game_on_off.dart
Normal file
@ -0,0 +1,55 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rogapp/widgets/GameState/Colors.dart';
|
||||
|
||||
class GameStatusIndicator extends StatelessWidget {
|
||||
final bool gameStarted;
|
||||
final bool minimized;
|
||||
|
||||
const GameStatusIndicator(
|
||||
{Key? key, required this.gameStarted, this.minimized = true})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Icons to show based on the game status
|
||||
IconData iconData =
|
||||
gameStarted ? Icons.stop_circle : Icons.play_circle_filled;
|
||||
// Text to show based on the game status
|
||||
String text = gameStarted ? 'ゲーム開始' : 'ゲーム未開始';
|
||||
|
||||
// Layout for minimized view
|
||||
if (minimized) {
|
||||
return Container(
|
||||
height: 40, // Square size
|
||||
width: 40, // Square size
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
gameStarted ? JapaneseColors.indigo : JapaneseColors.sakuraPink,
|
||||
shape: BoxShape
|
||||
.circle, // Making it circle when minimized for a more distinct look
|
||||
),
|
||||
child: Icon(iconData, color: Colors.white),
|
||||
);
|
||||
}
|
||||
|
||||
// Layout for expanded view
|
||||
return Container(
|
||||
padding: EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: gameStarted ? JapaneseColors.indigo : JapaneseColors.sakuraPink,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(iconData, color: Colors.white),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
text,
|
||||
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
200
lib/widgets/game_state_view.dart
Normal file
200
lib/widgets/game_state_view.dart
Normal file
@ -0,0 +1,200 @@
|
||||
import 'dart:ffi';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rogapp/model/destination.dart';
|
||||
import 'package:rogapp/pages/destination/destination_controller.dart';
|
||||
import 'package:rogapp/pages/index/index_controller.dart';
|
||||
import 'package:rogapp/services/DatabaseService.dart';
|
||||
import 'package:rogapp/utils/database_helper.dart';
|
||||
import 'package:rogapp/widgets/GameState/CheckinState.dart';
|
||||
import 'package:rogapp/widgets/GameState/ConnectionStatus.dart';
|
||||
import 'package:rogapp/widgets/GameState/DashboardWidget.dart';
|
||||
import 'package:rogapp/widgets/GameState/game_on_off.dart';
|
||||
|
||||
class GameStateManager {
|
||||
static final GameStateManager _instance = GameStateManager._internal();
|
||||
|
||||
factory GameStateManager() {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
GameStateManager._internal();
|
||||
|
||||
List<String> _logs = [];
|
||||
List<VoidCallback> _listeners = [];
|
||||
|
||||
List<String> get logs => _logs;
|
||||
|
||||
void addLog(String log) {
|
||||
_logs.add(log);
|
||||
_notifyListeners(); // Notify all listeners
|
||||
}
|
||||
|
||||
void clearLogs() {
|
||||
_logs.clear();
|
||||
_notifyListeners(); // Notify all listeners
|
||||
}
|
||||
|
||||
void addListener(VoidCallback listener) {
|
||||
_listeners.add(listener);
|
||||
}
|
||||
|
||||
void removeListener(VoidCallback listener) {
|
||||
_listeners.remove(listener);
|
||||
}
|
||||
|
||||
void _notifyListeners() {
|
||||
for (var listener in _listeners) {
|
||||
listener();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GameStateWidget extends StatefulWidget {
|
||||
const GameStateWidget({super.key});
|
||||
|
||||
@override
|
||||
State<GameStateWidget> createState() => _GameStateWidgetState();
|
||||
}
|
||||
|
||||
class _GameStateWidgetState extends State<GameStateWidget> {
|
||||
final GameStateManager gameStateManager = GameStateManager();
|
||||
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
final DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
gameStateManager.addListener(_updateLogs);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
gameStateManager.removeListener(_updateLogs);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _updateLogs() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void toggleExpanded() {
|
||||
setState(() {
|
||||
isExpanded = !isExpanded;
|
||||
});
|
||||
}
|
||||
|
||||
void clearLogs() {
|
||||
gameStateManager.clearLogs();
|
||||
}
|
||||
|
||||
bool isExpanded = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final DatabaseService dbService = DatabaseService();
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
decoration: BoxDecoration(color: Colors.black12),
|
||||
child: GestureDetector(
|
||||
onTap: toggleExpanded,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
color: isExpanded ? Colors.black54 : Colors.black12,
|
||||
height: isExpanded ? 160.0 : 48.0, // Adjust sizes as needed
|
||||
child: Column(
|
||||
children: [
|
||||
// Top bar with clear button
|
||||
if (isExpanded)
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
color: Colors.blueGrey, // Adjust color as needed
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text('ゲームステータス', style: TextStyle(color: Colors.white)),
|
||||
IconButton(
|
||||
icon: Icon(Icons.clear, color: Colors.white),
|
||||
onPressed: toggleExpanded,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// Log messages
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Wrap(
|
||||
alignment: WrapAlignment.spaceEvenly,
|
||||
children: [
|
||||
Obx(() => Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: GameStatusIndicator(
|
||||
gameStarted: destinationController.isInRog.value,
|
||||
minimized: !isExpanded,
|
||||
),
|
||||
)),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: StreamBuilder<List<Destination>>(
|
||||
stream: dbService.destinationUpdatesStream,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState ==
|
||||
ConnectionState.waiting) {
|
||||
return const CircularProgressIndicator();
|
||||
} else if (snapshot.hasError) {
|
||||
return LocationVisitedWidget(
|
||||
count: 0,
|
||||
minimized: !isExpanded,
|
||||
);
|
||||
} else if (snapshot.hasData) {
|
||||
return LocationVisitedWidget(
|
||||
count: snapshot.data!.length,
|
||||
minimized: !isExpanded,
|
||||
);
|
||||
} else {
|
||||
return LocationVisitedWidget(
|
||||
count: 0,
|
||||
minimized: !isExpanded,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
// child: LocationVisitedWidget(
|
||||
// count:
|
||||
// minimized: !isExpanded,
|
||||
// ),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: ConnectionStatusIndicator(
|
||||
connectionStatus: ConnectionStatus.wifi,
|
||||
minimized: !isExpanded),
|
||||
) // Expanded view
|
||||
],
|
||||
),
|
||||
// child: Obx(
|
||||
// () => DashboardWidget(
|
||||
// gameStarted: destinationController.isInRog.value,
|
||||
// locationsVisited: 3,
|
||||
// isMinimized: false,
|
||||
// ),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -14,7 +14,7 @@ import 'package:rogapp/utils/database_helper.dart';
|
||||
import 'package:rogapp/utils/text_util.dart';
|
||||
import 'package:rogapp/widgets/base_layer_widget.dart';
|
||||
import 'package:rogapp/widgets/bottom_sheet_new.dart';
|
||||
import 'package:rogapp/widgets/debug_widget.dart';
|
||||
import 'package:rogapp/widgets/game_state_view.dart';
|
||||
|
||||
class MapWidget extends StatelessWidget {
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
@ -249,6 +249,7 @@ class MapWidget extends StatelessWidget {
|
||||
: const Center(child: CircularProgressIndicator()),
|
||||
],
|
||||
)),
|
||||
const Positioned(top: 0, left: 0, child: GameStateWidget()),
|
||||
// const Positioned(
|
||||
// bottom: 10,
|
||||
// left: 0,
|
||||
|
||||
Reference in New Issue
Block a user