diff --git a/.metadata b/.metadata index dc84ef0..85b54cb 100644 --- a/.metadata +++ b/.metadata @@ -15,19 +15,7 @@ migration: - platform: root create_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8 base_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8 - - platform: android - create_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8 - base_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8 - - platform: linux - create_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8 - base_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8 - - platform: macos - create_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8 - base_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8 - - platform: web - create_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8 - base_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8 - - platform: windows + - platform: ios create_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8 base_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8 diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..1dc6cf7 --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 13.0 + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..ec97fc6 --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..c4855bf --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 0000000..620e46e --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,43 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '13.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! + + 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 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8358b1c --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,731 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 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 */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 8AD879B4BA24BC1EB84E1092 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8543AAE6520EA0C0B3AF8FEE /* 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 */; }; + DDD6907F99188C9B97C6B11F /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D622CF241440C10C19C0D397 /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 13301BC306FBFE16F253F2B9 /* 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 = ""; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 32DDFE3349B038E1CA758D7B /* 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 = ""; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 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 = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 8543AAE6520EA0C0B3AF8FEE /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 96CDE41BAA7259C918DB326B /* 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 = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B194217AD06D15D90AAF9056 /* 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 = ""; }; + B68CF4A64F0B5E45B43D6900 /* 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 = ""; }; + D622CF241440C10C19C0D397 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E754D1191B3E54E52B6DCC49 /* 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6F6FEDCE9772FEF7A6255134 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8AD879B4BA24BC1EB84E1092 /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DDD6907F99188C9B97C6B11F /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + ABF0E17C36D6999806C09130 /* Pods */, + F14326E3F17437DD2E32AB7B /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + ABF0E17C36D6999806C09130 /* Pods */ = { + isa = PBXGroup; + children = ( + B194217AD06D15D90AAF9056 /* Pods-Runner.debug.xcconfig */, + 32DDFE3349B038E1CA758D7B /* Pods-Runner.release.xcconfig */, + 13301BC306FBFE16F253F2B9 /* Pods-Runner.profile.xcconfig */, + 96CDE41BAA7259C918DB326B /* Pods-RunnerTests.debug.xcconfig */, + B68CF4A64F0B5E45B43D6900 /* Pods-RunnerTests.release.xcconfig */, + E754D1191B3E54E52B6DCC49 /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + F14326E3F17437DD2E32AB7B /* Frameworks */ = { + isa = PBXGroup; + children = ( + D622CF241440C10C19C0D397 /* Pods_Runner.framework */, + 8543AAE6520EA0C0B3AF8FEE /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + F7D5E29C2C77E2E8925BBB8A /* [CP] Check Pods Manifest.lock */, + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + 6F6FEDCE9772FEF7A6255134 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 8947D8DE27F8CB7D5A5F265C /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 0CC58B149CD3F41CF94E1C52 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 0CC58B149CD3F41CF94E1C52 /* [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; + }; + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 8947D8DE27F8CB7D5A5F265C /* [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; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + F7D5E29C2C77E2E8925BBB8A /* [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; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = RJB4MM6RVS; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.gameTracker; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 96CDE41BAA7259C918DB326B /* Pods-RunnerTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.gameTracker.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B68CF4A64F0B5E45B43D6900 /* Pods-RunnerTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.gameTracker.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E754D1191B3E54E52B6DCC49 /* Pods-RunnerTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.gameTracker.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = RJB4MM6RVS; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.gameTracker; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = RJB4MM6RVS; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.gameTracker; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..e3773d4 --- /dev/null +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..6266644 --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Flutter +import UIKit + +@main +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..7353c41 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..6ed2d93 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cd7b00 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..fe73094 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..321773c Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..502f463 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..e9f5fea Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..84ac32a Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..8953cba Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..0467bf1 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist new file mode 100644 index 0000000..048157d --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Game Tracker + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + game_tracker + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/lib/core/custom_theme.dart b/lib/core/custom_theme.dart new file mode 100644 index 0000000..438aab5 --- /dev/null +++ b/lib/core/custom_theme.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; + +class CustomTheme { + static Color primaryColor = const Color(0xFF7505E4); + static Color secondaryColor = const Color(0xFFAFA2FF); + static Color backgroundColor = const Color(0xFF0B0B0B); + static Color boxColor = const Color(0xFF101010); + static Color boxBorder = const Color(0xFF272727); + + static AppBarTheme appBarTheme = AppBarTheme( + backgroundColor: backgroundColor, + foregroundColor: Colors.white, + elevation: 0, + titleTextStyle: const TextStyle( + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.bold, + ), + iconTheme: const IconThemeData(color: Colors.white), + ); +} diff --git a/lib/data/dao/game_dao.dart b/lib/data/dao/game_dao.dart new file mode 100644 index 0000000..3b6529a --- /dev/null +++ b/lib/data/dao/game_dao.dart @@ -0,0 +1,34 @@ +import 'package:drift/drift.dart'; +import 'package:game_tracker/data/db/database.dart'; +import 'package:game_tracker/data/db/tables/game_table.dart'; +import 'package:game_tracker/data/dto/game.dart'; + +part 'game_dao.g.dart'; + +@DriftAccessor(tables: [GameTable]) +class GameDao extends DatabaseAccessor with _$GameDaoMixin { + GameDao(super.db); + + /// Retrieves all games from the database. + Future> getAllGames() async { + final query = select(gameTable); + final result = await query.get(); + return result.map((row) => Game(id: row.id, name: row.name)).toList(); + } + + /// Retrieves a [Game] by its [id]. + Future getGameById(String id) async { + final query = select(gameTable)..where((g) => g.id.equals(id)); + final result = await query.getSingle(); + return Game(id: result.id, name: result.name); + } + + /// Retrieves the number of games in the database. + Future getGameCount() async { + final count = + await (selectOnly(gameTable)..addColumns([gameTable.id.count()])) + .map((row) => row.read(gameTable.id.count())) + .getSingle(); + return count ?? 0; + } +} diff --git a/lib/data/dao/game_dao.g.dart b/lib/data/dao/game_dao.g.dart new file mode 100644 index 0000000..b5a29fe --- /dev/null +++ b/lib/data/dao/game_dao.g.dart @@ -0,0 +1,8 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'game_dao.dart'; + +// ignore_for_file: type=lint +mixin _$GameDaoMixin on DatabaseAccessor { + $GameTableTable get gameTable => attachedDatabase.gameTable; +} diff --git a/lib/data/dao/group_dao.dart b/lib/data/dao/group_dao.dart new file mode 100644 index 0000000..7dc144d --- /dev/null +++ b/lib/data/dao/group_dao.dart @@ -0,0 +1,68 @@ +import 'package:drift/drift.dart'; +import 'package:game_tracker/data/db/database.dart'; +import 'package:game_tracker/data/db/tables/group_table.dart'; +import 'package:game_tracker/data/dto/group.dart'; +import 'package:game_tracker/data/dto/player.dart'; + +part 'group_dao.g.dart'; + +@DriftAccessor(tables: [GroupTable]) +class GroupDao extends DatabaseAccessor with _$GroupDaoMixin { + GroupDao(super.db); + + /// Retrieves all groups from the database. + Future> getAllGroups() async { + final query = select(groupTable); + final result = await query.get(); + return result + .map((row) => Group(id: row.id, name: row.name, members: [])) + .toList(); + } + + /// Retrieves a [Group] by its [id], including its members. + Future getGroupById(String id) async { + final query = select(groupTable)..where((g) => g.id.equals(id)); + final result = await query.getSingle(); + + List members = []; + + members = await db.playerGroupDao.getPlayersOfGroupById(id); + + return Group(id: result.id, name: result.name, members: members); + } + + /// Adds a new group with the given [id] and [name] to the database. + /// Returns `true` if more than 0 rows were affected, otherwise `false`. + Future addGroup(String id, String name) async { + await into( + groupTable, + ).insert(GroupTableCompanion.insert(id: id, name: name)); + } + + /// Deletes the group with the given [id] from the database. + /// Returns `true` if more than 0 rows were affected, otherwise `false`. + Future deleteGroup(String id) async { + final query = (delete(groupTable)..where((g) => g.id.equals(id))); + final rowsAffected = await query.go(); + return rowsAffected > 0; + } + + /// Updates the name of the group with the given [id] to [newName]. + /// Returns `true` if more than 0 rows were affected, otherwise `false`. + Future updateGroupname(String id, String newName) async { + final rowsAffected = + await (update(groupTable)..where((g) => g.id.equals(id))).write( + GroupTableCompanion(name: Value(newName)), + ); + return rowsAffected > 0; + } + + /// Retrieves the number of groups in the database. + Future getGroupCount() async { + final count = + await (selectOnly(groupTable)..addColumns([groupTable.id.count()])) + .map((row) => row.read(groupTable.id.count())) + .getSingle(); + return count ?? 0; + } +} diff --git a/lib/data/dao/group_dao.g.dart b/lib/data/dao/group_dao.g.dart new file mode 100644 index 0000000..4a09208 --- /dev/null +++ b/lib/data/dao/group_dao.g.dart @@ -0,0 +1,8 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'group_dao.dart'; + +// ignore_for_file: type=lint +mixin _$GroupDaoMixin on DatabaseAccessor { + $GroupTableTable get groupTable => attachedDatabase.groupTable; +} diff --git a/lib/data/dao/player_dao.dart b/lib/data/dao/player_dao.dart new file mode 100644 index 0000000..2d3c0ab --- /dev/null +++ b/lib/data/dao/player_dao.dart @@ -0,0 +1,55 @@ +import 'package:drift/drift.dart'; +import 'package:game_tracker/data/db/database.dart'; +import 'package:game_tracker/data/db/tables/player_table.dart'; +import 'package:game_tracker/data/dto/player.dart'; + +part 'player_dao.g.dart'; + +@DriftAccessor(tables: [PlayerTable]) +class PlayerDao extends DatabaseAccessor with _$PlayerDaoMixin { + PlayerDao(super.db); + + /// Retrieves all players from the database. + Future> getAllPlayers() async { + final query = select(playerTable); + final result = await query.get(); + return result.map((row) => Player(id: row.id, name: row.name)).toList(); + } + + /// Retrieves a [Player] by their [id]. + Future getPlayerById(String id) async { + final query = select(playerTable)..where((p) => p.id.equals(id)); + final result = await query.getSingle(); + return Player(id: result.id, name: result.name); + } + + /// Adds a new [player] to the database. + Future addPlayer(Player player) async { + await into( + playerTable, + ).insert(PlayerTableCompanion.insert(id: player.id, name: player.name)); + } + + /// Deletes the player with the given [id] from the database. + /// Returns `true` if the player was deleted, `false` if the player did not exist. + Future deletePlayer(String id) async { + final query = delete(playerTable)..where((p) => p.id.equals(id)); + final rowsAffected = await query.go(); + return rowsAffected > 0; + } + + /// Checks if a player with the given [id] exists in the database. + /// Returns `true` if the player exists, `false` otherwise. + Future playerExists(String id) async { + final query = select(playerTable)..where((p) => p.id.equals(id)); + final result = await query.getSingleOrNull(); + return result != null; + } + + /// Updates the name of the player with the given [id] to [newName]. + Future updatePlayername(String id, String newName) async { + await (update(playerTable)..where((p) => p.id.equals(id))).write( + PlayerTableCompanion(name: Value(newName)), + ); + } +} diff --git a/lib/data/dao/player_dao.g.dart b/lib/data/dao/player_dao.g.dart new file mode 100644 index 0000000..c517581 --- /dev/null +++ b/lib/data/dao/player_dao.g.dart @@ -0,0 +1,8 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'player_dao.dart'; + +// ignore_for_file: type=lint +mixin _$PlayerDaoMixin on DatabaseAccessor { + $PlayerTableTable get playerTable => attachedDatabase.playerTable; +} diff --git a/lib/data/dao/player_group_dao.dart b/lib/data/dao/player_group_dao.dart new file mode 100644 index 0000000..b68ed09 --- /dev/null +++ b/lib/data/dao/player_group_dao.dart @@ -0,0 +1,44 @@ +import 'package:drift/drift.dart'; +import 'package:game_tracker/data/db/database.dart'; +import 'package:game_tracker/data/db/tables/player_group_table.dart'; +import 'package:game_tracker/data/dto/player.dart'; + +part 'player_group_dao.g.dart'; + +@DriftAccessor(tables: [PlayerGroupTable]) +class PlayerGroupDao extends DatabaseAccessor + with _$PlayerGroupDaoMixin { + PlayerGroupDao(super.db); + + /// Retrieves all players belonging to a specific group by [groupId]. + Future> getPlayersOfGroupById(String groupId) async { + final query = select(playerGroupTable) + ..where((pG) => pG.groupId.equals(groupId)); + final result = await query.get(); + + List groupMembers = []; + + for (var entry in result) { + final player = await db.playerDao.getPlayerById(entry.userId); + groupMembers.add(player); + } + + return groupMembers; + } + + /// Removes a player from a group based on [userId] and [groupId]. + /// Returns `true` if more than 0 rows were affected, otherwise `false`. + Future removePlayerFromGroup(String userId, String groupId) async { + final query = delete(playerGroupTable) + ..where((p) => p.userId.equals(userId) & p.groupId.equals(groupId)); + final rowsAffected = await query.go(); + return rowsAffected > 0; + } + + /// Adds a player to a group with the given [userId] and [groupId]. + Future addPlayerToGroup(String userId, String groupId) async { + await into(playerGroupTable).insert( + PlayerGroupTableCompanion.insert(userId: userId, groupId: groupId), + ); + } +} diff --git a/lib/data/dao/player_group_dao.g.dart b/lib/data/dao/player_group_dao.g.dart new file mode 100644 index 0000000..d54f979 --- /dev/null +++ b/lib/data/dao/player_group_dao.g.dart @@ -0,0 +1,11 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'player_group_dao.dart'; + +// ignore_for_file: type=lint +mixin _$PlayerGroupDaoMixin on DatabaseAccessor { + $PlayerTableTable get playerTable => attachedDatabase.playerTable; + $GroupTableTable get groupTable => attachedDatabase.groupTable; + $PlayerGroupTableTable get playerGroupTable => + attachedDatabase.playerGroupTable; +} diff --git a/lib/data/db/database.dart b/lib/data/db/database.dart new file mode 100644 index 0000000..e35513e --- /dev/null +++ b/lib/data/db/database.dart @@ -0,0 +1,33 @@ +import 'package:drift/drift.dart'; +import 'package:drift_flutter/drift_flutter.dart'; +import 'package:game_tracker/data/dao/game_dao.dart'; +import 'package:game_tracker/data/dao/group_dao.dart'; +import 'package:game_tracker/data/dao/player_dao.dart'; +import 'package:game_tracker/data/dao/player_group_dao.dart'; +import 'package:game_tracker/data/db/tables/game_table.dart'; +import 'package:game_tracker/data/db/tables/group_table.dart'; +import 'package:game_tracker/data/db/tables/player_group_table.dart'; +import 'package:game_tracker/data/db/tables/player_table.dart'; +import 'package:path_provider/path_provider.dart'; + +part 'database.g.dart'; + +@DriftDatabase( + tables: [PlayerTable, GroupTable, PlayerGroupTable, GameTable], + daos: [GroupDao, PlayerDao, PlayerGroupDao, GameDao], +) +class AppDatabase extends _$AppDatabase { + AppDatabase([QueryExecutor? executor]) : super(executor ?? _openConnection()); + + @override + int get schemaVersion => 1; + + static QueryExecutor _openConnection() { + return driftDatabase( + name: 'gametracker_db', + native: const DriftNativeOptions( + databaseDirectory: getApplicationSupportDirectory, + ), + ); + } +} diff --git a/lib/data/db/database.g.dart b/lib/data/db/database.g.dart new file mode 100644 index 0000000..4075912 --- /dev/null +++ b/lib/data/db/database.g.dart @@ -0,0 +1,1871 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'database.dart'; + +// ignore_for_file: type=lint +class $PlayerTableTable extends PlayerTable + with TableInfo<$PlayerTableTable, PlayerTableData> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $PlayerTableTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + static const VerificationMeta _nameMeta = const VerificationMeta('name'); + @override + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + @override + List get $columns => [id, name]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'player_table'; + @override + VerificationContext validateIntegrity( + Insertable instance, { + bool isInserting = false, + }) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('id')) { + context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); + } else if (isInserting) { + context.missing(_idMeta); + } + if (data.containsKey('name')) { + context.handle( + _nameMeta, + name.isAcceptableOrUnknown(data['name']!, _nameMeta), + ); + } else if (isInserting) { + context.missing(_nameMeta); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + PlayerTableData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return PlayerTableData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + ); + } + + @override + $PlayerTableTable createAlias(String alias) { + return $PlayerTableTable(attachedDatabase, alias); + } +} + +class PlayerTableData extends DataClass implements Insertable { + final String id; + final String name; + const PlayerTableData({required this.id, required this.name}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + return map; + } + + PlayerTableCompanion toCompanion(bool nullToAbsent) { + return PlayerTableCompanion(id: Value(id), name: Value(name)); + } + + factory PlayerTableData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return PlayerTableData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + }; + } + + PlayerTableData copyWith({String? id, String? name}) => + PlayerTableData(id: id ?? this.id, name: name ?? this.name); + PlayerTableData copyWithCompanion(PlayerTableCompanion data) { + return PlayerTableData( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + ); + } + + @override + String toString() { + return (StringBuffer('PlayerTableData(') + ..write('id: $id, ') + ..write('name: $name') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, name); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is PlayerTableData && + other.id == this.id && + other.name == this.name); +} + +class PlayerTableCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value rowid; + const PlayerTableCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.rowid = const Value.absent(), + }); + PlayerTableCompanion.insert({ + required String id, + required String name, + this.rowid = const Value.absent(), + }) : id = Value(id), + name = Value(name); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (rowid != null) 'rowid': rowid, + }); + } + + PlayerTableCompanion copyWith({ + Value? id, + Value? name, + Value? rowid, + }) { + return PlayerTableCompanion( + id: id ?? this.id, + name: name ?? this.name, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('PlayerTableCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class $GroupTableTable extends GroupTable + with TableInfo<$GroupTableTable, GroupTableData> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $GroupTableTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + static const VerificationMeta _nameMeta = const VerificationMeta('name'); + @override + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + @override + List get $columns => [id, name]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'group_table'; + @override + VerificationContext validateIntegrity( + Insertable instance, { + bool isInserting = false, + }) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('id')) { + context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); + } else if (isInserting) { + context.missing(_idMeta); + } + if (data.containsKey('name')) { + context.handle( + _nameMeta, + name.isAcceptableOrUnknown(data['name']!, _nameMeta), + ); + } else if (isInserting) { + context.missing(_nameMeta); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + GroupTableData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return GroupTableData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + ); + } + + @override + $GroupTableTable createAlias(String alias) { + return $GroupTableTable(attachedDatabase, alias); + } +} + +class GroupTableData extends DataClass implements Insertable { + final String id; + final String name; + const GroupTableData({required this.id, required this.name}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + return map; + } + + GroupTableCompanion toCompanion(bool nullToAbsent) { + return GroupTableCompanion(id: Value(id), name: Value(name)); + } + + factory GroupTableData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return GroupTableData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + }; + } + + GroupTableData copyWith({String? id, String? name}) => + GroupTableData(id: id ?? this.id, name: name ?? this.name); + GroupTableData copyWithCompanion(GroupTableCompanion data) { + return GroupTableData( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + ); + } + + @override + String toString() { + return (StringBuffer('GroupTableData(') + ..write('id: $id, ') + ..write('name: $name') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, name); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is GroupTableData && + other.id == this.id && + other.name == this.name); +} + +class GroupTableCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value rowid; + const GroupTableCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.rowid = const Value.absent(), + }); + GroupTableCompanion.insert({ + required String id, + required String name, + this.rowid = const Value.absent(), + }) : id = Value(id), + name = Value(name); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (rowid != null) 'rowid': rowid, + }); + } + + GroupTableCompanion copyWith({ + Value? id, + Value? name, + Value? rowid, + }) { + return GroupTableCompanion( + id: id ?? this.id, + name: name ?? this.name, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('GroupTableCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class $PlayerGroupTableTable extends PlayerGroupTable + with TableInfo<$PlayerGroupTableTable, PlayerGroupTableData> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $PlayerGroupTableTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _userIdMeta = const VerificationMeta('userId'); + @override + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES player_table (id)', + ), + ); + static const VerificationMeta _groupIdMeta = const VerificationMeta( + 'groupId', + ); + @override + late final GeneratedColumn groupId = GeneratedColumn( + 'group_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES group_table (id)', + ), + ); + @override + List get $columns => [userId, groupId]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'player_group_table'; + @override + VerificationContext validateIntegrity( + Insertable instance, { + bool isInserting = false, + }) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('user_id')) { + context.handle( + _userIdMeta, + userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta), + ); + } else if (isInserting) { + context.missing(_userIdMeta); + } + if (data.containsKey('group_id')) { + context.handle( + _groupIdMeta, + groupId.isAcceptableOrUnknown(data['group_id']!, _groupIdMeta), + ); + } else if (isInserting) { + context.missing(_groupIdMeta); + } + return context; + } + + @override + Set get $primaryKey => {userId, groupId}; + @override + PlayerGroupTableData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return PlayerGroupTableData( + userId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}user_id'], + )!, + groupId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}group_id'], + )!, + ); + } + + @override + $PlayerGroupTableTable createAlias(String alias) { + return $PlayerGroupTableTable(attachedDatabase, alias); + } +} + +class PlayerGroupTableData extends DataClass + implements Insertable { + final String userId; + final String groupId; + const PlayerGroupTableData({required this.userId, required this.groupId}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['user_id'] = Variable(userId); + map['group_id'] = Variable(groupId); + return map; + } + + PlayerGroupTableCompanion toCompanion(bool nullToAbsent) { + return PlayerGroupTableCompanion( + userId: Value(userId), + groupId: Value(groupId), + ); + } + + factory PlayerGroupTableData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return PlayerGroupTableData( + userId: serializer.fromJson(json['userId']), + groupId: serializer.fromJson(json['groupId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'userId': serializer.toJson(userId), + 'groupId': serializer.toJson(groupId), + }; + } + + PlayerGroupTableData copyWith({String? userId, String? groupId}) => + PlayerGroupTableData( + userId: userId ?? this.userId, + groupId: groupId ?? this.groupId, + ); + PlayerGroupTableData copyWithCompanion(PlayerGroupTableCompanion data) { + return PlayerGroupTableData( + userId: data.userId.present ? data.userId.value : this.userId, + groupId: data.groupId.present ? data.groupId.value : this.groupId, + ); + } + + @override + String toString() { + return (StringBuffer('PlayerGroupTableData(') + ..write('userId: $userId, ') + ..write('groupId: $groupId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(userId, groupId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is PlayerGroupTableData && + other.userId == this.userId && + other.groupId == this.groupId); +} + +class PlayerGroupTableCompanion extends UpdateCompanion { + final Value userId; + final Value groupId; + final Value rowid; + const PlayerGroupTableCompanion({ + this.userId = const Value.absent(), + this.groupId = const Value.absent(), + this.rowid = const Value.absent(), + }); + PlayerGroupTableCompanion.insert({ + required String userId, + required String groupId, + this.rowid = const Value.absent(), + }) : userId = Value(userId), + groupId = Value(groupId); + static Insertable custom({ + Expression? userId, + Expression? groupId, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (userId != null) 'user_id': userId, + if (groupId != null) 'group_id': groupId, + if (rowid != null) 'rowid': rowid, + }); + } + + PlayerGroupTableCompanion copyWith({ + Value? userId, + Value? groupId, + Value? rowid, + }) { + return PlayerGroupTableCompanion( + userId: userId ?? this.userId, + groupId: groupId ?? this.groupId, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (userId.present) { + map['user_id'] = Variable(userId.value); + } + if (groupId.present) { + map['group_id'] = Variable(groupId.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('PlayerGroupTableCompanion(') + ..write('userId: $userId, ') + ..write('groupId: $groupId, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class $GameTableTable extends GameTable + with TableInfo<$GameTableTable, GameTableData> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $GameTableTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + static const VerificationMeta _nameMeta = const VerificationMeta('name'); + @override + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + @override + List get $columns => [id, name]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'game_table'; + @override + VerificationContext validateIntegrity( + Insertable instance, { + bool isInserting = false, + }) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('id')) { + context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); + } else if (isInserting) { + context.missing(_idMeta); + } + if (data.containsKey('name')) { + context.handle( + _nameMeta, + name.isAcceptableOrUnknown(data['name']!, _nameMeta), + ); + } else if (isInserting) { + context.missing(_nameMeta); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + GameTableData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return GameTableData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + ); + } + + @override + $GameTableTable createAlias(String alias) { + return $GameTableTable(attachedDatabase, alias); + } +} + +class GameTableData extends DataClass implements Insertable { + final String id; + final String name; + const GameTableData({required this.id, required this.name}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + return map; + } + + GameTableCompanion toCompanion(bool nullToAbsent) { + return GameTableCompanion(id: Value(id), name: Value(name)); + } + + factory GameTableData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return GameTableData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + }; + } + + GameTableData copyWith({String? id, String? name}) => + GameTableData(id: id ?? this.id, name: name ?? this.name); + GameTableData copyWithCompanion(GameTableCompanion data) { + return GameTableData( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + ); + } + + @override + String toString() { + return (StringBuffer('GameTableData(') + ..write('id: $id, ') + ..write('name: $name') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, name); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is GameTableData && + other.id == this.id && + other.name == this.name); +} + +class GameTableCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value rowid; + const GameTableCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.rowid = const Value.absent(), + }); + GameTableCompanion.insert({ + required String id, + required String name, + this.rowid = const Value.absent(), + }) : id = Value(id), + name = Value(name); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (rowid != null) 'rowid': rowid, + }); + } + + GameTableCompanion copyWith({ + Value? id, + Value? name, + Value? rowid, + }) { + return GameTableCompanion( + id: id ?? this.id, + name: name ?? this.name, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('GameTableCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +abstract class _$AppDatabase extends GeneratedDatabase { + _$AppDatabase(QueryExecutor e) : super(e); + $AppDatabaseManager get managers => $AppDatabaseManager(this); + late final $PlayerTableTable playerTable = $PlayerTableTable(this); + late final $GroupTableTable groupTable = $GroupTableTable(this); + late final $PlayerGroupTableTable playerGroupTable = $PlayerGroupTableTable( + this, + ); + late final $GameTableTable gameTable = $GameTableTable(this); + late final GroupDao groupDao = GroupDao(this as AppDatabase); + late final PlayerDao playerDao = PlayerDao(this as AppDatabase); + late final PlayerGroupDao playerGroupDao = PlayerGroupDao( + this as AppDatabase, + ); + late final GameDao gameDao = GameDao(this as AppDatabase); + @override + Iterable> get allTables => + allSchemaEntities.whereType>(); + @override + List get allSchemaEntities => [ + playerTable, + groupTable, + playerGroupTable, + gameTable, + ]; +} + +typedef $$PlayerTableTableCreateCompanionBuilder = + PlayerTableCompanion Function({ + required String id, + required String name, + Value rowid, + }); +typedef $$PlayerTableTableUpdateCompanionBuilder = + PlayerTableCompanion Function({ + Value id, + Value name, + Value rowid, + }); + +final class $$PlayerTableTableReferences + extends BaseReferences<_$AppDatabase, $PlayerTableTable, PlayerTableData> { + $$PlayerTableTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static MultiTypedResultKey<$PlayerGroupTableTable, List> + _playerGroupTableRefsTable(_$AppDatabase db) => MultiTypedResultKey.fromTable( + db.playerGroupTable, + aliasName: $_aliasNameGenerator( + db.playerTable.id, + db.playerGroupTable.userId, + ), + ); + + $$PlayerGroupTableTableProcessedTableManager get playerGroupTableRefs { + final manager = $$PlayerGroupTableTableTableManager( + $_db, + $_db.playerGroupTable, + ).filter((f) => f.userId.id.sqlEquals($_itemColumn('id')!)); + + final cache = $_typedResult.readTableOrNull( + _playerGroupTableRefsTable($_db), + ); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache), + ); + } +} + +class $$PlayerTableTableFilterComposer + extends Composer<_$AppDatabase, $PlayerTableTable> { + $$PlayerTableTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder( + column: $table.id, + builder: (column) => ColumnFilters(column), + ); + + ColumnFilters get name => $composableBuilder( + column: $table.name, + builder: (column) => ColumnFilters(column), + ); + + Expression playerGroupTableRefs( + Expression Function($$PlayerGroupTableTableFilterComposer f) f, + ) { + final $$PlayerGroupTableTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.playerGroupTable, + getReferencedColumn: (t) => t.userId, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$PlayerGroupTableTableFilterComposer( + $db: $db, + $table: $db.playerGroupTable, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return f(composer); + } +} + +class $$PlayerTableTableOrderingComposer + extends Composer<_$AppDatabase, $PlayerTableTable> { + $$PlayerTableTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder( + column: $table.id, + builder: (column) => ColumnOrderings(column), + ); + + ColumnOrderings get name => $composableBuilder( + column: $table.name, + builder: (column) => ColumnOrderings(column), + ); +} + +class $$PlayerTableTableAnnotationComposer + extends Composer<_$AppDatabase, $PlayerTableTable> { + $$PlayerTableTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get name => + $composableBuilder(column: $table.name, builder: (column) => column); + + Expression playerGroupTableRefs( + Expression Function($$PlayerGroupTableTableAnnotationComposer a) f, + ) { + final $$PlayerGroupTableTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.playerGroupTable, + getReferencedColumn: (t) => t.userId, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$PlayerGroupTableTableAnnotationComposer( + $db: $db, + $table: $db.playerGroupTable, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return f(composer); + } +} + +class $$PlayerTableTableTableManager + extends + RootTableManager< + _$AppDatabase, + $PlayerTableTable, + PlayerTableData, + $$PlayerTableTableFilterComposer, + $$PlayerTableTableOrderingComposer, + $$PlayerTableTableAnnotationComposer, + $$PlayerTableTableCreateCompanionBuilder, + $$PlayerTableTableUpdateCompanionBuilder, + (PlayerTableData, $$PlayerTableTableReferences), + PlayerTableData, + PrefetchHooks Function({bool playerGroupTableRefs}) + > { + $$PlayerTableTableTableManager(_$AppDatabase db, $PlayerTableTable table) + : super( + TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$PlayerTableTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$PlayerTableTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$PlayerTableTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: + ({ + Value id = const Value.absent(), + Value name = const Value.absent(), + Value rowid = const Value.absent(), + }) => PlayerTableCompanion(id: id, name: name, rowid: rowid), + createCompanionCallback: + ({ + required String id, + required String name, + Value rowid = const Value.absent(), + }) => + PlayerTableCompanion.insert(id: id, name: name, rowid: rowid), + withReferenceMapper: (p0) => p0 + .map( + (e) => ( + e.readTable(table), + $$PlayerTableTableReferences(db, table, e), + ), + ) + .toList(), + prefetchHooksCallback: ({playerGroupTableRefs = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [ + if (playerGroupTableRefs) db.playerGroupTable, + ], + addJoins: null, + getPrefetchedDataCallback: (items) async { + return [ + if (playerGroupTableRefs) + await $_getPrefetchedData< + PlayerTableData, + $PlayerTableTable, + PlayerGroupTableData + >( + currentTable: table, + referencedTable: $$PlayerTableTableReferences + ._playerGroupTableRefsTable(db), + managerFromTypedResult: (p0) => + $$PlayerTableTableReferences( + db, + table, + p0, + ).playerGroupTableRefs, + referencedItemsForCurrentItem: (item, referencedItems) => + referencedItems.where((e) => e.userId == item.id), + typedResults: items, + ), + ]; + }, + ); + }, + ), + ); +} + +typedef $$PlayerTableTableProcessedTableManager = + ProcessedTableManager< + _$AppDatabase, + $PlayerTableTable, + PlayerTableData, + $$PlayerTableTableFilterComposer, + $$PlayerTableTableOrderingComposer, + $$PlayerTableTableAnnotationComposer, + $$PlayerTableTableCreateCompanionBuilder, + $$PlayerTableTableUpdateCompanionBuilder, + (PlayerTableData, $$PlayerTableTableReferences), + PlayerTableData, + PrefetchHooks Function({bool playerGroupTableRefs}) + >; +typedef $$GroupTableTableCreateCompanionBuilder = + GroupTableCompanion Function({ + required String id, + required String name, + Value rowid, + }); +typedef $$GroupTableTableUpdateCompanionBuilder = + GroupTableCompanion Function({ + Value id, + Value name, + Value rowid, + }); + +final class $$GroupTableTableReferences + extends BaseReferences<_$AppDatabase, $GroupTableTable, GroupTableData> { + $$GroupTableTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static MultiTypedResultKey<$PlayerGroupTableTable, List> + _playerGroupTableRefsTable(_$AppDatabase db) => MultiTypedResultKey.fromTable( + db.playerGroupTable, + aliasName: $_aliasNameGenerator( + db.groupTable.id, + db.playerGroupTable.groupId, + ), + ); + + $$PlayerGroupTableTableProcessedTableManager get playerGroupTableRefs { + final manager = $$PlayerGroupTableTableTableManager( + $_db, + $_db.playerGroupTable, + ).filter((f) => f.groupId.id.sqlEquals($_itemColumn('id')!)); + + final cache = $_typedResult.readTableOrNull( + _playerGroupTableRefsTable($_db), + ); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache), + ); + } +} + +class $$GroupTableTableFilterComposer + extends Composer<_$AppDatabase, $GroupTableTable> { + $$GroupTableTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder( + column: $table.id, + builder: (column) => ColumnFilters(column), + ); + + ColumnFilters get name => $composableBuilder( + column: $table.name, + builder: (column) => ColumnFilters(column), + ); + + Expression playerGroupTableRefs( + Expression Function($$PlayerGroupTableTableFilterComposer f) f, + ) { + final $$PlayerGroupTableTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.playerGroupTable, + getReferencedColumn: (t) => t.groupId, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$PlayerGroupTableTableFilterComposer( + $db: $db, + $table: $db.playerGroupTable, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return f(composer); + } +} + +class $$GroupTableTableOrderingComposer + extends Composer<_$AppDatabase, $GroupTableTable> { + $$GroupTableTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder( + column: $table.id, + builder: (column) => ColumnOrderings(column), + ); + + ColumnOrderings get name => $composableBuilder( + column: $table.name, + builder: (column) => ColumnOrderings(column), + ); +} + +class $$GroupTableTableAnnotationComposer + extends Composer<_$AppDatabase, $GroupTableTable> { + $$GroupTableTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get name => + $composableBuilder(column: $table.name, builder: (column) => column); + + Expression playerGroupTableRefs( + Expression Function($$PlayerGroupTableTableAnnotationComposer a) f, + ) { + final $$PlayerGroupTableTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.playerGroupTable, + getReferencedColumn: (t) => t.groupId, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$PlayerGroupTableTableAnnotationComposer( + $db: $db, + $table: $db.playerGroupTable, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return f(composer); + } +} + +class $$GroupTableTableTableManager + extends + RootTableManager< + _$AppDatabase, + $GroupTableTable, + GroupTableData, + $$GroupTableTableFilterComposer, + $$GroupTableTableOrderingComposer, + $$GroupTableTableAnnotationComposer, + $$GroupTableTableCreateCompanionBuilder, + $$GroupTableTableUpdateCompanionBuilder, + (GroupTableData, $$GroupTableTableReferences), + GroupTableData, + PrefetchHooks Function({bool playerGroupTableRefs}) + > { + $$GroupTableTableTableManager(_$AppDatabase db, $GroupTableTable table) + : super( + TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$GroupTableTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$GroupTableTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$GroupTableTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: + ({ + Value id = const Value.absent(), + Value name = const Value.absent(), + Value rowid = const Value.absent(), + }) => GroupTableCompanion(id: id, name: name, rowid: rowid), + createCompanionCallback: + ({ + required String id, + required String name, + Value rowid = const Value.absent(), + }) => + GroupTableCompanion.insert(id: id, name: name, rowid: rowid), + withReferenceMapper: (p0) => p0 + .map( + (e) => ( + e.readTable(table), + $$GroupTableTableReferences(db, table, e), + ), + ) + .toList(), + prefetchHooksCallback: ({playerGroupTableRefs = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [ + if (playerGroupTableRefs) db.playerGroupTable, + ], + addJoins: null, + getPrefetchedDataCallback: (items) async { + return [ + if (playerGroupTableRefs) + await $_getPrefetchedData< + GroupTableData, + $GroupTableTable, + PlayerGroupTableData + >( + currentTable: table, + referencedTable: $$GroupTableTableReferences + ._playerGroupTableRefsTable(db), + managerFromTypedResult: (p0) => + $$GroupTableTableReferences( + db, + table, + p0, + ).playerGroupTableRefs, + referencedItemsForCurrentItem: (item, referencedItems) => + referencedItems.where((e) => e.groupId == item.id), + typedResults: items, + ), + ]; + }, + ); + }, + ), + ); +} + +typedef $$GroupTableTableProcessedTableManager = + ProcessedTableManager< + _$AppDatabase, + $GroupTableTable, + GroupTableData, + $$GroupTableTableFilterComposer, + $$GroupTableTableOrderingComposer, + $$GroupTableTableAnnotationComposer, + $$GroupTableTableCreateCompanionBuilder, + $$GroupTableTableUpdateCompanionBuilder, + (GroupTableData, $$GroupTableTableReferences), + GroupTableData, + PrefetchHooks Function({bool playerGroupTableRefs}) + >; +typedef $$PlayerGroupTableTableCreateCompanionBuilder = + PlayerGroupTableCompanion Function({ + required String userId, + required String groupId, + Value rowid, + }); +typedef $$PlayerGroupTableTableUpdateCompanionBuilder = + PlayerGroupTableCompanion Function({ + Value userId, + Value groupId, + Value rowid, + }); + +final class $$PlayerGroupTableTableReferences + extends + BaseReferences< + _$AppDatabase, + $PlayerGroupTableTable, + PlayerGroupTableData + > { + $$PlayerGroupTableTableReferences( + super.$_db, + super.$_table, + super.$_typedResult, + ); + + static $PlayerTableTable _userIdTable(_$AppDatabase db) => + db.playerTable.createAlias( + $_aliasNameGenerator(db.playerGroupTable.userId, db.playerTable.id), + ); + + $$PlayerTableTableProcessedTableManager get userId { + final $_column = $_itemColumn('user_id')!; + + final manager = $$PlayerTableTableTableManager( + $_db, + $_db.playerTable, + ).filter((f) => f.id.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_userIdTable($_db)); + if (item == null) return manager; + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item]), + ); + } + + static $GroupTableTable _groupIdTable(_$AppDatabase db) => + db.groupTable.createAlias( + $_aliasNameGenerator(db.playerGroupTable.groupId, db.groupTable.id), + ); + + $$GroupTableTableProcessedTableManager get groupId { + final $_column = $_itemColumn('group_id')!; + + final manager = $$GroupTableTableTableManager( + $_db, + $_db.groupTable, + ).filter((f) => f.id.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_groupIdTable($_db)); + if (item == null) return manager; + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item]), + ); + } +} + +class $$PlayerGroupTableTableFilterComposer + extends Composer<_$AppDatabase, $PlayerGroupTableTable> { + $$PlayerGroupTableTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + $$PlayerTableTableFilterComposer get userId { + final $$PlayerTableTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.userId, + referencedTable: $db.playerTable, + getReferencedColumn: (t) => t.id, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$PlayerTableTableFilterComposer( + $db: $db, + $table: $db.playerTable, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return composer; + } + + $$GroupTableTableFilterComposer get groupId { + final $$GroupTableTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.groupId, + referencedTable: $db.groupTable, + getReferencedColumn: (t) => t.id, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$GroupTableTableFilterComposer( + $db: $db, + $table: $db.groupTable, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return composer; + } +} + +class $$PlayerGroupTableTableOrderingComposer + extends Composer<_$AppDatabase, $PlayerGroupTableTable> { + $$PlayerGroupTableTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + $$PlayerTableTableOrderingComposer get userId { + final $$PlayerTableTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.userId, + referencedTable: $db.playerTable, + getReferencedColumn: (t) => t.id, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$PlayerTableTableOrderingComposer( + $db: $db, + $table: $db.playerTable, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return composer; + } + + $$GroupTableTableOrderingComposer get groupId { + final $$GroupTableTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.groupId, + referencedTable: $db.groupTable, + getReferencedColumn: (t) => t.id, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$GroupTableTableOrderingComposer( + $db: $db, + $table: $db.groupTable, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return composer; + } +} + +class $$PlayerGroupTableTableAnnotationComposer + extends Composer<_$AppDatabase, $PlayerGroupTableTable> { + $$PlayerGroupTableTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + $$PlayerTableTableAnnotationComposer get userId { + final $$PlayerTableTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.userId, + referencedTable: $db.playerTable, + getReferencedColumn: (t) => t.id, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$PlayerTableTableAnnotationComposer( + $db: $db, + $table: $db.playerTable, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return composer; + } + + $$GroupTableTableAnnotationComposer get groupId { + final $$GroupTableTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.groupId, + referencedTable: $db.groupTable, + getReferencedColumn: (t) => t.id, + builder: + ( + joinBuilder, { + $addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer, + }) => $$GroupTableTableAnnotationComposer( + $db: $db, + $table: $db.groupTable, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + ), + ); + return composer; + } +} + +class $$PlayerGroupTableTableTableManager + extends + RootTableManager< + _$AppDatabase, + $PlayerGroupTableTable, + PlayerGroupTableData, + $$PlayerGroupTableTableFilterComposer, + $$PlayerGroupTableTableOrderingComposer, + $$PlayerGroupTableTableAnnotationComposer, + $$PlayerGroupTableTableCreateCompanionBuilder, + $$PlayerGroupTableTableUpdateCompanionBuilder, + (PlayerGroupTableData, $$PlayerGroupTableTableReferences), + PlayerGroupTableData, + PrefetchHooks Function({bool userId, bool groupId}) + > { + $$PlayerGroupTableTableTableManager( + _$AppDatabase db, + $PlayerGroupTableTable table, + ) : super( + TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$PlayerGroupTableTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$PlayerGroupTableTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$PlayerGroupTableTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: + ({ + Value userId = const Value.absent(), + Value groupId = const Value.absent(), + Value rowid = const Value.absent(), + }) => PlayerGroupTableCompanion( + userId: userId, + groupId: groupId, + rowid: rowid, + ), + createCompanionCallback: + ({ + required String userId, + required String groupId, + Value rowid = const Value.absent(), + }) => PlayerGroupTableCompanion.insert( + userId: userId, + groupId: groupId, + rowid: rowid, + ), + withReferenceMapper: (p0) => p0 + .map( + (e) => ( + e.readTable(table), + $$PlayerGroupTableTableReferences(db, table, e), + ), + ) + .toList(), + prefetchHooksCallback: ({userId = false, groupId = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [], + addJoins: + < + T extends TableManagerState< + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic + > + >(state) { + if (userId) { + state = + state.withJoin( + currentTable: table, + currentColumn: table.userId, + referencedTable: + $$PlayerGroupTableTableReferences + ._userIdTable(db), + referencedColumn: + $$PlayerGroupTableTableReferences + ._userIdTable(db) + .id, + ) + as T; + } + if (groupId) { + state = + state.withJoin( + currentTable: table, + currentColumn: table.groupId, + referencedTable: + $$PlayerGroupTableTableReferences + ._groupIdTable(db), + referencedColumn: + $$PlayerGroupTableTableReferences + ._groupIdTable(db) + .id, + ) + as T; + } + + return state; + }, + getPrefetchedDataCallback: (items) async { + return []; + }, + ); + }, + ), + ); +} + +typedef $$PlayerGroupTableTableProcessedTableManager = + ProcessedTableManager< + _$AppDatabase, + $PlayerGroupTableTable, + PlayerGroupTableData, + $$PlayerGroupTableTableFilterComposer, + $$PlayerGroupTableTableOrderingComposer, + $$PlayerGroupTableTableAnnotationComposer, + $$PlayerGroupTableTableCreateCompanionBuilder, + $$PlayerGroupTableTableUpdateCompanionBuilder, + (PlayerGroupTableData, $$PlayerGroupTableTableReferences), + PlayerGroupTableData, + PrefetchHooks Function({bool userId, bool groupId}) + >; +typedef $$GameTableTableCreateCompanionBuilder = + GameTableCompanion Function({ + required String id, + required String name, + Value rowid, + }); +typedef $$GameTableTableUpdateCompanionBuilder = + GameTableCompanion Function({ + Value id, + Value name, + Value rowid, + }); + +class $$GameTableTableFilterComposer + extends Composer<_$AppDatabase, $GameTableTable> { + $$GameTableTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get id => $composableBuilder( + column: $table.id, + builder: (column) => ColumnFilters(column), + ); + + ColumnFilters get name => $composableBuilder( + column: $table.name, + builder: (column) => ColumnFilters(column), + ); +} + +class $$GameTableTableOrderingComposer + extends Composer<_$AppDatabase, $GameTableTable> { + $$GameTableTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get id => $composableBuilder( + column: $table.id, + builder: (column) => ColumnOrderings(column), + ); + + ColumnOrderings get name => $composableBuilder( + column: $table.name, + builder: (column) => ColumnOrderings(column), + ); +} + +class $$GameTableTableAnnotationComposer + extends Composer<_$AppDatabase, $GameTableTable> { + $$GameTableTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get name => + $composableBuilder(column: $table.name, builder: (column) => column); +} + +class $$GameTableTableTableManager + extends + RootTableManager< + _$AppDatabase, + $GameTableTable, + GameTableData, + $$GameTableTableFilterComposer, + $$GameTableTableOrderingComposer, + $$GameTableTableAnnotationComposer, + $$GameTableTableCreateCompanionBuilder, + $$GameTableTableUpdateCompanionBuilder, + ( + GameTableData, + BaseReferences<_$AppDatabase, $GameTableTable, GameTableData>, + ), + GameTableData, + PrefetchHooks Function() + > { + $$GameTableTableTableManager(_$AppDatabase db, $GameTableTable table) + : super( + TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$GameTableTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$GameTableTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$GameTableTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: + ({ + Value id = const Value.absent(), + Value name = const Value.absent(), + Value rowid = const Value.absent(), + }) => GameTableCompanion(id: id, name: name, rowid: rowid), + createCompanionCallback: + ({ + required String id, + required String name, + Value rowid = const Value.absent(), + }) => GameTableCompanion.insert(id: id, name: name, rowid: rowid), + withReferenceMapper: (p0) => p0 + .map((e) => (e.readTable(table), BaseReferences(db, table, e))) + .toList(), + prefetchHooksCallback: null, + ), + ); +} + +typedef $$GameTableTableProcessedTableManager = + ProcessedTableManager< + _$AppDatabase, + $GameTableTable, + GameTableData, + $$GameTableTableFilterComposer, + $$GameTableTableOrderingComposer, + $$GameTableTableAnnotationComposer, + $$GameTableTableCreateCompanionBuilder, + $$GameTableTableUpdateCompanionBuilder, + ( + GameTableData, + BaseReferences<_$AppDatabase, $GameTableTable, GameTableData>, + ), + GameTableData, + PrefetchHooks Function() + >; + +class $AppDatabaseManager { + final _$AppDatabase _db; + $AppDatabaseManager(this._db); + $$PlayerTableTableTableManager get playerTable => + $$PlayerTableTableTableManager(_db, _db.playerTable); + $$GroupTableTableTableManager get groupTable => + $$GroupTableTableTableManager(_db, _db.groupTable); + $$PlayerGroupTableTableTableManager get playerGroupTable => + $$PlayerGroupTableTableTableManager(_db, _db.playerGroupTable); + $$GameTableTableTableManager get gameTable => + $$GameTableTableTableManager(_db, _db.gameTable); +} diff --git a/lib/data/db/tables/game_table.dart b/lib/data/db/tables/game_table.dart new file mode 100644 index 0000000..45bfb20 --- /dev/null +++ b/lib/data/db/tables/game_table.dart @@ -0,0 +1,9 @@ +import 'package:drift/drift.dart'; + +class GameTable extends Table { + TextColumn get id => text()(); + TextColumn get name => text()(); + + @override + Set> get primaryKey => {id}; +} diff --git a/lib/data/db/tables/group_table.dart b/lib/data/db/tables/group_table.dart new file mode 100644 index 0000000..dc9335d --- /dev/null +++ b/lib/data/db/tables/group_table.dart @@ -0,0 +1,9 @@ +import 'package:drift/drift.dart'; + +class GroupTable extends Table { + TextColumn get id => text()(); + TextColumn get name => text()(); + + @override + Set> get primaryKey => {id}; +} diff --git a/lib/data/db/tables/player_group_table.dart b/lib/data/db/tables/player_group_table.dart new file mode 100644 index 0000000..096a981 --- /dev/null +++ b/lib/data/db/tables/player_group_table.dart @@ -0,0 +1,11 @@ +import 'package:drift/drift.dart'; +import 'package:game_tracker/data/db/tables/group_table.dart'; +import 'package:game_tracker/data/db/tables/player_table.dart'; + +class PlayerGroupTable extends Table { + TextColumn get userId => text().references(PlayerTable, #id)(); + TextColumn get groupId => text().references(GroupTable, #id)(); + + @override + Set> get primaryKey => {userId, groupId}; +} diff --git a/lib/data/db/tables/player_table.dart b/lib/data/db/tables/player_table.dart new file mode 100644 index 0000000..3d97459 --- /dev/null +++ b/lib/data/db/tables/player_table.dart @@ -0,0 +1,9 @@ +import 'package:drift/drift.dart'; + +class PlayerTable extends Table { + TextColumn get id => text()(); + TextColumn get name => text()(); + + @override + Set> get primaryKey => {id}; +} diff --git a/lib/data/dto/game.dart b/lib/data/dto/game.dart new file mode 100644 index 0000000..7457b54 --- /dev/null +++ b/lib/data/dto/game.dart @@ -0,0 +1,6 @@ +class Game { + final String id; + final String name; + + Game({required this.id, required this.name}); +} diff --git a/lib/data/dto/group.dart b/lib/data/dto/group.dart new file mode 100644 index 0000000..6f12fe9 --- /dev/null +++ b/lib/data/dto/group.dart @@ -0,0 +1,9 @@ +import 'package:game_tracker/data/dto/player.dart'; + +class Group { + final String id; + final String name; + final List members; + + Group({required this.id, required this.name, required this.members}); +} diff --git a/lib/data/dto/player.dart b/lib/data/dto/player.dart new file mode 100644 index 0000000..d5e84e8 --- /dev/null +++ b/lib/data/dto/player.dart @@ -0,0 +1,6 @@ +class Player { + final String id; + final String name; + + Player({required this.id, required this.name}); +} diff --git a/lib/main.dart b/lib/main.dart index 1188332..22f94c7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,8 +1,17 @@ import 'package:flutter/material.dart'; -import 'package:game_tracker/presentation/views/home_view.dart'; +import 'package:game_tracker/core/custom_theme.dart'; +import 'package:game_tracker/data/db/database.dart'; +import 'package:game_tracker/presentation/views/main_menu/custom_navigation_bar.dart'; +import 'package:provider/provider.dart'; void main() { - runApp(const MyApp()); + runApp( + Provider( + create: (context) => AppDatabase(), + child: const MyApp(), + dispose: (context, db) => db.close(), + ), + ); } class MyApp extends StatelessWidget { @@ -11,11 +20,23 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( + debugShowCheckedModeBanner: false, title: 'Game Tracker', + darkTheme: ThemeData.dark(), + + themeMode: ThemeMode.dark, // forces dark mode theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + primaryColor: CustomTheme.primaryColor, + scaffoldBackgroundColor: CustomTheme.backgroundColor, + appBarTheme: CustomTheme.appBarTheme, + + colorScheme: ColorScheme.fromSeed( + seedColor: CustomTheme.primaryColor, + brightness: Brightness.dark, + ).copyWith(surface: CustomTheme.backgroundColor), ), - home: const HomeView(), + + home: const CustomNavigationBar(), ); } } diff --git a/lib/presentation/views/home_view.dart b/lib/presentation/views/home_view.dart deleted file mode 100644 index 234dc1a..0000000 --- a/lib/presentation/views/home_view.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:flutter/material.dart'; - -class HomeView extends StatelessWidget { - const HomeView({super.key}); - - @override - Widget build(BuildContext context) { - return const Placeholder(); - } -} diff --git a/lib/presentation/views/main_menu/custom_navigation_bar.dart b/lib/presentation/views/main_menu/custom_navigation_bar.dart new file mode 100644 index 0000000..20ced7a --- /dev/null +++ b/lib/presentation/views/main_menu/custom_navigation_bar.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; +import 'package:game_tracker/core/custom_theme.dart'; +import 'package:game_tracker/presentation/views/main_menu/game_history_view.dart'; +import 'package:game_tracker/presentation/views/main_menu/groups_view.dart'; +import 'package:game_tracker/presentation/views/main_menu/home_view.dart'; +import 'package:game_tracker/presentation/views/main_menu/settings_view.dart'; +import 'package:game_tracker/presentation/views/main_menu/statistics_view.dart'; +import 'package:game_tracker/presentation/widgets/navbar_item.dart'; + +class CustomNavigationBar extends StatefulWidget { + const CustomNavigationBar({super.key}); + + @override + State createState() => _CustomNavigationBarState(); +} + +class _CustomNavigationBarState extends State + with SingleTickerProviderStateMixin { + int currentIndex = 0; + final List tabs = [ + const HomeView(), + const GameHistoryView(), + const GroupsView(), + const StatisticsView(), + ]; + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + centerTitle: true, + title: Text( + _currentTabTitle(), + style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + backgroundColor: CustomTheme.backgroundColor, + scrolledUnderElevation: 0, + actions: [ + IconButton( + onPressed: () => Navigator.push( + context, + MaterialPageRoute(builder: (_) => const SettingsView()), + ), + icon: const Icon(Icons.settings), + ), + ], + elevation: 0, + ), + backgroundColor: CustomTheme.backgroundColor, + body: tabs[currentIndex], + extendBody: true, + bottomNavigationBar: Padding( + padding: const EdgeInsets.only(left: 12.0, right: 12.0, bottom: 8.0), + child: Material( + elevation: 10, + borderRadius: BorderRadius.circular(24), + color: CustomTheme.primaryColor, + child: ClipRRect( + borderRadius: BorderRadius.circular(24), + child: SizedBox( + height: 60, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + NavbarItem( + index: 0, + isSelected: currentIndex == 0, + icon: Icons.home_rounded, + label: 'Home', + onTabTapped: onTabTapped, + ), + NavbarItem( + index: 1, + isSelected: currentIndex == 1, + icon: Icons.gamepad_rounded, + label: 'Games', + onTabTapped: onTabTapped, + ), + NavbarItem( + index: 2, + isSelected: currentIndex == 2, + icon: Icons.group_rounded, + label: 'Groups', + onTabTapped: onTabTapped, + ), + NavbarItem( + index: 3, + isSelected: currentIndex == 3, + icon: Icons.bar_chart_rounded, + label: 'Stats', + onTabTapped: onTabTapped, + ), + ], + ), + ), + ), + ), + ), + ); + } + + void onTabTapped(int index) { + setState(() { + currentIndex = index; + }); + } + + String _currentTabTitle() { + switch (currentIndex) { + case 0: + return 'Home'; + case 1: + return 'Game History'; + case 2: + return 'Groups'; + case 3: + return 'Statistics'; + default: + return ''; + } + } +} diff --git a/lib/presentation/views/main_menu/game_history_view.dart b/lib/presentation/views/main_menu/game_history_view.dart new file mode 100644 index 0000000..de75ae6 --- /dev/null +++ b/lib/presentation/views/main_menu/game_history_view.dart @@ -0,0 +1,198 @@ +import 'package:flutter/material.dart'; +import 'package:game_tracker/core/custom_theme.dart'; +import 'package:game_tracker/presentation/widgets/top_centered_message.dart'; +import 'package:game_tracker/presentation/widgets/double_row_info_tile.dart'; + +class GameHistoryView extends StatefulWidget { + const GameHistoryView({super.key}); + + @override + State createState() => _GameHistoryViewState(); +} + +class _GameHistoryViewState extends State { + final allGameData = [ + { + 'game': 'Schach', + 'title': 'Abendpartie', + 'players': 2, + 'group': 'Familie', + 'date': '01.06.2024', + }, + { + 'game': 'Monopoly', + 'title': 'Wochenendspaß mit Gras du Saas', + 'players': 4, + 'group': 'Freunde', + 'date': '28.05.2024', + }, + { + 'game': 'Catan', + 'title': 'Strategieabend', + 'players': 3, + 'group': 'Brettspieler', + 'date': '25.05.2024', + }, + { + 'game': 'Uno', + 'title': 'Schnelle Runde', + 'players': 5, + 'group': 'Kollegen', + 'date': '22.05.2024', + }, + { + 'game': 'Poker', + 'title': 'Freitagspoker', + 'players': 6, + 'group': 'Pokerclub', + 'date': '20.05.2024', + }, + { + 'game': 'Scrabble', + 'title': 'Wortschlacht', + 'players': 4, + 'group': 'Familie', + 'date': '18.05.2024', + }, + { + 'game': 'Risiko', + 'title': 'Weltherrschaft', + 'players': 5, + 'group': 'Strategiegruppe', + 'date': '15.05.2024', + }, + { + 'game': 'Zug um Zug', + 'title': 'Zug-Abenteuer', + 'players': 4, + 'group': 'Reisende', + 'date': '12.05.2024', + }, + { + 'game': 'Carcassonne', + 'title': 'Plättchenlegen', + 'players': 3, + 'group': 'Brettspieler', + 'date': '10.05.2024', + }, + { + 'game': 'Pandemie', + 'title': 'Welt retten', + 'players': 4, + 'group': 'Koop-Team', + 'date': '08.05.2024', + }, + { + 'game': 'Cluedo', + 'title': 'Krimiabend', + 'players': 6, + 'group': 'Detektive', + 'date': '05.05.2024', + }, + { + 'game': 'Dixit', + 'title': 'Fantasiespiel', + 'players': 5, + 'group': 'Künstler', + 'date': '02.05.2024', + }, + { + 'game': 'Azul', + 'title': 'Plättchenmeister', + 'players': 4, + 'group': 'Familie', + 'date': '30.04.2024', + }, + { + 'game': 'Splendor', + 'title': 'Edelsteinhändler', + 'players': 3, + 'group': 'Freunde', + 'date': '28.04.2024', + }, + { + 'game': '7 Wonders', + 'title': 'Antike Reiche', + 'players': 7, + 'group': 'Geschichtsfreunde', + 'date': '25.04.2024', + }, + ]; + late List> suggestedGameData; + + @override + void initState() { + super.initState(); + suggestedGameData = List.from(allGameData); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: CustomTheme.backgroundColor, + body: Stack( + children: [ + Column( + children: [ + Container(margin: EdgeInsets.only(bottom: 75)), + Expanded( + child: gameHistoryListView(allGameData, suggestedGameData), + ), + ], + ), + Container( + margin: EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10), + child: SearchBar( + leading: Icon(Icons.search), + onChanged: (value) { + if (value.isEmpty) { + setState(() { + suggestedGameData.clear(); + suggestedGameData.addAll(allGameData); + }); + return; + } + final suggestions = allGameData.where((currentGame) { + return currentGame['game'].toString().toLowerCase().contains( + value.toLowerCase(), + ) || + currentGame['title'].toString().toLowerCase().contains( + value.toLowerCase(), + ) || + currentGame['group'].toString().toLowerCase().contains( + value.toLowerCase(), + ); + }); + setState(() { + suggestedGameData.clear(); + suggestedGameData.addAll(suggestions); + }); + }, + ), + ), + ], + ), + ); + } +} + +Widget gameHistoryListView(allGameData, suggestedGameData) { + if (suggestedGameData.isEmpty && allGameData.isEmpty) { + return TopCenteredMessage("Keine Spiele erstellt"); + } else if (suggestedGameData.isEmpty) { + return TopCenteredMessage("Kein Spiel mit den Suchparametern gefunden."); + } + return ListView.builder( + itemCount: suggestedGameData.length, + itemBuilder: (context, index) { + final currentGame = suggestedGameData[index]; + return doubleRowInfoTile( + currentGame['game'] + ": ", + currentGame['title'], + currentGame['players'].toString() + " Spieler", + currentGame['group'], + currentGame['date'], + ); + }, + ); +} diff --git a/lib/presentation/views/main_menu/groups_view.dart b/lib/presentation/views/main_menu/groups_view.dart new file mode 100644 index 0000000..485d516 --- /dev/null +++ b/lib/presentation/views/main_menu/groups_view.dart @@ -0,0 +1,10 @@ +import 'package:flutter/cupertino.dart'; + +class GroupsView extends StatelessWidget { + const GroupsView({super.key}); + + @override + Widget build(BuildContext context) { + return const Center(child: Text('Groups View')); + } +} diff --git a/lib/presentation/views/main_menu/home_view.dart b/lib/presentation/views/main_menu/home_view.dart new file mode 100644 index 0000000..141af77 --- /dev/null +++ b/lib/presentation/views/main_menu/home_view.dart @@ -0,0 +1,145 @@ +import 'package:flutter/material.dart'; +import 'package:game_tracker/data/db/database.dart'; +import 'package:game_tracker/presentation/widgets/game_tile.dart'; +import 'package:game_tracker/presentation/widgets/quick_create_button.dart'; +import 'package:game_tracker/presentation/widgets/tiles/info_tile.dart'; +import 'package:game_tracker/presentation/widgets/tiles/quick_info_tile.dart'; +import 'package:provider/provider.dart'; + +class HomeView extends StatefulWidget { + const HomeView({super.key}); + + @override + State createState() => _HomeViewState(); +} + +class _HomeViewState extends State { + late Future _gameCountFuture; + late Future _groupCountFuture; + + @override + initState() { + super.initState(); + final db = Provider.of(context, listen: false); + _gameCountFuture = db.gameDao.getGameCount(); + _groupCountFuture = db.groupDao.getGroupCount(); + } + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + FutureBuilder( + future: _gameCountFuture, + builder: (context, snapshot) { + final int count = (snapshot.hasData) ? snapshot.data! : 0; + return QuickInfoTile( + width: constraints.maxWidth * 0.45, + height: constraints.maxHeight * 0.15, + title: 'Games', + icon: Icons.groups_rounded, + value: count, + ); + }, + ), + SizedBox(width: constraints.maxWidth * 0.05), + FutureBuilder( + future: _groupCountFuture, + builder: (context, snapshot) { + final int count = + (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) + ? snapshot.data! + : 0; + return QuickInfoTile( + width: constraints.maxWidth * 0.45, + height: constraints.maxHeight * 0.15, + title: 'Groups', + icon: Icons.groups_rounded, + value: count, + ); + }, + ), + ], + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: InfoTile( + width: constraints.maxWidth * 0.95, + title: 'Recent Games', + icon: Icons.timer, + content: const Padding( + padding: EdgeInsets.symmetric(horizontal: 40.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + GameTile( + gameTitle: 'Gamenight', + gameType: 'Cabo', + ruleset: 'Lowest Points', + players: '5 Players', + winner: 'Leonard', + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 8.0), + child: Divider(), + ), + GameTile( + gameTitle: 'Schoolbreak', + gameType: 'Uno', + ruleset: 'Highest Points', + players: 'The Gang', + winner: 'Lina', + ), + SizedBox(height: 8), + ], + ), + ), + ), + ), + InfoTile( + width: constraints.maxWidth * 0.95, + title: 'Quick Create', + icon: Icons.add_box_rounded, + content: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + QuickCreateButton(text: 'Category 1', onPressed: () {}), + QuickCreateButton(text: 'Category 2', onPressed: () {}), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + QuickCreateButton(text: 'Category 3', onPressed: () {}), + QuickCreateButton(text: 'Category 4', onPressed: () {}), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + QuickCreateButton(text: 'Category 5', onPressed: () {}), + QuickCreateButton(text: 'Category 6', onPressed: () {}), + ], + ), + ], + ), + ), + ], + ), + ); + }, + ); + } +} diff --git a/lib/presentation/views/main_menu/settings_view.dart b/lib/presentation/views/main_menu/settings_view.dart new file mode 100644 index 0000000..c3e75f3 --- /dev/null +++ b/lib/presentation/views/main_menu/settings_view.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class SettingsView extends StatelessWidget { + const SettingsView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Einstellungen')), + body: const Center(child: Text('Settings View')), + ); + } +} diff --git a/lib/presentation/views/main_menu/statistics_view.dart b/lib/presentation/views/main_menu/statistics_view.dart new file mode 100644 index 0000000..84ccf77 --- /dev/null +++ b/lib/presentation/views/main_menu/statistics_view.dart @@ -0,0 +1,10 @@ +import 'package:flutter/cupertino.dart'; + +class StatisticsView extends StatelessWidget { + const StatisticsView({super.key}); + + @override + Widget build(BuildContext context) { + return const Center(child: Text('Statistics View')); + } +} diff --git a/lib/presentation/widgets/double_row_info_tile.dart b/lib/presentation/widgets/double_row_info_tile.dart new file mode 100644 index 0000000..621cc74 --- /dev/null +++ b/lib/presentation/widgets/double_row_info_tile.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:game_tracker/core/custom_theme.dart'; + +Widget doubleRowInfoTile( + String titleOneUpperLeft, + String titleTwoUpperLeft, + String titleUpperRight, + String titleLowerLeft, + String titleLowerRight, +) { + return Container( + margin: EdgeInsets.symmetric(vertical: 5, horizontal: 10), + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: CustomTheme.secondaryColor, + ), + child: Column( + children: [ + Row( + children: [ + Expanded( + flex: 10, + child: Text( + "$titleOneUpperLeft $titleTwoUpperLeft", + style: TextStyle(fontSize: 20), + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ), + Spacer(), + Expanded( + flex: 3, + child: Text( + "$titleUpperRight", + style: TextStyle(fontSize: 20), + overflow: TextOverflow.ellipsis, + maxLines: 1, + textAlign: TextAlign.end, + ), + ), + ], + ), + Row( + children: [ + Expanded( + flex: 10, + child: Text( + "$titleLowerLeft", + style: TextStyle(fontSize: 20), + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ), + Spacer(), + Expanded( + flex: 4, + child: Text( + "$titleLowerRight", + style: TextStyle(fontSize: 20), + overflow: TextOverflow.ellipsis, + maxLines: 1, + textAlign: TextAlign.end, + ), + ), + ], + ), + ], + ), + ); +} diff --git a/lib/presentation/widgets/game_tile.dart b/lib/presentation/widgets/game_tile.dart new file mode 100644 index 0000000..c79a6b7 --- /dev/null +++ b/lib/presentation/widgets/game_tile.dart @@ -0,0 +1,90 @@ +import 'package:flutter/material.dart'; +import 'package:game_tracker/core/custom_theme.dart'; + +class GameTile extends StatefulWidget { + final String gameTitle; + final String gameType; + final String ruleset; + final String players; + final String winner; + + const GameTile({ + super.key, + required this.gameTitle, + required this.gameType, + required this.ruleset, + required this.players, + required this.winner, + }); + + @override + State createState() => _GameTileState(); +} + +class _GameTileState extends State { + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + widget.gameTitle, + style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + const SizedBox(width: 5), + Text( + widget.gameType, + style: const TextStyle(fontSize: 14, color: Colors.grey), + ), + ], + ), + const SizedBox(height: 5), + Container( + padding: const EdgeInsets.symmetric(horizontal: 4), + height: 20, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: CustomTheme.primaryColor, + ), + child: Text( + widget.ruleset, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ), + Center( + heightFactor: 1.5, + child: Text( + widget.players, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ), + Center( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 4), + width: 220, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: Colors.yellow.shade300, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.emoji_events, color: Colors.black, size: 20), + Text( + widget.winner, + textAlign: TextAlign.center, + style: const TextStyle( + fontWeight: FontWeight.bold, + color: Colors.black87, + ), + ), + ], + ), + ), + ), + ], + ); + } +} diff --git a/lib/presentation/widgets/navbar_item.dart b/lib/presentation/widgets/navbar_item.dart new file mode 100644 index 0000000..b249571 --- /dev/null +++ b/lib/presentation/widgets/navbar_item.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; + +class NavbarItem extends StatefulWidget { + final int index; + final bool isSelected; + final IconData icon; + final String label; + final Function(int) onTabTapped; + + const NavbarItem({ + super.key, + required this.index, + required this.isSelected, + required this.icon, + required this.label, + required this.onTabTapped, + }); + + @override + State createState() => _NavbarItemState(); +} + +class _NavbarItemState extends State { + @override + Widget build(BuildContext context) { + return Expanded( + child: GestureDetector( + onTap: () => widget.onTabTapped(widget.index), + behavior: HitTestBehavior.opaque, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 5.0), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + widget.icon, + color: widget.isSelected ? Colors.white : Colors.black, + ), + const SizedBox(height: 4), + Text( + widget.label, + style: TextStyle( + color: widget.isSelected ? Colors.white : Colors.black, + fontSize: 12, + fontWeight: widget.isSelected + ? FontWeight.bold + : FontWeight.normal, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/presentation/widgets/quick_create_button.dart b/lib/presentation/widgets/quick_create_button.dart new file mode 100644 index 0000000..3860f1c --- /dev/null +++ b/lib/presentation/widgets/quick_create_button.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:game_tracker/core/custom_theme.dart'; + +class QuickCreateButton extends StatefulWidget { + final String text; + final VoidCallback? onPressed; + const QuickCreateButton({ + super.key, + required this.text, + required this.onPressed, + }); + + @override + State createState() => _QuickCreateButtonState(); +} + +class _QuickCreateButtonState extends State { + @override + Widget build(BuildContext context) { + return ElevatedButton( + onPressed: widget.onPressed, + style: ElevatedButton.styleFrom( + minimumSize: const Size(140, 45), + backgroundColor: CustomTheme.primaryColor, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + ), + child: Text( + widget.text, + style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + ), + ); + } +} diff --git a/lib/presentation/widgets/tiles/info_tile.dart b/lib/presentation/widgets/tiles/info_tile.dart new file mode 100644 index 0000000..168262e --- /dev/null +++ b/lib/presentation/widgets/tiles/info_tile.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; +import 'package:game_tracker/core/custom_theme.dart'; + +class InfoTile extends StatefulWidget { + final String title; + final IconData icon; + final Widget content; + final EdgeInsets? padding; + final double? height; + final double? width; + const InfoTile({ + super.key, + required this.title, + required this.icon, + required this.content, + this.padding, + this.height, + this.width, + }); + + @override + State createState() => _InfoTileState(); +} + +class _InfoTileState extends State { + @override + Widget build(BuildContext context) { + return Container( + padding: widget.padding ?? const EdgeInsets.all(12), + height: widget.height, + width: widget.width ?? 380, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: CustomTheme.boxColor, + border: Border.all(color: CustomTheme.boxBorder), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Icon(widget.icon), + const SizedBox(width: 5), + Text( + widget.title, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + const SizedBox(height: 10), + widget.content, + ], + ), + ); + } +} diff --git a/lib/presentation/widgets/tiles/quick_info_tile.dart b/lib/presentation/widgets/tiles/quick_info_tile.dart new file mode 100644 index 0000000..423b8d3 --- /dev/null +++ b/lib/presentation/widgets/tiles/quick_info_tile.dart @@ -0,0 +1,62 @@ +import 'package:flutter/material.dart'; +import 'package:game_tracker/core/custom_theme.dart'; + +class QuickInfoTile extends StatefulWidget { + final String title; + final IconData icon; + final int value; + final double? height; + final double? width; + final EdgeInsets? padding; + const QuickInfoTile({ + super.key, + required this.title, + required this.icon, + required this.value, + this.height, + this.width, + this.padding, + }); + + @override + State createState() => _QuickInfoTileState(); +} + +class _QuickInfoTileState extends State { + @override + Widget build(BuildContext context) { + return Container( + padding: widget.padding ?? const EdgeInsets.all(12), + height: widget.height ?? 110, + width: widget.width ?? 180, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: CustomTheme.boxColor, + border: Border.all(color: CustomTheme.boxBorder), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Row( + children: [ + Icon(widget.icon), + const SizedBox(width: 5), + Text( + widget.title, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + const Spacer(), + Text( + widget.value.toString(), + style: const TextStyle(fontSize: 32, fontWeight: FontWeight.bold), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/widgets/top_centered_message.dart b/lib/presentation/widgets/top_centered_message.dart new file mode 100644 index 0000000..6fe34ff --- /dev/null +++ b/lib/presentation/widgets/top_centered_message.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; + +Widget TopCenteredMessage(String message) { + return Container( + padding: EdgeInsets.only(top: 100), + margin: EdgeInsets.only(left: 10, right: 10), + alignment: Alignment.topCenter, + child: Text( + "$message", + style: TextStyle(fontSize: 20), + textAlign: TextAlign.center, + ), + ); +} diff --git a/pubspec.yaml b/pubspec.yaml index aa5fa8a..5fa8019 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,89 +1,30 @@ name: game_tracker -description: "A new Flutter project." -# The following line prevents the package from being accidentally published to -# pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -# In Windows, build-name is used as the major, minor, and patch parts -# of the product and file versions while build-number is used as the build suffix. -version: 1.0.0+1 +description: "Game Tracking App for Card Games" +publish_to: 'none' +version: 0.0.1+21 environment: sdk: ^3.8.1 -# Dependencies specify other packages that your package needs in order to work. -# To automatically upgrade your package dependencies to the latest versions -# consider running `flutter pub upgrade --major-versions`. Alternatively, -# dependencies can be manually updated by changing the version numbers below to -# the latest version available on pub.dev. To see which dependencies have newer -# versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter + material_symbols_icons: ^4.2815.1 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 + drift: ^2.27.0 + drift_flutter: ^0.2.4 + path_provider: ^2.1.5 + provider: ^6.1.5 dev_dependencies: flutter_test: sdk: flutter - - # The "flutter_lints" package below contains a set of recommended lints to - # encourage good coding practices. The lint set provided by the package is - # activated in the `analysis_options.yaml` file located at the root of your - # package. See that file for information about deactivating specific lint - # rules and activating additional ones. flutter_lints: ^5.0.0 + drift_dev: ^2.27.0 + build_runner: ^2.5.4 -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter packages. flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/to/resolution-aware-images - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/to/asset-from-package - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/to/font-from-package