Compare commits
No commits in common. "main" and "0.0.32+1" have entirely different histories.
57
README.md
57
README.md
|
@ -1,58 +1,3 @@
|
|||
# dth-pingpong-mobileapp
|
||||
>
|
||||
> Minimum supported Android API: 28 (Android 9).\
|
||||
> Minimum required iOS version: 14
|
||||
>
|
||||
Flutter application for ping pong score tracking. supports friends, elo tracking, match creation and planning.
|
||||
|
||||
![lang](https://img.shields.io/badge/Flutter-02569B?style=for-the-badge&logo=flutter&logoColor=white) ![os1](https://img.shields.io/badge/Android-3DDC84?style=for-the-badge&logo=android&logoColor=white)
|
||||
---
|
||||
|
||||
# Installing
|
||||
|
||||
Installation options are available for major mobile platforms. Although we mainly support android, all the features are cross-compatible with iOS
|
||||
|
||||
### Stable release channel (Android only)
|
||||
Grab one of the builds from the releases page or run:
|
||||
```bash
|
||||
flutter build apk
|
||||
```
|
||||
Production artifacts will be found in the `build\app\outputs\apk\` directory.
|
||||
|
||||
**RRC (Rolling Release Channel)**
|
||||
There's also a Rolling release available as pre-release builds. They will be released in a much quicker update ring (every other commit i'd assume) and are mostly debug builds so they'll be very heavy and *likely* broken.
|
||||
|
||||
### Building instructions (Android)
|
||||
Make sure you have [Flutter](https://flutter.dev/), [Android Studio](https://developer.android.com/studio), and [Visual Studio Code](https://code.visualstudio.com/) installed. Install the suggested Flutter, Dart, and linting extensions in Visual Studio Code.
|
||||
|
||||
Run the following commands to ensure all dependencies are met:
|
||||
```bash
|
||||
flutter doctor
|
||||
```
|
||||
|
||||
You'll be guided through a first-time setup that checks for platform tools, dependencies, and missing components.
|
||||
|
||||
Once the setup is complete you can navigate to the repo folder and run
|
||||
```bash
|
||||
flutter run
|
||||
```
|
||||
If you want to build debug you can also run
|
||||
```bash
|
||||
flutter build apk --debug
|
||||
```
|
||||
Build artifacts for Android are saved under `build\app\outputs\apk`.
|
||||
|
||||
### Building instructions (iOS)
|
||||
**MAJOR WORD OF WARNING: iOS builds are NOT officially supported, and we have NO clue as to why or how certain things just break on the xCode build (namely some icons and some api calls). if you encounter these issues you are free to patch them, and, if you seem fit, hit me up with a PR**
|
||||
|
||||
Make sure you have [Flutter](https://flutter.dev/), [xCode and Apple Developer Tools](https://apps.apple.com/en/app/xcode/id497799835?mt=12), [cocoapods](https://formulae.brew.sh/formula/cocoapods), and [Visual Studio Code](https://code.visualstudio.com/) installed.
|
||||
Install the suggested Flutter, Dart, and linting extensions in Visual Studio Code and set up xcode for "iOS on iphone" developement. Once that is done, go in the project's folder and run the following command to ensure that your build environment is properly configured, any missing component will be highlighted
|
||||
```bash
|
||||
flutter doctor
|
||||
```
|
||||
|
||||
Once you've done that, from the same terminal, run this command to generate a .IPA file - once you're done it's a matter of sideloading it to your device. since i've never owned an apple device i have no idea how to do that. iOS artifacts are saved in `build/ios/runner/`.
|
||||
|
||||
```bash
|
||||
flutter build ios
|
||||
```
|
||||
Mobile application for ping pong score tracking. supports friends ,elo tracking, match creation and planning.
|
BIN
ios/.DS_Store
vendored
BIN
ios/.DS_Store
vendored
Binary file not shown.
|
@ -1,2 +1 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
|
|
44
ios/Podfile
44
ios/Podfile
|
@ -1,44 +0,0 @@
|
|||
# Uncomment this line to define a global platform for your project
|
||||
# platform :ios, '12.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_ios_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
target 'RunnerTests' do
|
||||
inherit! :search_paths
|
||||
end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
PODS:
|
||||
- Flutter (1.0.0)
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
|
||||
DEPENDENCIES:
|
||||
- Flutter (from `Flutter`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
shared_preferences_foundation:
|
||||
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||
|
||||
PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796
|
||||
|
||||
COCOAPODS: 1.16.2
|
|
@ -10,9 +10,7 @@
|
|||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
4ECA18A68D772963A75CDDEE /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 664C6953382FB54D8ADFAA15 /* Pods_Runner.framework */; };
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||
860A7C4827A4A1FA258EE3B0 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A33A52767F410023C3017843 /* Pods_RunnerTests.framework */; };
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
|
@ -44,19 +42,12 @@
|
|||
/* Begin PBXFileReference section */
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
1D683FDEB78EA33536EDD9B0 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
2310337C49F4840CC13DECEC /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
2BD08DFC2DFC2958AE95FAD5 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
||||
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
664C6953382FB54D8ADFAA15 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7339FE983199E9675039DE4E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
8D54E1F7566A817BB3B988AC /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
9702D4B740EAB4624B982FE0 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -64,38 +55,19 @@
|
|||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
A33A52767F410023C3017843 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
035979494952341CA3553103 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
860A7C4827A4A1FA258EE3B0 /* Pods_RunnerTests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4ECA18A68D772963A75CDDEE /* Pods_Runner.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
2F1367A0823D5A1C2FD30B1E /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
664C6953382FB54D8ADFAA15 /* Pods_Runner.framework */,
|
||||
A33A52767F410023C3017843 /* Pods_RunnerTests.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
331C8082294A63A400263BE5 /* RunnerTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -104,20 +76,6 @@
|
|||
path = RunnerTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
803619556C668AF928FE7E28 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2310337C49F4840CC13DECEC /* Pods-Runner.debug.xcconfig */,
|
||||
7339FE983199E9675039DE4E /* Pods-Runner.release.xcconfig */,
|
||||
2BD08DFC2DFC2958AE95FAD5 /* Pods-Runner.profile.xcconfig */,
|
||||
1D683FDEB78EA33536EDD9B0 /* Pods-RunnerTests.debug.xcconfig */,
|
||||
8D54E1F7566A817BB3B988AC /* Pods-RunnerTests.release.xcconfig */,
|
||||
9702D4B740EAB4624B982FE0 /* Pods-RunnerTests.profile.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -136,8 +94,6 @@
|
|||
97C146F01CF9000F007C117D /* Runner */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
331C8082294A63A400263BE5 /* RunnerTests */,
|
||||
803619556C668AF928FE7E28 /* Pods */,
|
||||
2F1367A0823D5A1C2FD30B1E /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
|
@ -172,10 +128,8 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
||||
buildPhases = (
|
||||
B52AA023DC4D626077351632 /* [CP] Check Pods Manifest.lock */,
|
||||
331C807D294A63A400263BE5 /* Sources */,
|
||||
331C807F294A63A400263BE5 /* Resources */,
|
||||
035979494952341CA3553103 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
@ -191,14 +145,12 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
B9DF9E6804910D262BD7E7EA /* [CP] Check Pods Manifest.lock */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
64EEB9E634C86FA592F486D2 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
@ -286,23 +238,6 @@
|
|||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
||||
};
|
||||
64EEB9E634C86FA592F486D2 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
|
@ -318,50 +253,6 @@
|
|||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||
};
|
||||
B52AA023DC4D626077351632 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
B9DF9E6804910D262BD7E7EA /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
|
@ -436,7 +327,6 @@
|
|||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
|
@ -471,10 +361,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = R28MH57GSC;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
@ -483,7 +370,6 @@
|
|||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dth.innodesi.pingpongapp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
@ -492,7 +378,6 @@
|
|||
};
|
||||
331C8088294A63A400263BE5 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1D683FDEB78EA33536EDD9B0 /* Pods-RunnerTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
|
@ -510,7 +395,6 @@
|
|||
};
|
||||
331C8089294A63A400263BE5 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 8D54E1F7566A817BB3B988AC /* Pods-RunnerTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
|
@ -526,7 +410,6 @@
|
|||
};
|
||||
331C808A294A63A400263BE5 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9702D4B740EAB4624B982FE0 /* Pods-RunnerTests.profile.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
|
@ -564,7 +447,6 @@
|
|||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
|
@ -622,7 +504,6 @@
|
|||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
|
@ -659,10 +540,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = R28MH57GSC;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
@ -671,7 +549,6 @@
|
|||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dth.innodesi.pingpongapp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
@ -685,10 +562,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = R28MH57GSC;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
@ -697,7 +571,6 @@
|
|||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = dth.innodesi.pingpongapp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
|
3
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
3
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
|
@ -4,7 +4,4 @@
|
|||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Flutter
|
||||
import UIKit
|
||||
|
||||
@main
|
||||
@UIApplicationMain
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
// lib/globals.dart
|
||||
const String apiurl = "https://api.dthpp.mercurio.moe";
|
||||
//const String apiurl = "http://192.168.1.120:9134";
|
|
@ -17,7 +17,7 @@ class MyApp extends StatelessWidget {
|
|||
title: 'Ping Pong Tracker',
|
||||
theme: ThemeData.dark(useMaterial3: true).copyWith(
|
||||
colorScheme: ColorScheme.dark(
|
||||
primary: Colors.blue.shade800,
|
||||
primary: Colors.blue.shade900,
|
||||
),
|
||||
),
|
||||
home: EntryPoint(),
|
||||
|
|
|
@ -7,9 +7,6 @@ import 'views/joinmatch.dart';
|
|||
import 'views/creatematch.dart';
|
||||
import 'views/friendlist.dart';
|
||||
import 'views/myprofile.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import '../globals.dart';
|
||||
|
||||
class HomePage extends StatefulWidget {
|
||||
@override
|
||||
|
@ -19,6 +16,7 @@ class HomePage extends StatefulWidget {
|
|||
class _HomePageState extends State<HomePage> {
|
||||
int _selectedIndex = 0;
|
||||
|
||||
// Define the pages for each section
|
||||
final List<Widget> _pages = [
|
||||
LeaderboardPage(),
|
||||
JoinMatchPage(),
|
||||
|
@ -42,70 +40,12 @@ 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 {
|
||||
final commitHashes = await fetchCommitHashes();
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AboutDialog(
|
||||
applicationIcon: const Icon(Icons.code),
|
||||
applicationLegalese: '© 2024 Thomas Bassi @ Defence Tech.',
|
||||
applicationName: 'DTHPP',
|
||||
applicationVersion:
|
||||
'API: ${commitHashes['backend']} - UI: ${commitHashes['frontend']}',
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16.0),
|
||||
child: Text(
|
||||
"Do people even care about licenses? Is this ever going to be opened? Anywho, i hope you're enjoying the app and having fun on your break :D",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w400),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Ping Pong Tracker'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.info),
|
||||
onPressed: _showOpenSourceLicenses,
|
||||
tooltip: 'Open Source Licenses',
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.logout),
|
||||
onPressed: () => _logout(context),
|
||||
|
|
|
@ -3,9 +3,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
|||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import 'home.dart';
|
||||
import '../globals.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
|
||||
class LoginPage extends StatefulWidget {
|
||||
@override
|
||||
|
@ -20,20 +18,11 @@ class _LoginPageState extends State<LoginPage> {
|
|||
bool _isLogin = true;
|
||||
bool _isLoading = false;
|
||||
|
||||
final String baseUrl = 'http://api.dthpp.mercurio.moe';
|
||||
|
||||
Future<void> _handleAuth() async {
|
||||
final email = _emailController.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(() {
|
||||
_isLoading = true;
|
||||
|
@ -49,13 +38,13 @@ class _LoginPageState extends State<LoginPage> {
|
|||
context, MaterialPageRoute(builder: (context) => HomePage()));
|
||||
}
|
||||
} else {
|
||||
final uid = await _register(email, password, displayName);
|
||||
final uid = await _register(email, password, _displayNameController.text.trim());
|
||||
if (uid != null) {
|
||||
setState(() {
|
||||
_isLogin = true;
|
||||
});
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
content: Text('Registration successful! Please login.')));
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Registration successful! Please login.')));
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -69,7 +58,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||
}
|
||||
|
||||
Future<String?> _login(String email, String password) async {
|
||||
final url = Uri.parse('$apiurl/login');
|
||||
final url = Uri.parse('$baseUrl/login');
|
||||
final response = await http.post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
|
@ -84,9 +73,8 @@ class _LoginPageState extends State<LoginPage> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<String?> _register(
|
||||
String email, String password, String displayName) async {
|
||||
final url = Uri.parse('$apiurl/register');
|
||||
Future<String?> _register(String email, String password, String displayName) async {
|
||||
final url = Uri.parse('$baseUrl/register');
|
||||
final response = await http.post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
|
@ -130,61 +118,21 @@ class _LoginPageState extends State<LoginPage> {
|
|||
decoration: InputDecoration(labelText: 'Display Name'),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
if (_isLoading)
|
||||
CircularProgressIndicator()
|
||||
else
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: _handleAuth,
|
||||
child: Text(_isLogin ? 'Login' : 'Register'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_isLogin = !_isLogin;
|
||||
});
|
||||
},
|
||||
child: Text(_isLogin ? 'Register' : 'Back to 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';
|
||||
}
|
||||
}),
|
||||
],
|
||||
_isLoading
|
||||
? CircularProgressIndicator()
|
||||
: ElevatedButton(
|
||||
onPressed: _handleAuth,
|
||||
child: Text(_isLogin ? 'Login' : 'Register'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_isLogin = !_isLogin;
|
||||
});
|
||||
},
|
||||
child: Text(_isLogin
|
||||
? 'Don\'t have an account? Register'
|
||||
: 'Already have an account? Login'),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:convert';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../../globals.dart';
|
||||
|
||||
class CreateMatchPage extends StatefulWidget {
|
||||
@override
|
||||
|
@ -13,8 +12,9 @@ class _CreateMatchPageState extends State<CreateMatchPage> {
|
|||
String? _matchId;
|
||||
bool _isLoading = false;
|
||||
|
||||
final String _createMatchApiUrl = '$apiurl/creatematch';
|
||||
final String _createMatchApiUrl = 'http://api.dthpp.mercurio.moe/creatematch'; // Replace with your API endpoint
|
||||
|
||||
// Method to create a match
|
||||
Future<void> _createMatch() async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
|
@ -88,18 +88,12 @@ class _CreateMatchPageState extends State<CreateMatchPage> {
|
|||
textAlign: TextAlign.center,
|
||||
),
|
||||
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
|
||||
? CircularProgressIndicator() // Show loading spinner
|
||||
: ElevatedButton(
|
||||
onPressed: _createMatch,
|
||||
child: Text('Create Match'),
|
||||
),
|
||||
onPressed: _createMatch,
|
||||
child: Text('Create Match'),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
if (_matchId != null)
|
||||
Text(
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:convert';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../../globals.dart';
|
||||
|
||||
class AddFriendPage extends StatefulWidget {
|
||||
@override
|
||||
|
@ -14,8 +13,8 @@ class _AddFriendPageState extends State<AddFriendPage> {
|
|||
List<dynamic> _friends = [];
|
||||
bool _isLoading = false;
|
||||
|
||||
final String _addFriendApiUrl = '$apiurl/add_friend';
|
||||
final String _getFriendsApiUrl = '$apiurl/get_friends';
|
||||
final String _addFriendApiUrl = 'http://api.dthpp.mercurio.moe/add_friend';
|
||||
final String _getFriendsApiUrl = 'http://api.dthpp.mercurio.moe/get_friends';
|
||||
|
||||
// Method to add a friend
|
||||
Future<void> _addFriend(String friendUid) async {
|
||||
|
@ -125,17 +124,17 @@ class _AddFriendPageState extends State<AddFriendPage> {
|
|||
_isLoading
|
||||
? Center(child: CircularProgressIndicator())
|
||||
: Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: _friends.length,
|
||||
itemBuilder: (context, index) {
|
||||
final friend = _friends[index];
|
||||
return ListTile(
|
||||
title: Text(friend['name']),
|
||||
subtitle: Text('UID: ${friend['uid']}'),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
child: ListView.builder(
|
||||
itemCount: _friends.length,
|
||||
itemBuilder: (context, index) {
|
||||
final friend = _friends[index];
|
||||
return ListTile(
|
||||
title: Text(friend['name']),
|
||||
subtitle: Text('UID: ${friend['uid']}'),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:convert';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../../globals.dart';
|
||||
|
||||
class JoinMatchPage extends StatefulWidget {
|
||||
@override
|
||||
|
@ -17,9 +16,10 @@ class _JoinMatchPageState extends State<JoinMatchPage> {
|
|||
int _player2Score = 0;
|
||||
String? _matchId;
|
||||
|
||||
final String _joinMatchApiUrl = '$apiurl/joinmatch';
|
||||
final String _endMatchApiUrl = '$apiurl/endmatch';
|
||||
final String _joinMatchApiUrl = 'http://api.dthpp.mercurio.moe/joinmatch'; // Replace with your API endpoint
|
||||
final String _endMatchApiUrl = 'http://api.dthpp.mercurio.moe/endmatch'; // Replace with your API endpoint
|
||||
|
||||
// Join Match Function
|
||||
Future<void> _joinMatch() async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
|
@ -64,6 +64,7 @@ class _JoinMatchPageState extends State<JoinMatchPage> {
|
|||
}
|
||||
}
|
||||
|
||||
// Increment/Decrement Player Scores
|
||||
void _updateScore(int player, int delta) {
|
||||
setState(() {
|
||||
if (player == 1) {
|
||||
|
@ -74,6 +75,7 @@ class _JoinMatchPageState extends State<JoinMatchPage> {
|
|||
});
|
||||
}
|
||||
|
||||
// End Match Function
|
||||
Future<void> _endMatch() async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
|
@ -133,80 +135,80 @@ class _JoinMatchPageState extends State<JoinMatchPage> {
|
|||
child: _isLoading
|
||||
? Center(child: CircularProgressIndicator())
|
||||
: _isJoined
|
||||
? Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.remove),
|
||||
onPressed: () => _updateScore(1, -1),
|
||||
),
|
||||
Text(
|
||||
'Player 1 Score: $_player1Score',
|
||||
style: TextStyle(fontSize: 20),
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.add),
|
||||
onPressed: () => _updateScore(1, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
// Player 2 Score Controls
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.remove),
|
||||
onPressed: () => _updateScore(2, -1),
|
||||
),
|
||||
Text(
|
||||
'Player 2 Score: $_player2Score',
|
||||
style: TextStyle(fontSize: 20),
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.add),
|
||||
onPressed: () => _updateScore(2, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 32),
|
||||
// End Match Button
|
||||
ElevatedButton(
|
||||
onPressed: _endMatch,
|
||||
child: Text('End Match'),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
// Match ID Text Field
|
||||
TextField(
|
||||
controller: _matchIdController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Enter Match ID',
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
// Join Match Button
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
if (_matchIdController.text.isNotEmpty) {
|
||||
_joinMatch();
|
||||
} else {
|
||||
_showToast('Please enter a Match ID.');
|
||||
}
|
||||
},
|
||||
child: Text('Join Match'),
|
||||
),
|
||||
],
|
||||
),
|
||||
? Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.remove),
|
||||
onPressed: () => _updateScore(1, -1),
|
||||
),
|
||||
Text(
|
||||
'Player 1 Score: $_player1Score',
|
||||
style: TextStyle(fontSize: 20),
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.add),
|
||||
onPressed: () => _updateScore(1, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
// Player 2 Score Controls
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.remove),
|
||||
onPressed: () => _updateScore(2, -1),
|
||||
),
|
||||
Text(
|
||||
'Player 2 Score: $_player2Score',
|
||||
style: TextStyle(fontSize: 20),
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.add),
|
||||
onPressed: () => _updateScore(2, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 32),
|
||||
// End Match Button
|
||||
ElevatedButton(
|
||||
onPressed: _endMatch,
|
||||
child: Text('End Match'),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
// Match ID Text Field
|
||||
TextField(
|
||||
controller: _matchIdController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Enter Match ID',
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
// Join Match Button
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
if (_matchIdController.text.isNotEmpty) {
|
||||
_joinMatch();
|
||||
} else {
|
||||
_showToast('Please enter a Match ID.');
|
||||
}
|
||||
},
|
||||
child: Text('Join Match'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../../globals.dart';
|
||||
|
||||
class LeaderboardPage extends StatefulWidget {
|
||||
@override
|
||||
|
@ -12,7 +11,7 @@ class _LeaderboardPageState extends State<LeaderboardPage> {
|
|||
List<dynamic> _leaderboard = [];
|
||||
bool _isLoading = true;
|
||||
|
||||
final String _leaderboardApi = '$apiurl/leaderboards';
|
||||
final String _apiUrl = 'http://api.dthpp.mercurio.moe/leaderboards';
|
||||
|
||||
Future<void> _fetchLeaderboard() async {
|
||||
setState(() {
|
||||
|
@ -20,7 +19,7 @@ class _LeaderboardPageState extends State<LeaderboardPage> {
|
|||
});
|
||||
|
||||
try {
|
||||
final response = await http.get(Uri.parse(_leaderboardApi));
|
||||
final response = await http.get(Uri.parse(_apiUrl));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
List<dynamic> data = json.decode(response.body);
|
||||
|
@ -63,35 +62,35 @@ class _LeaderboardPageState extends State<LeaderboardPage> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchLeaderboard();
|
||||
_fetchLeaderboard();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: _isLoading
|
||||
? Center(child: CircularProgressIndicator())
|
||||
? Center(child: CircularProgressIndicator())
|
||||
: RefreshIndicator(
|
||||
onRefresh: _fetchLeaderboard,
|
||||
child: ListView.builder(
|
||||
itemCount: _leaderboard.length,
|
||||
itemBuilder: (context, index) {
|
||||
var player = _leaderboard[index];
|
||||
return Card(
|
||||
margin: EdgeInsets.all(8),
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.all(10),
|
||||
leading: CircleAvatar(
|
||||
child: Text(player['player_name'][0].toUpperCase()),
|
||||
),
|
||||
title: Text(player['player_name']),
|
||||
subtitle: Text('Elo Rating: ${player['elo_rating']}'),
|
||||
trailing: Text('Friend Code: ${player['friend_code']}'),
|
||||
),
|
||||
);
|
||||
},
|
||||
onRefresh: _fetchLeaderboard,
|
||||
child: ListView.builder(
|
||||
itemCount: _leaderboard.length,
|
||||
itemBuilder: (context, index) {
|
||||
var player = _leaderboard[index];
|
||||
return Card(
|
||||
margin: EdgeInsets.all(8),
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.all(10),
|
||||
leading: CircleAvatar(
|
||||
child: Text(player['player_name'][0].toUpperCase()),
|
||||
),
|
||||
title: Text(player['player_name']),
|
||||
subtitle: Text('Elo Rating: ${player['elo_rating']}'),
|
||||
trailing: Text('Friend Code: ${player['friend_code']}'),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ import 'dart:math';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../../globals.dart';
|
||||
|
||||
class ProfilePage extends StatefulWidget {
|
||||
@override
|
||||
|
@ -17,7 +16,7 @@ class _ProfilePageState extends State<ProfilePage> {
|
|||
int? _elo;
|
||||
List<dynamic> _matches = [];
|
||||
|
||||
final String _getProfileApiUrl = '$apiurl/getprofile';
|
||||
final String _getProfileApiUrl = 'http://api.dthpp.mercurio.moe/getprofile';
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -80,116 +79,114 @@ class _ProfilePageState extends State<ProfilePage> {
|
|||
body: _isLoading
|
||||
? Center(child: CircularProgressIndicator())
|
||||
: RefreshIndicator(
|
||||
onRefresh: _fetchProfileData,
|
||||
child: Column(
|
||||
onRefresh: _fetchProfileData,
|
||||
child: Column(
|
||||
children: [
|
||||
// Profile Details
|
||||
Container(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
// Profile Details
|
||||
Container(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
// Profile Icon
|
||||
CircleAvatar(
|
||||
backgroundColor: _generateRandomColor(),
|
||||
child: Text(
|
||||
_name != null && _name!.isNotEmpty
|
||||
? _name![0].toUpperCase()
|
||||
: '?',
|
||||
style: TextStyle(fontSize: 24, color: Colors.white),
|
||||
),
|
||||
radius: 40,
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
// Profile Info
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
_name ?? 'Name not available',
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text('UID: ${_uid ?? 'N/A'}'),
|
||||
Text('ELO: ${_elo ?? 'N/A'}'),
|
||||
],
|
||||
),
|
||||
],
|
||||
// Profile Icon
|
||||
CircleAvatar(
|
||||
backgroundColor: _generateRandomColor(),
|
||||
child: Text(
|
||||
_name != null && _name!.isNotEmpty
|
||||
? _name![0].toUpperCase()
|
||||
: '?',
|
||||
style: TextStyle(fontSize: 24, color: Colors.white),
|
||||
),
|
||||
radius: 40,
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
// Recent Matches
|
||||
Expanded(
|
||||
child: _matches.isEmpty
|
||||
? Center(
|
||||
child: Text(
|
||||
"You haven't played any matches yet",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
)
|
||||
: ListView.builder(
|
||||
itemCount: _matches.length,
|
||||
itemBuilder: (context, index) {
|
||||
final match = _matches[index];
|
||||
final result = match['result'];
|
||||
final eloChange = match['elo_change'];
|
||||
|
||||
return Card(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: 16.0, vertical: 8.0),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Match ID: ${match['match_id']}',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Opponent: ${match['opponent_name']}'),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'$result',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: result == 'Win'
|
||||
? Colors.green
|
||||
: Colors.red,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
if (eloChange != null)
|
||||
Text(
|
||||
'ELO Change: ${eloChange > 0 ? '+' : ''}$eloChange',
|
||||
style: TextStyle(
|
||||
color: eloChange > 0
|
||||
? Colors.green
|
||||
: Colors.red,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
// Profile Info
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
_name ?? 'Name not available',
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text('UID: ${_uid ?? 'N/A'}'),
|
||||
Text('ELO: ${_elo ?? 'N/A'}'),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
// Recent Matches
|
||||
Expanded(
|
||||
child: _matches.isEmpty
|
||||
? Center(
|
||||
child: Text(
|
||||
"You haven't played any matches yet",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
)
|
||||
: ListView.builder(
|
||||
itemCount: _matches.length,
|
||||
itemBuilder: (context, index) {
|
||||
final match = _matches[index];
|
||||
final result = match['result'];
|
||||
final eloChange = match['elo_change'];
|
||||
|
||||
return Card(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: 16.0, vertical: 8.0),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Match ID: ${match['match_id']}',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Text('Opponent: ${match['opponent_name']}'),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'$result',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: result == 'Win'
|
||||
? Colors.green
|
||||
: Colors.red,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
if (eloChange != null)
|
||||
Text(
|
||||
'ELO Change: ${eloChange > 0 ? '+' : ''}$eloChange',
|
||||
style: TextStyle(
|
||||
color: eloChange > 0
|
||||
? Colors.green
|
||||
: Colors.red,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
|
|
|
@ -5,10 +5,8 @@
|
|||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import package_info
|
||||
import shared_preferences_foundation
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
platform :osx, '10.14'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_macos_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
|
||||
flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
|
||||
target 'RunnerTests' do
|
||||
inherit! :search_paths
|
||||
end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_macos_build_settings(target)
|
||||
end
|
||||
end
|
|
@ -1,8 +1,8 @@
|
|||
name: pingpongapp
|
||||
description: "DTH Ping Pong Score tracking app"
|
||||
description: "A new Flutter project."
|
||||
publish_to: 'none'
|
||||
|
||||
version: 0.0.34+1
|
||||
version: 0.0.32+1
|
||||
|
||||
environment:
|
||||
sdk: '>=3.4.3 <4.0.0'
|
||||
|
@ -14,9 +14,6 @@ dependencies:
|
|||
shared_preferences: ^2.3.3
|
||||
http: ^1.2.2
|
||||
logger: ^2.5.0
|
||||
package_info: ^2.0.2
|
||||
font_awesome_flutter: ^10.8.0
|
||||
url_launcher: ^6.3.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
Loading…
Reference in a new issue