Compare commits
2 commits
Author | SHA1 | Date | |
---|---|---|---|
b304ab3a7b | |||
4d27d3be11 |
|
@ -1,3 +1,3 @@
|
||||||
// lib/globals.dart
|
// lib/globals.dart
|
||||||
const String apiurl = "https://api.dthpp.mercurio.moe";
|
const String apiurl = "https://api.dthpp.mercurio.moe";
|
||||||
//const String apiurl = "http://10.0.0.10:9134";
|
//const String apiurl = "http://192.168.1.120:9134";
|
||||||
|
|
|
@ -7,6 +7,9 @@ import 'views/joinmatch.dart';
|
||||||
import 'views/creatematch.dart';
|
import 'views/creatematch.dart';
|
||||||
import 'views/friendlist.dart';
|
import 'views/friendlist.dart';
|
||||||
import 'views/myprofile.dart';
|
import 'views/myprofile.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'dart:convert';
|
||||||
|
import '../globals.dart';
|
||||||
|
|
||||||
class HomePage extends StatefulWidget {
|
class HomePage extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
|
@ -16,7 +19,6 @@ class HomePage extends StatefulWidget {
|
||||||
class _HomePageState extends State<HomePage> {
|
class _HomePageState extends State<HomePage> {
|
||||||
int _selectedIndex = 0;
|
int _selectedIndex = 0;
|
||||||
|
|
||||||
// Define the pages for each section
|
|
||||||
final List<Widget> _pages = [
|
final List<Widget> _pages = [
|
||||||
LeaderboardPage(),
|
LeaderboardPage(),
|
||||||
JoinMatchPage(),
|
JoinMatchPage(),
|
||||||
|
@ -40,14 +42,46 @@ class _HomePageState extends State<HomePage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Map<String, String>> fetchCommitHashes() async {
|
||||||
|
const apiUrl = '$apiurl/version';
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await http.get(Uri.parse(apiUrl));
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
final data = jsonDecode(response.body);
|
||||||
|
|
||||||
|
String formatHash(String? hash) {
|
||||||
|
if (hash == null) return 'Unknown';
|
||||||
|
return '#${hash.substring(0, 8).toUpperCase()}';
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'backend': formatHash(data['backend']),
|
||||||
|
'frontend': formatHash(data['frontend']),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
throw Exception('Failed to fetch commit hashes');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
'backend': 'Error fetching hash',
|
||||||
|
'frontend': 'Error fetching hash',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _showOpenSourceLicenses() async {
|
Future<void> _showOpenSourceLicenses() async {
|
||||||
|
final commitHashes = await fetchCommitHashes();
|
||||||
|
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) => AboutDialog(
|
builder: (BuildContext context) => AboutDialog(
|
||||||
applicationIcon: const Icon(Icons.code),
|
applicationIcon: const Icon(Icons.code),
|
||||||
applicationLegalese: '© 2024 Thomas Bassi @ Defence Tech.',
|
applicationLegalese: '© 2024 Thomas Bassi @ Defence Tech.',
|
||||||
applicationName: 'DTHPP',
|
applicationName: 'DTHPP',
|
||||||
applicationVersion: '#B22AF349A1',
|
applicationVersion:
|
||||||
|
'API: ${commitHashes['backend']} - UI: ${commitHashes['frontend']}',
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 16.0),
|
padding: const EdgeInsets.only(top: 16.0),
|
||||||
|
|
|
@ -4,6 +4,8 @@ import 'package:http/http.dart' as http;
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'home.dart';
|
import 'home.dart';
|
||||||
import '../globals.dart';
|
import '../globals.dart';
|
||||||
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
class LoginPage extends StatefulWidget {
|
class LoginPage extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
|
@ -21,6 +23,17 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
Future<void> _handleAuth() async {
|
Future<void> _handleAuth() async {
|
||||||
final email = _emailController.text.trim();
|
final email = _emailController.text.trim();
|
||||||
final password = _passwordController.text.trim();
|
final password = _passwordController.text.trim();
|
||||||
|
final displayName = _displayNameController.text.trim();
|
||||||
|
|
||||||
|
// Input validation
|
||||||
|
if (email.isEmpty ||
|
||||||
|
password.isEmpty ||
|
||||||
|
(!_isLogin && displayName.isEmpty)) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text('Please fill in all required fields.')),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
|
@ -36,8 +49,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
context, MaterialPageRoute(builder: (context) => HomePage()));
|
context, MaterialPageRoute(builder: (context) => HomePage()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final uid = await _register(
|
final uid = await _register(email, password, displayName);
|
||||||
email, password, _displayNameController.text.trim());
|
|
||||||
if (uid != null) {
|
if (uid != null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLogin = true;
|
_isLogin = true;
|
||||||
|
@ -118,21 +130,61 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
decoration: InputDecoration(labelText: 'Display Name'),
|
decoration: InputDecoration(labelText: 'Display Name'),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
_isLoading
|
if (_isLoading)
|
||||||
? CircularProgressIndicator()
|
CircularProgressIndicator()
|
||||||
: ElevatedButton(
|
else
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
ElevatedButton(
|
||||||
onPressed: _handleAuth,
|
onPressed: _handleAuth,
|
||||||
child: Text(_isLogin ? 'Login' : 'Register'),
|
child: Text(_isLogin ? 'Login' : 'Register'),
|
||||||
),
|
),
|
||||||
TextButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLogin = !_isLogin;
|
_isLogin = !_isLogin;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Text(_isLogin
|
child: Text(_isLogin ? 'Register' : 'Back to Login'),
|
||||||
? 'Don\'t have an account? Register'
|
),
|
||||||
: 'Already have an account? Login'),
|
],
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(FontAwesomeIcons.github),
|
||||||
|
onPressed: () async {
|
||||||
|
final url = Uri.parse(
|
||||||
|
'https://git.mercurio.moe/Mercury/dth-pingpong-mobileapp');
|
||||||
|
if (await canLaunchUrl(url)) {
|
||||||
|
await launchUrl(
|
||||||
|
url,
|
||||||
|
mode: LaunchMode
|
||||||
|
.externalApplication, // Ensures it opens in the browser
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw 'Could not launch $url';
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(FontAwesomeIcons.chartSimple),
|
||||||
|
onPressed: () async {
|
||||||
|
final url =
|
||||||
|
Uri.parse('https://kuma.mercurio.moe/status/dthpp');
|
||||||
|
if (await canLaunchUrl(url)) {
|
||||||
|
await launchUrl(
|
||||||
|
url,
|
||||||
|
mode: LaunchMode
|
||||||
|
.externalApplication, // Ensures it opens in the browser
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw 'Could not launch $url';
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -13,10 +13,8 @@ class _CreateMatchPageState extends State<CreateMatchPage> {
|
||||||
String? _matchId;
|
String? _matchId;
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
|
|
||||||
final String _createMatchApiUrl =
|
final String _createMatchApiUrl = '$apiurl/creatematch';
|
||||||
'$apiurl/creatematch'; // Replace with your API endpoint
|
|
||||||
|
|
||||||
// Method to create a match
|
|
||||||
Future<void> _createMatch() async {
|
Future<void> _createMatch() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
|
@ -90,6 +88,12 @@ class _CreateMatchPageState extends State<CreateMatchPage> {
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
SizedBox(height: 16),
|
SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
'Due to current limitations in how we handle matchmaking, only the joining player can control the match. This is only a temporary solution to a problem we are actively fixing.',
|
||||||
|
style: TextStyle(fontSize: 14),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
SizedBox(height: 16),
|
||||||
_isLoading
|
_isLoading
|
||||||
? CircularProgressIndicator() // Show loading spinner
|
? CircularProgressIndicator() // Show loading spinner
|
||||||
: ElevatedButton(
|
: ElevatedButton(
|
||||||
|
|
|
@ -15,6 +15,8 @@ dependencies:
|
||||||
http: ^1.2.2
|
http: ^1.2.2
|
||||||
logger: ^2.5.0
|
logger: ^2.5.0
|
||||||
package_info: ^2.0.2
|
package_info: ^2.0.2
|
||||||
|
font_awesome_flutter: ^10.8.0
|
||||||
|
url_launcher: ^6.3.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Loading…
Reference in a new issue