diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3820a95 --- /dev/null +++ b/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ +/coverage/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..7cd7e6a --- /dev/null +++ b/.metadata @@ -0,0 +1,45 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "cc0734ac716fbb8b90f3f9db8020958b1553afa7" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + - platform: android + create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + - platform: ios + create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + - platform: linux + create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + - platform: macos + create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + - platform: web + create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + - platform: windows + create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/README.md b/README.md index 6e35240..6a21be2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,17 @@ # dailyou -Daily mood tracking app \ No newline at end of file +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter) +- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..0d29021 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..be3943c --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,14 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java +.cxx/ + +# Remember to never publicly share your keystore. +# See https://flutter.dev/to/reference-keystore +key.properties +**/*.keystore +**/*.jks diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts new file mode 100644 index 0000000..c3026ca --- /dev/null +++ b/android/app/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + id("com.android.application") + id("kotlin-android") + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id("dev.flutter.flutter-gradle-plugin") +} + +android { + namespace = "com.example.dailyou" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17.toString() + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "com.example.dailyou" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = flutter.minSdkVersion + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig = signingConfigs.getByName("debug") + } + } +} + +flutter { + source = "../.." +} diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..77d52de --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/kotlin/com/example/dailyou/MainActivity.kt b/android/app/src/main/kotlin/com/example/dailyou/MainActivity.kt new file mode 100644 index 0000000..cbcd0ed --- /dev/null +++ b/android/app/src/main/kotlin/com/example/dailyou/MainActivity.kt @@ -0,0 +1,5 @@ +package com.example.dailyou + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/build.gradle.kts b/android/build.gradle.kts new file mode 100644 index 0000000..dbee657 --- /dev/null +++ b/android/build.gradle.kts @@ -0,0 +1,24 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +val newBuildDir: Directory = + rootProject.layout.buildDirectory + .dir("../../build") + .get() +rootProject.layout.buildDirectory.value(newBuildDir) + +subprojects { + val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) + project.layout.buildDirectory.value(newSubprojectBuildDir) +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean") { + delete(rootProject.layout.buildDirectory) +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..fbee1d8 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..e4ef43f --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts new file mode 100644 index 0000000..ca7fe06 --- /dev/null +++ b/android/settings.gradle.kts @@ -0,0 +1,26 @@ +pluginManagement { + val flutterSdkPath = + run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "8.11.1" apply false + id("org.jetbrains.kotlin.android") version "2.2.20" apply false +} + +include(":app") 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..391a902 --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8197107 --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,620 @@ +// !$*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 */; }; + 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; }; + 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 */; }; +/* 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 */ + 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 = ""; }; + 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 = ""; }; + 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + 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 */, + ); + 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 */, + 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + ); + 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 = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 */ + 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"; + }; + 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"; + }; +/* 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 */, + 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift 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)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.dailyou; + 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; + 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.dailyou.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; + 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.dailyou.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; + 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.dailyou.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)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.dailyou; + 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)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.dailyou; + 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..1d526a1 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + 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..c30b367 --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,16 @@ +import Flutter +import UIKit + +@main +@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } + + func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { + GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) + } +} 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..de7f630 --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,70 @@ + + + + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Dailyou + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + dailyou + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneConfigurationName + flutter + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + 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/Runner/SceneDelegate.swift b/ios/Runner/SceneDelegate.swift new file mode 100644 index 0000000..b9ce8ea --- /dev/null +++ b/ios/Runner/SceneDelegate.swift @@ -0,0 +1,6 @@ +import Flutter +import UIKit + +class SceneDelegate: FlutterSceneDelegate { + +} 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/app.dart b/lib/app.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/core/database/app_database.dart b/lib/core/database/app_database.dart new file mode 100644 index 0000000..8f27005 --- /dev/null +++ b/lib/core/database/app_database.dart @@ -0,0 +1,93 @@ +import 'package:drift/drift.dart'; +import 'package:drift_flutter/drift_flutter.dart'; +import 'package:path_provider/path_provider.dart'; + +import 'tables.dart'; +import 'daos/mood_dao.dart'; +import 'daos/activity_dao.dart'; +import 'daos/insight_dao.dart'; +import 'daos/settings_dao.dart'; + +part 'app_database.g.dart'; + +@DriftDatabase( + tables: [ + MoodEntries, + Activities, + EntryActivities, + Tags, + EntryTags, + LlmInsights, + UserSettings, + ], + daos: [ + MoodDao, + ActivityDao, + InsightDao, + SettingsDao, + ], +) +class AppDatabase extends _$AppDatabase { + AppDatabase() : super(_openConnection()); + + @override + int get schemaVersion => 1; + + @override + MigrationStrategy get migration => MigrationStrategy( + onCreate: (m) async { + await m.createAll(); + await _seedDefaultActivities(); + }, + onUpgrade: (m, from, to) async { + // Future migrations go here + }, + ); + + Future _seedDefaultActivities() async { + final defaults = [ + ( + name: 'Exercise', + icon: 0xe567, + colour: '#FF6B6B' + ), // Icons.fitness_center + (name: 'Good sleep', icon: 0xe7f5, colour: '#7B68EE'), // Icons.bedtime + (name: 'Social', icon: 0xe7ef, colour: '#FFB347'), // Icons.people + (name: 'Work', icon: 0xe8b6, colour: '#4FC3F7'), // Icons.work + (name: 'Food', icon: 0xe56c, colour: '#81C784'), // Icons.restaurant + (name: 'Reading', icon: 0xe865, colour: '#F06292'), // Icons.menu_book + (name: 'Outdoors', icon: 0xe1a1, colour: '#AED581'), // Icons.park + ( + name: 'Family', + icon: 0xe8a1, + colour: '#FFD54F' + ), // Icons.family_restroom + ( + name: 'Meditation', + icon: 0xe7fb, + colour: '#80CBC4' + ), // Icons.self_improvement + (name: 'Travel', icon: 0xe8b5, colour: '#FF8A65'), // Icons.flight + ]; + + for (final (index, a) in defaults.indexed) { + await into(activities).insert( + ActivitiesCompanion.insert( + name: a.name, + iconCodepoint: a.icon, + colourHex: a.colour, + sortOrder: Value(index), + ), + ); + } + } +} + +QueryExecutor _openConnection() { + return driftDatabase( + name: 'lumina_db', + native: DriftNativeOptions( + databaseDirectory: getApplicationSupportDirectory, + ), + ); +} diff --git a/lib/core/database/app_database.g.dart b/lib/core/database/app_database.g.dart new file mode 100644 index 0000000..b5607ed --- /dev/null +++ b/lib/core/database/app_database.g.dart @@ -0,0 +1,3658 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'app_database.dart'; + +// ignore_for_file: type=lint +class $MoodEntriesTable extends MoodEntries + with TableInfo<$MoodEntriesTable, MoodEntry> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $MoodEntriesTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')); + static const VerificationMeta _timestampMeta = + const VerificationMeta('timestamp'); + @override + late final GeneratedColumn timestamp = GeneratedColumn( + 'timestamp', aliasedName, false, + type: DriftSqlType.dateTime, requiredDuringInsert: true); + static const VerificationMeta _moodLevelMeta = + const VerificationMeta('moodLevel'); + @override + late final GeneratedColumn moodLevel = GeneratedColumn( + 'mood_level', aliasedName, false, + type: DriftSqlType.int, requiredDuringInsert: true); + static const VerificationMeta _noteMeta = const VerificationMeta('note'); + @override + late final GeneratedColumn note = GeneratedColumn( + 'note', aliasedName, true, + type: DriftSqlType.string, requiredDuringInsert: false); + static const VerificationMeta _createdAtMeta = + const VerificationMeta('createdAt'); + @override + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); + @override + List get $columns => + [id, timestamp, moodLevel, note, createdAt]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'mood_entries'; + @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)); + } + if (data.containsKey('timestamp')) { + context.handle(_timestampMeta, + timestamp.isAcceptableOrUnknown(data['timestamp']!, _timestampMeta)); + } else if (isInserting) { + context.missing(_timestampMeta); + } + if (data.containsKey('mood_level')) { + context.handle(_moodLevelMeta, + moodLevel.isAcceptableOrUnknown(data['mood_level']!, _moodLevelMeta)); + } else if (isInserting) { + context.missing(_moodLevelMeta); + } + if (data.containsKey('note')) { + context.handle( + _noteMeta, note.isAcceptableOrUnknown(data['note']!, _noteMeta)); + } + if (data.containsKey('created_at')) { + context.handle(_createdAtMeta, + createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + MoodEntry map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return MoodEntry( + id: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id'])!, + timestamp: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}timestamp'])!, + moodLevel: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}mood_level'])!, + note: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}note']), + createdAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, + ); + } + + @override + $MoodEntriesTable createAlias(String alias) { + return $MoodEntriesTable(attachedDatabase, alias); + } +} + +class MoodEntry extends DataClass implements Insertable { + final int id; + final DateTime timestamp; + final int moodLevel; + final String? note; + final DateTime createdAt; + const MoodEntry( + {required this.id, + required this.timestamp, + required this.moodLevel, + this.note, + required this.createdAt}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['timestamp'] = Variable(timestamp); + map['mood_level'] = Variable(moodLevel); + if (!nullToAbsent || note != null) { + map['note'] = Variable(note); + } + map['created_at'] = Variable(createdAt); + return map; + } + + MoodEntriesCompanion toCompanion(bool nullToAbsent) { + return MoodEntriesCompanion( + id: Value(id), + timestamp: Value(timestamp), + moodLevel: Value(moodLevel), + note: note == null && nullToAbsent ? const Value.absent() : Value(note), + createdAt: Value(createdAt), + ); + } + + factory MoodEntry.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return MoodEntry( + id: serializer.fromJson(json['id']), + timestamp: serializer.fromJson(json['timestamp']), + moodLevel: serializer.fromJson(json['moodLevel']), + note: serializer.fromJson(json['note']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'timestamp': serializer.toJson(timestamp), + 'moodLevel': serializer.toJson(moodLevel), + 'note': serializer.toJson(note), + 'createdAt': serializer.toJson(createdAt), + }; + } + + MoodEntry copyWith( + {int? id, + DateTime? timestamp, + int? moodLevel, + Value note = const Value.absent(), + DateTime? createdAt}) => + MoodEntry( + id: id ?? this.id, + timestamp: timestamp ?? this.timestamp, + moodLevel: moodLevel ?? this.moodLevel, + note: note.present ? note.value : this.note, + createdAt: createdAt ?? this.createdAt, + ); + MoodEntry copyWithCompanion(MoodEntriesCompanion data) { + return MoodEntry( + id: data.id.present ? data.id.value : this.id, + timestamp: data.timestamp.present ? data.timestamp.value : this.timestamp, + moodLevel: data.moodLevel.present ? data.moodLevel.value : this.moodLevel, + note: data.note.present ? data.note.value : this.note, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('MoodEntry(') + ..write('id: $id, ') + ..write('timestamp: $timestamp, ') + ..write('moodLevel: $moodLevel, ') + ..write('note: $note, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, timestamp, moodLevel, note, createdAt); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is MoodEntry && + other.id == this.id && + other.timestamp == this.timestamp && + other.moodLevel == this.moodLevel && + other.note == this.note && + other.createdAt == this.createdAt); +} + +class MoodEntriesCompanion extends UpdateCompanion { + final Value id; + final Value timestamp; + final Value moodLevel; + final Value note; + final Value createdAt; + const MoodEntriesCompanion({ + this.id = const Value.absent(), + this.timestamp = const Value.absent(), + this.moodLevel = const Value.absent(), + this.note = const Value.absent(), + this.createdAt = const Value.absent(), + }); + MoodEntriesCompanion.insert({ + this.id = const Value.absent(), + required DateTime timestamp, + required int moodLevel, + this.note = const Value.absent(), + this.createdAt = const Value.absent(), + }) : timestamp = Value(timestamp), + moodLevel = Value(moodLevel); + static Insertable custom({ + Expression? id, + Expression? timestamp, + Expression? moodLevel, + Expression? note, + Expression? createdAt, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (timestamp != null) 'timestamp': timestamp, + if (moodLevel != null) 'mood_level': moodLevel, + if (note != null) 'note': note, + if (createdAt != null) 'created_at': createdAt, + }); + } + + MoodEntriesCompanion copyWith( + {Value? id, + Value? timestamp, + Value? moodLevel, + Value? note, + Value? createdAt}) { + return MoodEntriesCompanion( + id: id ?? this.id, + timestamp: timestamp ?? this.timestamp, + moodLevel: moodLevel ?? this.moodLevel, + note: note ?? this.note, + createdAt: createdAt ?? this.createdAt, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (timestamp.present) { + map['timestamp'] = Variable(timestamp.value); + } + if (moodLevel.present) { + map['mood_level'] = Variable(moodLevel.value); + } + if (note.present) { + map['note'] = Variable(note.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('MoodEntriesCompanion(') + ..write('id: $id, ') + ..write('timestamp: $timestamp, ') + ..write('moodLevel: $moodLevel, ') + ..write('note: $note, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } +} + +class $ActivitiesTable extends Activities + with TableInfo<$ActivitiesTable, Activity> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $ActivitiesTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')); + static const VerificationMeta _nameMeta = const VerificationMeta('name'); + @override + late final GeneratedColumn name = GeneratedColumn( + 'name', aliasedName, false, + additionalChecks: + GeneratedColumn.checkTextLength(minTextLength: 1, maxTextLength: 50), + type: DriftSqlType.string, + requiredDuringInsert: true); + static const VerificationMeta _iconCodepointMeta = + const VerificationMeta('iconCodepoint'); + @override + late final GeneratedColumn iconCodepoint = GeneratedColumn( + 'icon_codepoint', aliasedName, false, + type: DriftSqlType.int, requiredDuringInsert: true); + static const VerificationMeta _colourHexMeta = + const VerificationMeta('colourHex'); + @override + late final GeneratedColumn colourHex = GeneratedColumn( + 'colour_hex', aliasedName, false, + additionalChecks: + GeneratedColumn.checkTextLength(minTextLength: 7, maxTextLength: 7), + type: DriftSqlType.string, + requiredDuringInsert: true); + static const VerificationMeta _isCustomMeta = + const VerificationMeta('isCustom'); + @override + late final GeneratedColumn isCustom = GeneratedColumn( + 'is_custom', aliasedName, false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('CHECK ("is_custom" IN (0, 1))'), + defaultValue: const Constant(false)); + static const VerificationMeta _sortOrderMeta = + const VerificationMeta('sortOrder'); + @override + late final GeneratedColumn sortOrder = GeneratedColumn( + 'sort_order', aliasedName, false, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultValue: const Constant(0)); + @override + List get $columns => + [id, name, iconCodepoint, colourHex, isCustom, sortOrder]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'activities'; + @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)); + } + if (data.containsKey('name')) { + context.handle( + _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); + } else if (isInserting) { + context.missing(_nameMeta); + } + if (data.containsKey('icon_codepoint')) { + context.handle( + _iconCodepointMeta, + iconCodepoint.isAcceptableOrUnknown( + data['icon_codepoint']!, _iconCodepointMeta)); + } else if (isInserting) { + context.missing(_iconCodepointMeta); + } + if (data.containsKey('colour_hex')) { + context.handle(_colourHexMeta, + colourHex.isAcceptableOrUnknown(data['colour_hex']!, _colourHexMeta)); + } else if (isInserting) { + context.missing(_colourHexMeta); + } + if (data.containsKey('is_custom')) { + context.handle(_isCustomMeta, + isCustom.isAcceptableOrUnknown(data['is_custom']!, _isCustomMeta)); + } + if (data.containsKey('sort_order')) { + context.handle(_sortOrderMeta, + sortOrder.isAcceptableOrUnknown(data['sort_order']!, _sortOrderMeta)); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + Activity map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return Activity( + id: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id'])!, + name: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}name'])!, + iconCodepoint: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}icon_codepoint'])!, + colourHex: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}colour_hex'])!, + isCustom: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}is_custom'])!, + sortOrder: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}sort_order'])!, + ); + } + + @override + $ActivitiesTable createAlias(String alias) { + return $ActivitiesTable(attachedDatabase, alias); + } +} + +class Activity extends DataClass implements Insertable { + final int id; + final String name; + final int iconCodepoint; + final String colourHex; + final bool isCustom; + final int sortOrder; + const Activity( + {required this.id, + required this.name, + required this.iconCodepoint, + required this.colourHex, + required this.isCustom, + required this.sortOrder}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + map['icon_codepoint'] = Variable(iconCodepoint); + map['colour_hex'] = Variable(colourHex); + map['is_custom'] = Variable(isCustom); + map['sort_order'] = Variable(sortOrder); + return map; + } + + ActivitiesCompanion toCompanion(bool nullToAbsent) { + return ActivitiesCompanion( + id: Value(id), + name: Value(name), + iconCodepoint: Value(iconCodepoint), + colourHex: Value(colourHex), + isCustom: Value(isCustom), + sortOrder: Value(sortOrder), + ); + } + + factory Activity.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return Activity( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + iconCodepoint: serializer.fromJson(json['iconCodepoint']), + colourHex: serializer.fromJson(json['colourHex']), + isCustom: serializer.fromJson(json['isCustom']), + sortOrder: serializer.fromJson(json['sortOrder']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'iconCodepoint': serializer.toJson(iconCodepoint), + 'colourHex': serializer.toJson(colourHex), + 'isCustom': serializer.toJson(isCustom), + 'sortOrder': serializer.toJson(sortOrder), + }; + } + + Activity copyWith( + {int? id, + String? name, + int? iconCodepoint, + String? colourHex, + bool? isCustom, + int? sortOrder}) => + Activity( + id: id ?? this.id, + name: name ?? this.name, + iconCodepoint: iconCodepoint ?? this.iconCodepoint, + colourHex: colourHex ?? this.colourHex, + isCustom: isCustom ?? this.isCustom, + sortOrder: sortOrder ?? this.sortOrder, + ); + Activity copyWithCompanion(ActivitiesCompanion data) { + return Activity( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + iconCodepoint: data.iconCodepoint.present + ? data.iconCodepoint.value + : this.iconCodepoint, + colourHex: data.colourHex.present ? data.colourHex.value : this.colourHex, + isCustom: data.isCustom.present ? data.isCustom.value : this.isCustom, + sortOrder: data.sortOrder.present ? data.sortOrder.value : this.sortOrder, + ); + } + + @override + String toString() { + return (StringBuffer('Activity(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('iconCodepoint: $iconCodepoint, ') + ..write('colourHex: $colourHex, ') + ..write('isCustom: $isCustom, ') + ..write('sortOrder: $sortOrder') + ..write(')')) + .toString(); + } + + @override + int get hashCode => + Object.hash(id, name, iconCodepoint, colourHex, isCustom, sortOrder); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is Activity && + other.id == this.id && + other.name == this.name && + other.iconCodepoint == this.iconCodepoint && + other.colourHex == this.colourHex && + other.isCustom == this.isCustom && + other.sortOrder == this.sortOrder); +} + +class ActivitiesCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value iconCodepoint; + final Value colourHex; + final Value isCustom; + final Value sortOrder; + const ActivitiesCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.iconCodepoint = const Value.absent(), + this.colourHex = const Value.absent(), + this.isCustom = const Value.absent(), + this.sortOrder = const Value.absent(), + }); + ActivitiesCompanion.insert({ + this.id = const Value.absent(), + required String name, + required int iconCodepoint, + required String colourHex, + this.isCustom = const Value.absent(), + this.sortOrder = const Value.absent(), + }) : name = Value(name), + iconCodepoint = Value(iconCodepoint), + colourHex = Value(colourHex); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? iconCodepoint, + Expression? colourHex, + Expression? isCustom, + Expression? sortOrder, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (iconCodepoint != null) 'icon_codepoint': iconCodepoint, + if (colourHex != null) 'colour_hex': colourHex, + if (isCustom != null) 'is_custom': isCustom, + if (sortOrder != null) 'sort_order': sortOrder, + }); + } + + ActivitiesCompanion copyWith( + {Value? id, + Value? name, + Value? iconCodepoint, + Value? colourHex, + Value? isCustom, + Value? sortOrder}) { + return ActivitiesCompanion( + id: id ?? this.id, + name: name ?? this.name, + iconCodepoint: iconCodepoint ?? this.iconCodepoint, + colourHex: colourHex ?? this.colourHex, + isCustom: isCustom ?? this.isCustom, + sortOrder: sortOrder ?? this.sortOrder, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (iconCodepoint.present) { + map['icon_codepoint'] = Variable(iconCodepoint.value); + } + if (colourHex.present) { + map['colour_hex'] = Variable(colourHex.value); + } + if (isCustom.present) { + map['is_custom'] = Variable(isCustom.value); + } + if (sortOrder.present) { + map['sort_order'] = Variable(sortOrder.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('ActivitiesCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('iconCodepoint: $iconCodepoint, ') + ..write('colourHex: $colourHex, ') + ..write('isCustom: $isCustom, ') + ..write('sortOrder: $sortOrder') + ..write(')')) + .toString(); + } +} + +class $EntryActivitiesTable extends EntryActivities + with TableInfo<$EntryActivitiesTable, EntryActivity> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $EntryActivitiesTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _entryIdMeta = + const VerificationMeta('entryId'); + @override + late final GeneratedColumn entryId = GeneratedColumn( + 'entry_id', aliasedName, false, + type: DriftSqlType.int, + requiredDuringInsert: true, + defaultConstraints: + GeneratedColumn.constraintIsAlways('REFERENCES mood_entries (id)')); + static const VerificationMeta _activityIdMeta = + const VerificationMeta('activityId'); + @override + late final GeneratedColumn activityId = GeneratedColumn( + 'activity_id', aliasedName, false, + type: DriftSqlType.int, + requiredDuringInsert: true, + defaultConstraints: + GeneratedColumn.constraintIsAlways('REFERENCES activities (id)')); + @override + List get $columns => [entryId, activityId]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'entry_activities'; + @override + VerificationContext validateIntegrity(Insertable instance, + {bool isInserting = false}) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('entry_id')) { + context.handle(_entryIdMeta, + entryId.isAcceptableOrUnknown(data['entry_id']!, _entryIdMeta)); + } else if (isInserting) { + context.missing(_entryIdMeta); + } + if (data.containsKey('activity_id')) { + context.handle( + _activityIdMeta, + activityId.isAcceptableOrUnknown( + data['activity_id']!, _activityIdMeta)); + } else if (isInserting) { + context.missing(_activityIdMeta); + } + return context; + } + + @override + Set get $primaryKey => {entryId, activityId}; + @override + EntryActivity map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return EntryActivity( + entryId: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}entry_id'])!, + activityId: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}activity_id'])!, + ); + } + + @override + $EntryActivitiesTable createAlias(String alias) { + return $EntryActivitiesTable(attachedDatabase, alias); + } +} + +class EntryActivity extends DataClass implements Insertable { + final int entryId; + final int activityId; + const EntryActivity({required this.entryId, required this.activityId}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['entry_id'] = Variable(entryId); + map['activity_id'] = Variable(activityId); + return map; + } + + EntryActivitiesCompanion toCompanion(bool nullToAbsent) { + return EntryActivitiesCompanion( + entryId: Value(entryId), + activityId: Value(activityId), + ); + } + + factory EntryActivity.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return EntryActivity( + entryId: serializer.fromJson(json['entryId']), + activityId: serializer.fromJson(json['activityId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'entryId': serializer.toJson(entryId), + 'activityId': serializer.toJson(activityId), + }; + } + + EntryActivity copyWith({int? entryId, int? activityId}) => EntryActivity( + entryId: entryId ?? this.entryId, + activityId: activityId ?? this.activityId, + ); + EntryActivity copyWithCompanion(EntryActivitiesCompanion data) { + return EntryActivity( + entryId: data.entryId.present ? data.entryId.value : this.entryId, + activityId: + data.activityId.present ? data.activityId.value : this.activityId, + ); + } + + @override + String toString() { + return (StringBuffer('EntryActivity(') + ..write('entryId: $entryId, ') + ..write('activityId: $activityId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(entryId, activityId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is EntryActivity && + other.entryId == this.entryId && + other.activityId == this.activityId); +} + +class EntryActivitiesCompanion extends UpdateCompanion { + final Value entryId; + final Value activityId; + final Value rowid; + const EntryActivitiesCompanion({ + this.entryId = const Value.absent(), + this.activityId = const Value.absent(), + this.rowid = const Value.absent(), + }); + EntryActivitiesCompanion.insert({ + required int entryId, + required int activityId, + this.rowid = const Value.absent(), + }) : entryId = Value(entryId), + activityId = Value(activityId); + static Insertable custom({ + Expression? entryId, + Expression? activityId, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (entryId != null) 'entry_id': entryId, + if (activityId != null) 'activity_id': activityId, + if (rowid != null) 'rowid': rowid, + }); + } + + EntryActivitiesCompanion copyWith( + {Value? entryId, Value? activityId, Value? rowid}) { + return EntryActivitiesCompanion( + entryId: entryId ?? this.entryId, + activityId: activityId ?? this.activityId, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (entryId.present) { + map['entry_id'] = Variable(entryId.value); + } + if (activityId.present) { + map['activity_id'] = Variable(activityId.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('EntryActivitiesCompanion(') + ..write('entryId: $entryId, ') + ..write('activityId: $activityId, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class $TagsTable extends Tags with TableInfo<$TagsTable, Tag> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $TagsTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')); + static const VerificationMeta _nameMeta = const VerificationMeta('name'); + @override + late final GeneratedColumn name = GeneratedColumn( + 'name', aliasedName, false, + additionalChecks: + GeneratedColumn.checkTextLength(minTextLength: 1, maxTextLength: 30), + type: DriftSqlType.string, + requiredDuringInsert: true); + static const VerificationMeta _colourHexMeta = + const VerificationMeta('colourHex'); + @override + late final GeneratedColumn colourHex = GeneratedColumn( + 'colour_hex', aliasedName, false, + additionalChecks: + GeneratedColumn.checkTextLength(minTextLength: 7, maxTextLength: 7), + type: DriftSqlType.string, + requiredDuringInsert: true); + @override + List get $columns => [id, name, colourHex]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'tags'; + @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)); + } + if (data.containsKey('name')) { + context.handle( + _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); + } else if (isInserting) { + context.missing(_nameMeta); + } + if (data.containsKey('colour_hex')) { + context.handle(_colourHexMeta, + colourHex.isAcceptableOrUnknown(data['colour_hex']!, _colourHexMeta)); + } else if (isInserting) { + context.missing(_colourHexMeta); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + Tag map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return Tag( + id: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id'])!, + name: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}name'])!, + colourHex: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}colour_hex'])!, + ); + } + + @override + $TagsTable createAlias(String alias) { + return $TagsTable(attachedDatabase, alias); + } +} + +class Tag extends DataClass implements Insertable { + final int id; + final String name; + final String colourHex; + const Tag({required this.id, required this.name, required this.colourHex}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + map['colour_hex'] = Variable(colourHex); + return map; + } + + TagsCompanion toCompanion(bool nullToAbsent) { + return TagsCompanion( + id: Value(id), + name: Value(name), + colourHex: Value(colourHex), + ); + } + + factory Tag.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return Tag( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + colourHex: serializer.fromJson(json['colourHex']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'colourHex': serializer.toJson(colourHex), + }; + } + + Tag copyWith({int? id, String? name, String? colourHex}) => Tag( + id: id ?? this.id, + name: name ?? this.name, + colourHex: colourHex ?? this.colourHex, + ); + Tag copyWithCompanion(TagsCompanion data) { + return Tag( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + colourHex: data.colourHex.present ? data.colourHex.value : this.colourHex, + ); + } + + @override + String toString() { + return (StringBuffer('Tag(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('colourHex: $colourHex') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, name, colourHex); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is Tag && + other.id == this.id && + other.name == this.name && + other.colourHex == this.colourHex); +} + +class TagsCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value colourHex; + const TagsCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.colourHex = const Value.absent(), + }); + TagsCompanion.insert({ + this.id = const Value.absent(), + required String name, + required String colourHex, + }) : name = Value(name), + colourHex = Value(colourHex); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? colourHex, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (colourHex != null) 'colour_hex': colourHex, + }); + } + + TagsCompanion copyWith( + {Value? id, Value? name, Value? colourHex}) { + return TagsCompanion( + id: id ?? this.id, + name: name ?? this.name, + colourHex: colourHex ?? this.colourHex, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (colourHex.present) { + map['colour_hex'] = Variable(colourHex.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('TagsCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('colourHex: $colourHex') + ..write(')')) + .toString(); + } +} + +class $EntryTagsTable extends EntryTags + with TableInfo<$EntryTagsTable, EntryTag> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $EntryTagsTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _entryIdMeta = + const VerificationMeta('entryId'); + @override + late final GeneratedColumn entryId = GeneratedColumn( + 'entry_id', aliasedName, false, + type: DriftSqlType.int, + requiredDuringInsert: true, + defaultConstraints: + GeneratedColumn.constraintIsAlways('REFERENCES mood_entries (id)')); + static const VerificationMeta _tagIdMeta = const VerificationMeta('tagId'); + @override + late final GeneratedColumn tagId = GeneratedColumn( + 'tag_id', aliasedName, false, + type: DriftSqlType.int, + requiredDuringInsert: true, + defaultConstraints: + GeneratedColumn.constraintIsAlways('REFERENCES tags (id)')); + @override + List get $columns => [entryId, tagId]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'entry_tags'; + @override + VerificationContext validateIntegrity(Insertable instance, + {bool isInserting = false}) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('entry_id')) { + context.handle(_entryIdMeta, + entryId.isAcceptableOrUnknown(data['entry_id']!, _entryIdMeta)); + } else if (isInserting) { + context.missing(_entryIdMeta); + } + if (data.containsKey('tag_id')) { + context.handle( + _tagIdMeta, tagId.isAcceptableOrUnknown(data['tag_id']!, _tagIdMeta)); + } else if (isInserting) { + context.missing(_tagIdMeta); + } + return context; + } + + @override + Set get $primaryKey => {entryId, tagId}; + @override + EntryTag map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return EntryTag( + entryId: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}entry_id'])!, + tagId: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}tag_id'])!, + ); + } + + @override + $EntryTagsTable createAlias(String alias) { + return $EntryTagsTable(attachedDatabase, alias); + } +} + +class EntryTag extends DataClass implements Insertable { + final int entryId; + final int tagId; + const EntryTag({required this.entryId, required this.tagId}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['entry_id'] = Variable(entryId); + map['tag_id'] = Variable(tagId); + return map; + } + + EntryTagsCompanion toCompanion(bool nullToAbsent) { + return EntryTagsCompanion( + entryId: Value(entryId), + tagId: Value(tagId), + ); + } + + factory EntryTag.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return EntryTag( + entryId: serializer.fromJson(json['entryId']), + tagId: serializer.fromJson(json['tagId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'entryId': serializer.toJson(entryId), + 'tagId': serializer.toJson(tagId), + }; + } + + EntryTag copyWith({int? entryId, int? tagId}) => EntryTag( + entryId: entryId ?? this.entryId, + tagId: tagId ?? this.tagId, + ); + EntryTag copyWithCompanion(EntryTagsCompanion data) { + return EntryTag( + entryId: data.entryId.present ? data.entryId.value : this.entryId, + tagId: data.tagId.present ? data.tagId.value : this.tagId, + ); + } + + @override + String toString() { + return (StringBuffer('EntryTag(') + ..write('entryId: $entryId, ') + ..write('tagId: $tagId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(entryId, tagId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is EntryTag && + other.entryId == this.entryId && + other.tagId == this.tagId); +} + +class EntryTagsCompanion extends UpdateCompanion { + final Value entryId; + final Value tagId; + final Value rowid; + const EntryTagsCompanion({ + this.entryId = const Value.absent(), + this.tagId = const Value.absent(), + this.rowid = const Value.absent(), + }); + EntryTagsCompanion.insert({ + required int entryId, + required int tagId, + this.rowid = const Value.absent(), + }) : entryId = Value(entryId), + tagId = Value(tagId); + static Insertable custom({ + Expression? entryId, + Expression? tagId, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (entryId != null) 'entry_id': entryId, + if (tagId != null) 'tag_id': tagId, + if (rowid != null) 'rowid': rowid, + }); + } + + EntryTagsCompanion copyWith( + {Value? entryId, Value? tagId, Value? rowid}) { + return EntryTagsCompanion( + entryId: entryId ?? this.entryId, + tagId: tagId ?? this.tagId, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (entryId.present) { + map['entry_id'] = Variable(entryId.value); + } + if (tagId.present) { + map['tag_id'] = Variable(tagId.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('EntryTagsCompanion(') + ..write('entryId: $entryId, ') + ..write('tagId: $tagId, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class $LlmInsightsTable extends LlmInsights + with TableInfo<$LlmInsightsTable, LlmInsight> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $LlmInsightsTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')); + static const VerificationMeta _typeMeta = const VerificationMeta('type'); + @override + late final GeneratedColumn type = GeneratedColumn( + 'type', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _promptHashMeta = + const VerificationMeta('promptHash'); + @override + late final GeneratedColumn promptHash = GeneratedColumn( + 'prompt_hash', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _responseTextMeta = + const VerificationMeta('responseText'); + @override + late final GeneratedColumn responseText = GeneratedColumn( + 'response_text', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + static const VerificationMeta _generatedAtMeta = + const VerificationMeta('generatedAt'); + @override + late final GeneratedColumn generatedAt = GeneratedColumn( + 'generated_at', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); + static const VerificationMeta _rangeStartMeta = + const VerificationMeta('rangeStart'); + @override + late final GeneratedColumn rangeStart = GeneratedColumn( + 'range_start', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _rangeEndMeta = + const VerificationMeta('rangeEnd'); + @override + late final GeneratedColumn rangeEnd = GeneratedColumn( + 'range_end', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + @override + List get $columns => + [id, type, promptHash, responseText, generatedAt, rangeStart, rangeEnd]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'llm_insights'; + @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)); + } + if (data.containsKey('type')) { + context.handle( + _typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta)); + } else if (isInserting) { + context.missing(_typeMeta); + } + if (data.containsKey('prompt_hash')) { + context.handle( + _promptHashMeta, + promptHash.isAcceptableOrUnknown( + data['prompt_hash']!, _promptHashMeta)); + } else if (isInserting) { + context.missing(_promptHashMeta); + } + if (data.containsKey('response_text')) { + context.handle( + _responseTextMeta, + responseText.isAcceptableOrUnknown( + data['response_text']!, _responseTextMeta)); + } else if (isInserting) { + context.missing(_responseTextMeta); + } + if (data.containsKey('generated_at')) { + context.handle( + _generatedAtMeta, + generatedAt.isAcceptableOrUnknown( + data['generated_at']!, _generatedAtMeta)); + } + if (data.containsKey('range_start')) { + context.handle( + _rangeStartMeta, + rangeStart.isAcceptableOrUnknown( + data['range_start']!, _rangeStartMeta)); + } + if (data.containsKey('range_end')) { + context.handle(_rangeEndMeta, + rangeEnd.isAcceptableOrUnknown(data['range_end']!, _rangeEndMeta)); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + LlmInsight map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return LlmInsight( + id: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id'])!, + type: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}type'])!, + promptHash: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}prompt_hash'])!, + responseText: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}response_text'])!, + generatedAt: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}generated_at'])!, + rangeStart: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}range_start']), + rangeEnd: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}range_end']), + ); + } + + @override + $LlmInsightsTable createAlias(String alias) { + return $LlmInsightsTable(attachedDatabase, alias); + } +} + +class LlmInsight extends DataClass implements Insertable { + final int id; + final String type; + final String promptHash; + final String responseText; + final DateTime generatedAt; + final DateTime? rangeStart; + final DateTime? rangeEnd; + const LlmInsight( + {required this.id, + required this.type, + required this.promptHash, + required this.responseText, + required this.generatedAt, + this.rangeStart, + this.rangeEnd}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['type'] = Variable(type); + map['prompt_hash'] = Variable(promptHash); + map['response_text'] = Variable(responseText); + map['generated_at'] = Variable(generatedAt); + if (!nullToAbsent || rangeStart != null) { + map['range_start'] = Variable(rangeStart); + } + if (!nullToAbsent || rangeEnd != null) { + map['range_end'] = Variable(rangeEnd); + } + return map; + } + + LlmInsightsCompanion toCompanion(bool nullToAbsent) { + return LlmInsightsCompanion( + id: Value(id), + type: Value(type), + promptHash: Value(promptHash), + responseText: Value(responseText), + generatedAt: Value(generatedAt), + rangeStart: rangeStart == null && nullToAbsent + ? const Value.absent() + : Value(rangeStart), + rangeEnd: rangeEnd == null && nullToAbsent + ? const Value.absent() + : Value(rangeEnd), + ); + } + + factory LlmInsight.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return LlmInsight( + id: serializer.fromJson(json['id']), + type: serializer.fromJson(json['type']), + promptHash: serializer.fromJson(json['promptHash']), + responseText: serializer.fromJson(json['responseText']), + generatedAt: serializer.fromJson(json['generatedAt']), + rangeStart: serializer.fromJson(json['rangeStart']), + rangeEnd: serializer.fromJson(json['rangeEnd']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'type': serializer.toJson(type), + 'promptHash': serializer.toJson(promptHash), + 'responseText': serializer.toJson(responseText), + 'generatedAt': serializer.toJson(generatedAt), + 'rangeStart': serializer.toJson(rangeStart), + 'rangeEnd': serializer.toJson(rangeEnd), + }; + } + + LlmInsight copyWith( + {int? id, + String? type, + String? promptHash, + String? responseText, + DateTime? generatedAt, + Value rangeStart = const Value.absent(), + Value rangeEnd = const Value.absent()}) => + LlmInsight( + id: id ?? this.id, + type: type ?? this.type, + promptHash: promptHash ?? this.promptHash, + responseText: responseText ?? this.responseText, + generatedAt: generatedAt ?? this.generatedAt, + rangeStart: rangeStart.present ? rangeStart.value : this.rangeStart, + rangeEnd: rangeEnd.present ? rangeEnd.value : this.rangeEnd, + ); + LlmInsight copyWithCompanion(LlmInsightsCompanion data) { + return LlmInsight( + id: data.id.present ? data.id.value : this.id, + type: data.type.present ? data.type.value : this.type, + promptHash: + data.promptHash.present ? data.promptHash.value : this.promptHash, + responseText: data.responseText.present + ? data.responseText.value + : this.responseText, + generatedAt: + data.generatedAt.present ? data.generatedAt.value : this.generatedAt, + rangeStart: + data.rangeStart.present ? data.rangeStart.value : this.rangeStart, + rangeEnd: data.rangeEnd.present ? data.rangeEnd.value : this.rangeEnd, + ); + } + + @override + String toString() { + return (StringBuffer('LlmInsight(') + ..write('id: $id, ') + ..write('type: $type, ') + ..write('promptHash: $promptHash, ') + ..write('responseText: $responseText, ') + ..write('generatedAt: $generatedAt, ') + ..write('rangeStart: $rangeStart, ') + ..write('rangeEnd: $rangeEnd') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, type, promptHash, responseText, generatedAt, rangeStart, rangeEnd); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is LlmInsight && + other.id == this.id && + other.type == this.type && + other.promptHash == this.promptHash && + other.responseText == this.responseText && + other.generatedAt == this.generatedAt && + other.rangeStart == this.rangeStart && + other.rangeEnd == this.rangeEnd); +} + +class LlmInsightsCompanion extends UpdateCompanion { + final Value id; + final Value type; + final Value promptHash; + final Value responseText; + final Value generatedAt; + final Value rangeStart; + final Value rangeEnd; + const LlmInsightsCompanion({ + this.id = const Value.absent(), + this.type = const Value.absent(), + this.promptHash = const Value.absent(), + this.responseText = const Value.absent(), + this.generatedAt = const Value.absent(), + this.rangeStart = const Value.absent(), + this.rangeEnd = const Value.absent(), + }); + LlmInsightsCompanion.insert({ + this.id = const Value.absent(), + required String type, + required String promptHash, + required String responseText, + this.generatedAt = const Value.absent(), + this.rangeStart = const Value.absent(), + this.rangeEnd = const Value.absent(), + }) : type = Value(type), + promptHash = Value(promptHash), + responseText = Value(responseText); + static Insertable custom({ + Expression? id, + Expression? type, + Expression? promptHash, + Expression? responseText, + Expression? generatedAt, + Expression? rangeStart, + Expression? rangeEnd, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (type != null) 'type': type, + if (promptHash != null) 'prompt_hash': promptHash, + if (responseText != null) 'response_text': responseText, + if (generatedAt != null) 'generated_at': generatedAt, + if (rangeStart != null) 'range_start': rangeStart, + if (rangeEnd != null) 'range_end': rangeEnd, + }); + } + + LlmInsightsCompanion copyWith( + {Value? id, + Value? type, + Value? promptHash, + Value? responseText, + Value? generatedAt, + Value? rangeStart, + Value? rangeEnd}) { + return LlmInsightsCompanion( + id: id ?? this.id, + type: type ?? this.type, + promptHash: promptHash ?? this.promptHash, + responseText: responseText ?? this.responseText, + generatedAt: generatedAt ?? this.generatedAt, + rangeStart: rangeStart ?? this.rangeStart, + rangeEnd: rangeEnd ?? this.rangeEnd, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (promptHash.present) { + map['prompt_hash'] = Variable(promptHash.value); + } + if (responseText.present) { + map['response_text'] = Variable(responseText.value); + } + if (generatedAt.present) { + map['generated_at'] = Variable(generatedAt.value); + } + if (rangeStart.present) { + map['range_start'] = Variable(rangeStart.value); + } + if (rangeEnd.present) { + map['range_end'] = Variable(rangeEnd.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('LlmInsightsCompanion(') + ..write('id: $id, ') + ..write('type: $type, ') + ..write('promptHash: $promptHash, ') + ..write('responseText: $responseText, ') + ..write('generatedAt: $generatedAt, ') + ..write('rangeStart: $rangeStart, ') + ..write('rangeEnd: $rangeEnd') + ..write(')')) + .toString(); + } +} + +class $UserSettingsTable extends UserSettings + with TableInfo<$UserSettingsTable, UserSetting> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $UserSettingsTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _idMeta = const VerificationMeta('id'); + @override + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')); + static const VerificationMeta _keyMeta = const VerificationMeta('key'); + @override + late final GeneratedColumn key = GeneratedColumn( + 'key', aliasedName, false, + additionalChecks: + GeneratedColumn.checkTextLength(minTextLength: 1, maxTextLength: 50), + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways('UNIQUE')); + static const VerificationMeta _valueMeta = const VerificationMeta('value'); + @override + late final GeneratedColumn value = GeneratedColumn( + 'value', aliasedName, false, + type: DriftSqlType.string, requiredDuringInsert: true); + @override + List get $columns => [id, key, value]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'user_settings'; + @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)); + } + if (data.containsKey('key')) { + context.handle( + _keyMeta, key.isAcceptableOrUnknown(data['key']!, _keyMeta)); + } else if (isInserting) { + context.missing(_keyMeta); + } + if (data.containsKey('value')) { + context.handle( + _valueMeta, value.isAcceptableOrUnknown(data['value']!, _valueMeta)); + } else if (isInserting) { + context.missing(_valueMeta); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + UserSetting map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return UserSetting( + id: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id'])!, + key: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}key'])!, + value: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}value'])!, + ); + } + + @override + $UserSettingsTable createAlias(String alias) { + return $UserSettingsTable(attachedDatabase, alias); + } +} + +class UserSetting extends DataClass implements Insertable { + final int id; + final String key; + final String value; + const UserSetting({required this.id, required this.key, required this.value}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['key'] = Variable(key); + map['value'] = Variable(value); + return map; + } + + UserSettingsCompanion toCompanion(bool nullToAbsent) { + return UserSettingsCompanion( + id: Value(id), + key: Value(key), + value: Value(value), + ); + } + + factory UserSetting.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return UserSetting( + id: serializer.fromJson(json['id']), + key: serializer.fromJson(json['key']), + value: serializer.fromJson(json['value']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'key': serializer.toJson(key), + 'value': serializer.toJson(value), + }; + } + + UserSetting copyWith({int? id, String? key, String? value}) => UserSetting( + id: id ?? this.id, + key: key ?? this.key, + value: value ?? this.value, + ); + UserSetting copyWithCompanion(UserSettingsCompanion data) { + return UserSetting( + id: data.id.present ? data.id.value : this.id, + key: data.key.present ? data.key.value : this.key, + value: data.value.present ? data.value.value : this.value, + ); + } + + @override + String toString() { + return (StringBuffer('UserSetting(') + ..write('id: $id, ') + ..write('key: $key, ') + ..write('value: $value') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, key, value); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is UserSetting && + other.id == this.id && + other.key == this.key && + other.value == this.value); +} + +class UserSettingsCompanion extends UpdateCompanion { + final Value id; + final Value key; + final Value value; + const UserSettingsCompanion({ + this.id = const Value.absent(), + this.key = const Value.absent(), + this.value = const Value.absent(), + }); + UserSettingsCompanion.insert({ + this.id = const Value.absent(), + required String key, + required String value, + }) : key = Value(key), + value = Value(value); + static Insertable custom({ + Expression? id, + Expression? key, + Expression? value, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (key != null) 'key': key, + if (value != null) 'value': value, + }); + } + + UserSettingsCompanion copyWith( + {Value? id, Value? key, Value? value}) { + return UserSettingsCompanion( + id: id ?? this.id, + key: key ?? this.key, + value: value ?? this.value, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (key.present) { + map['key'] = Variable(key.value); + } + if (value.present) { + map['value'] = Variable(value.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('UserSettingsCompanion(') + ..write('id: $id, ') + ..write('key: $key, ') + ..write('value: $value') + ..write(')')) + .toString(); + } +} + +abstract class _$AppDatabase extends GeneratedDatabase { + _$AppDatabase(QueryExecutor e) : super(e); + $AppDatabaseManager get managers => $AppDatabaseManager(this); + late final $MoodEntriesTable moodEntries = $MoodEntriesTable(this); + late final $ActivitiesTable activities = $ActivitiesTable(this); + late final $EntryActivitiesTable entryActivities = + $EntryActivitiesTable(this); + late final $TagsTable tags = $TagsTable(this); + late final $EntryTagsTable entryTags = $EntryTagsTable(this); + late final $LlmInsightsTable llmInsights = $LlmInsightsTable(this); + late final $UserSettingsTable userSettings = $UserSettingsTable(this); + late final MoodDao moodDao = MoodDao(this as AppDatabase); + late final ActivityDao activityDao = ActivityDao(this as AppDatabase); + late final InsightDao insightDao = InsightDao(this as AppDatabase); + late final SettingsDao settingsDao = SettingsDao(this as AppDatabase); + @override + Iterable> get allTables => + allSchemaEntities.whereType>(); + @override + List get allSchemaEntities => [ + moodEntries, + activities, + entryActivities, + tags, + entryTags, + llmInsights, + userSettings + ]; +} + +typedef $$MoodEntriesTableCreateCompanionBuilder = MoodEntriesCompanion + Function({ + Value id, + required DateTime timestamp, + required int moodLevel, + Value note, + Value createdAt, +}); +typedef $$MoodEntriesTableUpdateCompanionBuilder = MoodEntriesCompanion + Function({ + Value id, + Value timestamp, + Value moodLevel, + Value note, + Value createdAt, +}); + +final class $$MoodEntriesTableReferences + extends BaseReferences<_$AppDatabase, $MoodEntriesTable, MoodEntry> { + $$MoodEntriesTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static MultiTypedResultKey<$EntryActivitiesTable, List> + _entryActivitiesRefsTable(_$AppDatabase db) => + MultiTypedResultKey.fromTable(db.entryActivities, + aliasName: $_aliasNameGenerator( + db.moodEntries.id, db.entryActivities.entryId)); + + $$EntryActivitiesTableProcessedTableManager get entryActivitiesRefs { + final manager = + $$EntryActivitiesTableTableManager($_db, $_db.entryActivities) + .filter((f) => f.entryId.id.sqlEquals($_itemColumn('id')!)); + + final cache = + $_typedResult.readTableOrNull(_entryActivitiesRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } + + static MultiTypedResultKey<$EntryTagsTable, List> + _entryTagsRefsTable(_$AppDatabase db) => MultiTypedResultKey.fromTable( + db.entryTags, + aliasName: + $_aliasNameGenerator(db.moodEntries.id, db.entryTags.entryId)); + + $$EntryTagsTableProcessedTableManager get entryTagsRefs { + final manager = $$EntryTagsTableTableManager($_db, $_db.entryTags) + .filter((f) => f.entryId.id.sqlEquals($_itemColumn('id')!)); + + final cache = $_typedResult.readTableOrNull(_entryTagsRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } +} + +class $$MoodEntriesTableFilterComposer + extends Composer<_$AppDatabase, $MoodEntriesTable> { + $$MoodEntriesTableFilterComposer({ + 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 timestamp => $composableBuilder( + column: $table.timestamp, builder: (column) => ColumnFilters(column)); + + ColumnFilters get moodLevel => $composableBuilder( + column: $table.moodLevel, builder: (column) => ColumnFilters(column)); + + ColumnFilters get note => $composableBuilder( + column: $table.note, builder: (column) => ColumnFilters(column)); + + ColumnFilters get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => ColumnFilters(column)); + + Expression entryActivitiesRefs( + Expression Function($$EntryActivitiesTableFilterComposer f) f) { + final $$EntryActivitiesTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.entryActivities, + getReferencedColumn: (t) => t.entryId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$EntryActivitiesTableFilterComposer( + $db: $db, + $table: $db.entryActivities, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } + + Expression entryTagsRefs( + Expression Function($$EntryTagsTableFilterComposer f) f) { + final $$EntryTagsTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.entryTags, + getReferencedColumn: (t) => t.entryId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$EntryTagsTableFilterComposer( + $db: $db, + $table: $db.entryTags, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } +} + +class $$MoodEntriesTableOrderingComposer + extends Composer<_$AppDatabase, $MoodEntriesTable> { + $$MoodEntriesTableOrderingComposer({ + 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 timestamp => $composableBuilder( + column: $table.timestamp, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get moodLevel => $composableBuilder( + column: $table.moodLevel, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get note => $composableBuilder( + column: $table.note, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => ColumnOrderings(column)); +} + +class $$MoodEntriesTableAnnotationComposer + extends Composer<_$AppDatabase, $MoodEntriesTable> { + $$MoodEntriesTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get timestamp => + $composableBuilder(column: $table.timestamp, builder: (column) => column); + + GeneratedColumn get moodLevel => + $composableBuilder(column: $table.moodLevel, builder: (column) => column); + + GeneratedColumn get note => + $composableBuilder(column: $table.note, builder: (column) => column); + + GeneratedColumn get createdAt => + $composableBuilder(column: $table.createdAt, builder: (column) => column); + + Expression entryActivitiesRefs( + Expression Function($$EntryActivitiesTableAnnotationComposer a) f) { + final $$EntryActivitiesTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.entryActivities, + getReferencedColumn: (t) => t.entryId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$EntryActivitiesTableAnnotationComposer( + $db: $db, + $table: $db.entryActivities, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } + + Expression entryTagsRefs( + Expression Function($$EntryTagsTableAnnotationComposer a) f) { + final $$EntryTagsTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.entryTags, + getReferencedColumn: (t) => t.entryId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$EntryTagsTableAnnotationComposer( + $db: $db, + $table: $db.entryTags, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } +} + +class $$MoodEntriesTableTableManager extends RootTableManager< + _$AppDatabase, + $MoodEntriesTable, + MoodEntry, + $$MoodEntriesTableFilterComposer, + $$MoodEntriesTableOrderingComposer, + $$MoodEntriesTableAnnotationComposer, + $$MoodEntriesTableCreateCompanionBuilder, + $$MoodEntriesTableUpdateCompanionBuilder, + (MoodEntry, $$MoodEntriesTableReferences), + MoodEntry, + PrefetchHooks Function({bool entryActivitiesRefs, bool entryTagsRefs})> { + $$MoodEntriesTableTableManager(_$AppDatabase db, $MoodEntriesTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$MoodEntriesTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$MoodEntriesTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$MoodEntriesTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value id = const Value.absent(), + Value timestamp = const Value.absent(), + Value moodLevel = const Value.absent(), + Value note = const Value.absent(), + Value createdAt = const Value.absent(), + }) => + MoodEntriesCompanion( + id: id, + timestamp: timestamp, + moodLevel: moodLevel, + note: note, + createdAt: createdAt, + ), + createCompanionCallback: ({ + Value id = const Value.absent(), + required DateTime timestamp, + required int moodLevel, + Value note = const Value.absent(), + Value createdAt = const Value.absent(), + }) => + MoodEntriesCompanion.insert( + id: id, + timestamp: timestamp, + moodLevel: moodLevel, + note: note, + createdAt: createdAt, + ), + withReferenceMapper: (p0) => p0 + .map((e) => ( + e.readTable(table), + $$MoodEntriesTableReferences(db, table, e) + )) + .toList(), + prefetchHooksCallback: ( + {entryActivitiesRefs = false, entryTagsRefs = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [ + if (entryActivitiesRefs) db.entryActivities, + if (entryTagsRefs) db.entryTags + ], + addJoins: null, + getPrefetchedDataCallback: (items) async { + return [ + if (entryActivitiesRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: $$MoodEntriesTableReferences + ._entryActivitiesRefsTable(db), + managerFromTypedResult: (p0) => + $$MoodEntriesTableReferences(db, table, p0) + .entryActivitiesRefs, + referencedItemsForCurrentItem: (item, + referencedItems) => + referencedItems.where((e) => e.entryId == item.id), + typedResults: items), + if (entryTagsRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: $$MoodEntriesTableReferences + ._entryTagsRefsTable(db), + managerFromTypedResult: (p0) => + $$MoodEntriesTableReferences(db, table, p0) + .entryTagsRefs, + referencedItemsForCurrentItem: (item, + referencedItems) => + referencedItems.where((e) => e.entryId == item.id), + typedResults: items) + ]; + }, + ); + }, + )); +} + +typedef $$MoodEntriesTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $MoodEntriesTable, + MoodEntry, + $$MoodEntriesTableFilterComposer, + $$MoodEntriesTableOrderingComposer, + $$MoodEntriesTableAnnotationComposer, + $$MoodEntriesTableCreateCompanionBuilder, + $$MoodEntriesTableUpdateCompanionBuilder, + (MoodEntry, $$MoodEntriesTableReferences), + MoodEntry, + PrefetchHooks Function({bool entryActivitiesRefs, bool entryTagsRefs})>; +typedef $$ActivitiesTableCreateCompanionBuilder = ActivitiesCompanion Function({ + Value id, + required String name, + required int iconCodepoint, + required String colourHex, + Value isCustom, + Value sortOrder, +}); +typedef $$ActivitiesTableUpdateCompanionBuilder = ActivitiesCompanion Function({ + Value id, + Value name, + Value iconCodepoint, + Value colourHex, + Value isCustom, + Value sortOrder, +}); + +final class $$ActivitiesTableReferences + extends BaseReferences<_$AppDatabase, $ActivitiesTable, Activity> { + $$ActivitiesTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static MultiTypedResultKey<$EntryActivitiesTable, List> + _entryActivitiesRefsTable(_$AppDatabase db) => + MultiTypedResultKey.fromTable(db.entryActivities, + aliasName: $_aliasNameGenerator( + db.activities.id, db.entryActivities.activityId)); + + $$EntryActivitiesTableProcessedTableManager get entryActivitiesRefs { + final manager = + $$EntryActivitiesTableTableManager($_db, $_db.entryActivities) + .filter((f) => f.activityId.id.sqlEquals($_itemColumn('id')!)); + + final cache = + $_typedResult.readTableOrNull(_entryActivitiesRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } +} + +class $$ActivitiesTableFilterComposer + extends Composer<_$AppDatabase, $ActivitiesTable> { + $$ActivitiesTableFilterComposer({ + 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)); + + ColumnFilters get iconCodepoint => $composableBuilder( + column: $table.iconCodepoint, builder: (column) => ColumnFilters(column)); + + ColumnFilters get colourHex => $composableBuilder( + column: $table.colourHex, builder: (column) => ColumnFilters(column)); + + ColumnFilters get isCustom => $composableBuilder( + column: $table.isCustom, builder: (column) => ColumnFilters(column)); + + ColumnFilters get sortOrder => $composableBuilder( + column: $table.sortOrder, builder: (column) => ColumnFilters(column)); + + Expression entryActivitiesRefs( + Expression Function($$EntryActivitiesTableFilterComposer f) f) { + final $$EntryActivitiesTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.entryActivities, + getReferencedColumn: (t) => t.activityId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$EntryActivitiesTableFilterComposer( + $db: $db, + $table: $db.entryActivities, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } +} + +class $$ActivitiesTableOrderingComposer + extends Composer<_$AppDatabase, $ActivitiesTable> { + $$ActivitiesTableOrderingComposer({ + 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)); + + ColumnOrderings get iconCodepoint => $composableBuilder( + column: $table.iconCodepoint, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get colourHex => $composableBuilder( + column: $table.colourHex, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get isCustom => $composableBuilder( + column: $table.isCustom, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get sortOrder => $composableBuilder( + column: $table.sortOrder, builder: (column) => ColumnOrderings(column)); +} + +class $$ActivitiesTableAnnotationComposer + extends Composer<_$AppDatabase, $ActivitiesTable> { + $$ActivitiesTableAnnotationComposer({ + 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); + + GeneratedColumn get iconCodepoint => $composableBuilder( + column: $table.iconCodepoint, builder: (column) => column); + + GeneratedColumn get colourHex => + $composableBuilder(column: $table.colourHex, builder: (column) => column); + + GeneratedColumn get isCustom => + $composableBuilder(column: $table.isCustom, builder: (column) => column); + + GeneratedColumn get sortOrder => + $composableBuilder(column: $table.sortOrder, builder: (column) => column); + + Expression entryActivitiesRefs( + Expression Function($$EntryActivitiesTableAnnotationComposer a) f) { + final $$EntryActivitiesTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.entryActivities, + getReferencedColumn: (t) => t.activityId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$EntryActivitiesTableAnnotationComposer( + $db: $db, + $table: $db.entryActivities, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } +} + +class $$ActivitiesTableTableManager extends RootTableManager< + _$AppDatabase, + $ActivitiesTable, + Activity, + $$ActivitiesTableFilterComposer, + $$ActivitiesTableOrderingComposer, + $$ActivitiesTableAnnotationComposer, + $$ActivitiesTableCreateCompanionBuilder, + $$ActivitiesTableUpdateCompanionBuilder, + (Activity, $$ActivitiesTableReferences), + Activity, + PrefetchHooks Function({bool entryActivitiesRefs})> { + $$ActivitiesTableTableManager(_$AppDatabase db, $ActivitiesTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$ActivitiesTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$ActivitiesTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$ActivitiesTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value id = const Value.absent(), + Value name = const Value.absent(), + Value iconCodepoint = const Value.absent(), + Value colourHex = const Value.absent(), + Value isCustom = const Value.absent(), + Value sortOrder = const Value.absent(), + }) => + ActivitiesCompanion( + id: id, + name: name, + iconCodepoint: iconCodepoint, + colourHex: colourHex, + isCustom: isCustom, + sortOrder: sortOrder, + ), + createCompanionCallback: ({ + Value id = const Value.absent(), + required String name, + required int iconCodepoint, + required String colourHex, + Value isCustom = const Value.absent(), + Value sortOrder = const Value.absent(), + }) => + ActivitiesCompanion.insert( + id: id, + name: name, + iconCodepoint: iconCodepoint, + colourHex: colourHex, + isCustom: isCustom, + sortOrder: sortOrder, + ), + withReferenceMapper: (p0) => p0 + .map((e) => ( + e.readTable(table), + $$ActivitiesTableReferences(db, table, e) + )) + .toList(), + prefetchHooksCallback: ({entryActivitiesRefs = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [ + if (entryActivitiesRefs) db.entryActivities + ], + addJoins: null, + getPrefetchedDataCallback: (items) async { + return [ + if (entryActivitiesRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: $$ActivitiesTableReferences + ._entryActivitiesRefsTable(db), + managerFromTypedResult: (p0) => + $$ActivitiesTableReferences(db, table, p0) + .entryActivitiesRefs, + referencedItemsForCurrentItem: + (item, referencedItems) => referencedItems + .where((e) => e.activityId == item.id), + typedResults: items) + ]; + }, + ); + }, + )); +} + +typedef $$ActivitiesTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $ActivitiesTable, + Activity, + $$ActivitiesTableFilterComposer, + $$ActivitiesTableOrderingComposer, + $$ActivitiesTableAnnotationComposer, + $$ActivitiesTableCreateCompanionBuilder, + $$ActivitiesTableUpdateCompanionBuilder, + (Activity, $$ActivitiesTableReferences), + Activity, + PrefetchHooks Function({bool entryActivitiesRefs})>; +typedef $$EntryActivitiesTableCreateCompanionBuilder = EntryActivitiesCompanion + Function({ + required int entryId, + required int activityId, + Value rowid, +}); +typedef $$EntryActivitiesTableUpdateCompanionBuilder = EntryActivitiesCompanion + Function({ + Value entryId, + Value activityId, + Value rowid, +}); + +final class $$EntryActivitiesTableReferences extends BaseReferences< + _$AppDatabase, $EntryActivitiesTable, EntryActivity> { + $$EntryActivitiesTableReferences( + super.$_db, super.$_table, super.$_typedResult); + + static $MoodEntriesTable _entryIdTable(_$AppDatabase db) => + db.moodEntries.createAlias( + $_aliasNameGenerator(db.entryActivities.entryId, db.moodEntries.id)); + + $$MoodEntriesTableProcessedTableManager get entryId { + final $_column = $_itemColumn('entry_id')!; + + final manager = $$MoodEntriesTableTableManager($_db, $_db.moodEntries) + .filter((f) => f.id.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_entryIdTable($_db)); + if (item == null) return manager; + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } + + static $ActivitiesTable _activityIdTable(_$AppDatabase db) => + db.activities.createAlias($_aliasNameGenerator( + db.entryActivities.activityId, db.activities.id)); + + $$ActivitiesTableProcessedTableManager get activityId { + final $_column = $_itemColumn('activity_id')!; + + final manager = $$ActivitiesTableTableManager($_db, $_db.activities) + .filter((f) => f.id.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_activityIdTable($_db)); + if (item == null) return manager; + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} + +class $$EntryActivitiesTableFilterComposer + extends Composer<_$AppDatabase, $EntryActivitiesTable> { + $$EntryActivitiesTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + $$MoodEntriesTableFilterComposer get entryId { + final $$MoodEntriesTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.entryId, + referencedTable: $db.moodEntries, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$MoodEntriesTableFilterComposer( + $db: $db, + $table: $db.moodEntries, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } + + $$ActivitiesTableFilterComposer get activityId { + final $$ActivitiesTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.activityId, + referencedTable: $db.activities, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$ActivitiesTableFilterComposer( + $db: $db, + $table: $db.activities, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } +} + +class $$EntryActivitiesTableOrderingComposer + extends Composer<_$AppDatabase, $EntryActivitiesTable> { + $$EntryActivitiesTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + $$MoodEntriesTableOrderingComposer get entryId { + final $$MoodEntriesTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.entryId, + referencedTable: $db.moodEntries, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$MoodEntriesTableOrderingComposer( + $db: $db, + $table: $db.moodEntries, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } + + $$ActivitiesTableOrderingComposer get activityId { + final $$ActivitiesTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.activityId, + referencedTable: $db.activities, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$ActivitiesTableOrderingComposer( + $db: $db, + $table: $db.activities, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } +} + +class $$EntryActivitiesTableAnnotationComposer + extends Composer<_$AppDatabase, $EntryActivitiesTable> { + $$EntryActivitiesTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + $$MoodEntriesTableAnnotationComposer get entryId { + final $$MoodEntriesTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.entryId, + referencedTable: $db.moodEntries, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$MoodEntriesTableAnnotationComposer( + $db: $db, + $table: $db.moodEntries, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } + + $$ActivitiesTableAnnotationComposer get activityId { + final $$ActivitiesTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.activityId, + referencedTable: $db.activities, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$ActivitiesTableAnnotationComposer( + $db: $db, + $table: $db.activities, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } +} + +class $$EntryActivitiesTableTableManager extends RootTableManager< + _$AppDatabase, + $EntryActivitiesTable, + EntryActivity, + $$EntryActivitiesTableFilterComposer, + $$EntryActivitiesTableOrderingComposer, + $$EntryActivitiesTableAnnotationComposer, + $$EntryActivitiesTableCreateCompanionBuilder, + $$EntryActivitiesTableUpdateCompanionBuilder, + (EntryActivity, $$EntryActivitiesTableReferences), + EntryActivity, + PrefetchHooks Function({bool entryId, bool activityId})> { + $$EntryActivitiesTableTableManager( + _$AppDatabase db, $EntryActivitiesTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$EntryActivitiesTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$EntryActivitiesTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$EntryActivitiesTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value entryId = const Value.absent(), + Value activityId = const Value.absent(), + Value rowid = const Value.absent(), + }) => + EntryActivitiesCompanion( + entryId: entryId, + activityId: activityId, + rowid: rowid, + ), + createCompanionCallback: ({ + required int entryId, + required int activityId, + Value rowid = const Value.absent(), + }) => + EntryActivitiesCompanion.insert( + entryId: entryId, + activityId: activityId, + rowid: rowid, + ), + withReferenceMapper: (p0) => p0 + .map((e) => ( + e.readTable(table), + $$EntryActivitiesTableReferences(db, table, e) + )) + .toList(), + prefetchHooksCallback: ({entryId = false, activityId = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [], + addJoins: < + T extends TableManagerState< + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic>>(state) { + if (entryId) { + state = state.withJoin( + currentTable: table, + currentColumn: table.entryId, + referencedTable: + $$EntryActivitiesTableReferences._entryIdTable(db), + referencedColumn: + $$EntryActivitiesTableReferences._entryIdTable(db).id, + ) as T; + } + if (activityId) { + state = state.withJoin( + currentTable: table, + currentColumn: table.activityId, + referencedTable: + $$EntryActivitiesTableReferences._activityIdTable(db), + referencedColumn: $$EntryActivitiesTableReferences + ._activityIdTable(db) + .id, + ) as T; + } + + return state; + }, + getPrefetchedDataCallback: (items) async { + return []; + }, + ); + }, + )); +} + +typedef $$EntryActivitiesTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $EntryActivitiesTable, + EntryActivity, + $$EntryActivitiesTableFilterComposer, + $$EntryActivitiesTableOrderingComposer, + $$EntryActivitiesTableAnnotationComposer, + $$EntryActivitiesTableCreateCompanionBuilder, + $$EntryActivitiesTableUpdateCompanionBuilder, + (EntryActivity, $$EntryActivitiesTableReferences), + EntryActivity, + PrefetchHooks Function({bool entryId, bool activityId})>; +typedef $$TagsTableCreateCompanionBuilder = TagsCompanion Function({ + Value id, + required String name, + required String colourHex, +}); +typedef $$TagsTableUpdateCompanionBuilder = TagsCompanion Function({ + Value id, + Value name, + Value colourHex, +}); + +final class $$TagsTableReferences + extends BaseReferences<_$AppDatabase, $TagsTable, Tag> { + $$TagsTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static MultiTypedResultKey<$EntryTagsTable, List> + _entryTagsRefsTable(_$AppDatabase db) => + MultiTypedResultKey.fromTable(db.entryTags, + aliasName: $_aliasNameGenerator(db.tags.id, db.entryTags.tagId)); + + $$EntryTagsTableProcessedTableManager get entryTagsRefs { + final manager = $$EntryTagsTableTableManager($_db, $_db.entryTags) + .filter((f) => f.tagId.id.sqlEquals($_itemColumn('id')!)); + + final cache = $_typedResult.readTableOrNull(_entryTagsRefsTable($_db)); + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } +} + +class $$TagsTableFilterComposer extends Composer<_$AppDatabase, $TagsTable> { + $$TagsTableFilterComposer({ + 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)); + + ColumnFilters get colourHex => $composableBuilder( + column: $table.colourHex, builder: (column) => ColumnFilters(column)); + + Expression entryTagsRefs( + Expression Function($$EntryTagsTableFilterComposer f) f) { + final $$EntryTagsTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.entryTags, + getReferencedColumn: (t) => t.tagId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$EntryTagsTableFilterComposer( + $db: $db, + $table: $db.entryTags, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } +} + +class $$TagsTableOrderingComposer extends Composer<_$AppDatabase, $TagsTable> { + $$TagsTableOrderingComposer({ + 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)); + + ColumnOrderings get colourHex => $composableBuilder( + column: $table.colourHex, builder: (column) => ColumnOrderings(column)); +} + +class $$TagsTableAnnotationComposer + extends Composer<_$AppDatabase, $TagsTable> { + $$TagsTableAnnotationComposer({ + 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); + + GeneratedColumn get colourHex => + $composableBuilder(column: $table.colourHex, builder: (column) => column); + + Expression entryTagsRefs( + Expression Function($$EntryTagsTableAnnotationComposer a) f) { + final $$EntryTagsTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.id, + referencedTable: $db.entryTags, + getReferencedColumn: (t) => t.tagId, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$EntryTagsTableAnnotationComposer( + $db: $db, + $table: $db.entryTags, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return f(composer); + } +} + +class $$TagsTableTableManager extends RootTableManager< + _$AppDatabase, + $TagsTable, + Tag, + $$TagsTableFilterComposer, + $$TagsTableOrderingComposer, + $$TagsTableAnnotationComposer, + $$TagsTableCreateCompanionBuilder, + $$TagsTableUpdateCompanionBuilder, + (Tag, $$TagsTableReferences), + Tag, + PrefetchHooks Function({bool entryTagsRefs})> { + $$TagsTableTableManager(_$AppDatabase db, $TagsTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$TagsTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$TagsTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$TagsTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value id = const Value.absent(), + Value name = const Value.absent(), + Value colourHex = const Value.absent(), + }) => + TagsCompanion( + id: id, + name: name, + colourHex: colourHex, + ), + createCompanionCallback: ({ + Value id = const Value.absent(), + required String name, + required String colourHex, + }) => + TagsCompanion.insert( + id: id, + name: name, + colourHex: colourHex, + ), + withReferenceMapper: (p0) => p0 + .map((e) => + (e.readTable(table), $$TagsTableReferences(db, table, e))) + .toList(), + prefetchHooksCallback: ({entryTagsRefs = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [if (entryTagsRefs) db.entryTags], + addJoins: null, + getPrefetchedDataCallback: (items) async { + return [ + if (entryTagsRefs) + await $_getPrefetchedData( + currentTable: table, + referencedTable: + $$TagsTableReferences._entryTagsRefsTable(db), + managerFromTypedResult: (p0) => + $$TagsTableReferences(db, table, p0).entryTagsRefs, + referencedItemsForCurrentItem: (item, + referencedItems) => + referencedItems.where((e) => e.tagId == item.id), + typedResults: items) + ]; + }, + ); + }, + )); +} + +typedef $$TagsTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $TagsTable, + Tag, + $$TagsTableFilterComposer, + $$TagsTableOrderingComposer, + $$TagsTableAnnotationComposer, + $$TagsTableCreateCompanionBuilder, + $$TagsTableUpdateCompanionBuilder, + (Tag, $$TagsTableReferences), + Tag, + PrefetchHooks Function({bool entryTagsRefs})>; +typedef $$EntryTagsTableCreateCompanionBuilder = EntryTagsCompanion Function({ + required int entryId, + required int tagId, + Value rowid, +}); +typedef $$EntryTagsTableUpdateCompanionBuilder = EntryTagsCompanion Function({ + Value entryId, + Value tagId, + Value rowid, +}); + +final class $$EntryTagsTableReferences + extends BaseReferences<_$AppDatabase, $EntryTagsTable, EntryTag> { + $$EntryTagsTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static $MoodEntriesTable _entryIdTable(_$AppDatabase db) => + db.moodEntries.createAlias( + $_aliasNameGenerator(db.entryTags.entryId, db.moodEntries.id)); + + $$MoodEntriesTableProcessedTableManager get entryId { + final $_column = $_itemColumn('entry_id')!; + + final manager = $$MoodEntriesTableTableManager($_db, $_db.moodEntries) + .filter((f) => f.id.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_entryIdTable($_db)); + if (item == null) return manager; + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } + + static $TagsTable _tagIdTable(_$AppDatabase db) => + db.tags.createAlias($_aliasNameGenerator(db.entryTags.tagId, db.tags.id)); + + $$TagsTableProcessedTableManager get tagId { + final $_column = $_itemColumn('tag_id')!; + + final manager = $$TagsTableTableManager($_db, $_db.tags) + .filter((f) => f.id.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_tagIdTable($_db)); + if (item == null) return manager; + return ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} + +class $$EntryTagsTableFilterComposer + extends Composer<_$AppDatabase, $EntryTagsTable> { + $$EntryTagsTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + $$MoodEntriesTableFilterComposer get entryId { + final $$MoodEntriesTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.entryId, + referencedTable: $db.moodEntries, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$MoodEntriesTableFilterComposer( + $db: $db, + $table: $db.moodEntries, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } + + $$TagsTableFilterComposer get tagId { + final $$TagsTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.tagId, + referencedTable: $db.tags, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$TagsTableFilterComposer( + $db: $db, + $table: $db.tags, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } +} + +class $$EntryTagsTableOrderingComposer + extends Composer<_$AppDatabase, $EntryTagsTable> { + $$EntryTagsTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + $$MoodEntriesTableOrderingComposer get entryId { + final $$MoodEntriesTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.entryId, + referencedTable: $db.moodEntries, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$MoodEntriesTableOrderingComposer( + $db: $db, + $table: $db.moodEntries, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } + + $$TagsTableOrderingComposer get tagId { + final $$TagsTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.tagId, + referencedTable: $db.tags, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$TagsTableOrderingComposer( + $db: $db, + $table: $db.tags, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } +} + +class $$EntryTagsTableAnnotationComposer + extends Composer<_$AppDatabase, $EntryTagsTable> { + $$EntryTagsTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + $$MoodEntriesTableAnnotationComposer get entryId { + final $$MoodEntriesTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.entryId, + referencedTable: $db.moodEntries, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$MoodEntriesTableAnnotationComposer( + $db: $db, + $table: $db.moodEntries, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } + + $$TagsTableAnnotationComposer get tagId { + final $$TagsTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.tagId, + referencedTable: $db.tags, + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + $$TagsTableAnnotationComposer( + $db: $db, + $table: $db.tags, + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } +} + +class $$EntryTagsTableTableManager extends RootTableManager< + _$AppDatabase, + $EntryTagsTable, + EntryTag, + $$EntryTagsTableFilterComposer, + $$EntryTagsTableOrderingComposer, + $$EntryTagsTableAnnotationComposer, + $$EntryTagsTableCreateCompanionBuilder, + $$EntryTagsTableUpdateCompanionBuilder, + (EntryTag, $$EntryTagsTableReferences), + EntryTag, + PrefetchHooks Function({bool entryId, bool tagId})> { + $$EntryTagsTableTableManager(_$AppDatabase db, $EntryTagsTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$EntryTagsTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$EntryTagsTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$EntryTagsTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value entryId = const Value.absent(), + Value tagId = const Value.absent(), + Value rowid = const Value.absent(), + }) => + EntryTagsCompanion( + entryId: entryId, + tagId: tagId, + rowid: rowid, + ), + createCompanionCallback: ({ + required int entryId, + required int tagId, + Value rowid = const Value.absent(), + }) => + EntryTagsCompanion.insert( + entryId: entryId, + tagId: tagId, + rowid: rowid, + ), + withReferenceMapper: (p0) => p0 + .map((e) => ( + e.readTable(table), + $$EntryTagsTableReferences(db, table, e) + )) + .toList(), + prefetchHooksCallback: ({entryId = false, tagId = false}) { + return PrefetchHooks( + db: db, + explicitlyWatchedTables: [], + addJoins: < + T extends TableManagerState< + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic>>(state) { + if (entryId) { + state = state.withJoin( + currentTable: table, + currentColumn: table.entryId, + referencedTable: + $$EntryTagsTableReferences._entryIdTable(db), + referencedColumn: + $$EntryTagsTableReferences._entryIdTable(db).id, + ) as T; + } + if (tagId) { + state = state.withJoin( + currentTable: table, + currentColumn: table.tagId, + referencedTable: $$EntryTagsTableReferences._tagIdTable(db), + referencedColumn: + $$EntryTagsTableReferences._tagIdTable(db).id, + ) as T; + } + + return state; + }, + getPrefetchedDataCallback: (items) async { + return []; + }, + ); + }, + )); +} + +typedef $$EntryTagsTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $EntryTagsTable, + EntryTag, + $$EntryTagsTableFilterComposer, + $$EntryTagsTableOrderingComposer, + $$EntryTagsTableAnnotationComposer, + $$EntryTagsTableCreateCompanionBuilder, + $$EntryTagsTableUpdateCompanionBuilder, + (EntryTag, $$EntryTagsTableReferences), + EntryTag, + PrefetchHooks Function({bool entryId, bool tagId})>; +typedef $$LlmInsightsTableCreateCompanionBuilder = LlmInsightsCompanion + Function({ + Value id, + required String type, + required String promptHash, + required String responseText, + Value generatedAt, + Value rangeStart, + Value rangeEnd, +}); +typedef $$LlmInsightsTableUpdateCompanionBuilder = LlmInsightsCompanion + Function({ + Value id, + Value type, + Value promptHash, + Value responseText, + Value generatedAt, + Value rangeStart, + Value rangeEnd, +}); + +class $$LlmInsightsTableFilterComposer + extends Composer<_$AppDatabase, $LlmInsightsTable> { + $$LlmInsightsTableFilterComposer({ + 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 type => $composableBuilder( + column: $table.type, builder: (column) => ColumnFilters(column)); + + ColumnFilters get promptHash => $composableBuilder( + column: $table.promptHash, builder: (column) => ColumnFilters(column)); + + ColumnFilters get responseText => $composableBuilder( + column: $table.responseText, builder: (column) => ColumnFilters(column)); + + ColumnFilters get generatedAt => $composableBuilder( + column: $table.generatedAt, builder: (column) => ColumnFilters(column)); + + ColumnFilters get rangeStart => $composableBuilder( + column: $table.rangeStart, builder: (column) => ColumnFilters(column)); + + ColumnFilters get rangeEnd => $composableBuilder( + column: $table.rangeEnd, builder: (column) => ColumnFilters(column)); +} + +class $$LlmInsightsTableOrderingComposer + extends Composer<_$AppDatabase, $LlmInsightsTable> { + $$LlmInsightsTableOrderingComposer({ + 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 type => $composableBuilder( + column: $table.type, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get promptHash => $composableBuilder( + column: $table.promptHash, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get responseText => $composableBuilder( + column: $table.responseText, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get generatedAt => $composableBuilder( + column: $table.generatedAt, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get rangeStart => $composableBuilder( + column: $table.rangeStart, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get rangeEnd => $composableBuilder( + column: $table.rangeEnd, builder: (column) => ColumnOrderings(column)); +} + +class $$LlmInsightsTableAnnotationComposer + extends Composer<_$AppDatabase, $LlmInsightsTable> { + $$LlmInsightsTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get type => + $composableBuilder(column: $table.type, builder: (column) => column); + + GeneratedColumn get promptHash => $composableBuilder( + column: $table.promptHash, builder: (column) => column); + + GeneratedColumn get responseText => $composableBuilder( + column: $table.responseText, builder: (column) => column); + + GeneratedColumn get generatedAt => $composableBuilder( + column: $table.generatedAt, builder: (column) => column); + + GeneratedColumn get rangeStart => $composableBuilder( + column: $table.rangeStart, builder: (column) => column); + + GeneratedColumn get rangeEnd => + $composableBuilder(column: $table.rangeEnd, builder: (column) => column); +} + +class $$LlmInsightsTableTableManager extends RootTableManager< + _$AppDatabase, + $LlmInsightsTable, + LlmInsight, + $$LlmInsightsTableFilterComposer, + $$LlmInsightsTableOrderingComposer, + $$LlmInsightsTableAnnotationComposer, + $$LlmInsightsTableCreateCompanionBuilder, + $$LlmInsightsTableUpdateCompanionBuilder, + (LlmInsight, BaseReferences<_$AppDatabase, $LlmInsightsTable, LlmInsight>), + LlmInsight, + PrefetchHooks Function()> { + $$LlmInsightsTableTableManager(_$AppDatabase db, $LlmInsightsTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$LlmInsightsTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$LlmInsightsTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$LlmInsightsTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value id = const Value.absent(), + Value type = const Value.absent(), + Value promptHash = const Value.absent(), + Value responseText = const Value.absent(), + Value generatedAt = const Value.absent(), + Value rangeStart = const Value.absent(), + Value rangeEnd = const Value.absent(), + }) => + LlmInsightsCompanion( + id: id, + type: type, + promptHash: promptHash, + responseText: responseText, + generatedAt: generatedAt, + rangeStart: rangeStart, + rangeEnd: rangeEnd, + ), + createCompanionCallback: ({ + Value id = const Value.absent(), + required String type, + required String promptHash, + required String responseText, + Value generatedAt = const Value.absent(), + Value rangeStart = const Value.absent(), + Value rangeEnd = const Value.absent(), + }) => + LlmInsightsCompanion.insert( + id: id, + type: type, + promptHash: promptHash, + responseText: responseText, + generatedAt: generatedAt, + rangeStart: rangeStart, + rangeEnd: rangeEnd, + ), + withReferenceMapper: (p0) => p0 + .map((e) => (e.readTable(table), BaseReferences(db, table, e))) + .toList(), + prefetchHooksCallback: null, + )); +} + +typedef $$LlmInsightsTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $LlmInsightsTable, + LlmInsight, + $$LlmInsightsTableFilterComposer, + $$LlmInsightsTableOrderingComposer, + $$LlmInsightsTableAnnotationComposer, + $$LlmInsightsTableCreateCompanionBuilder, + $$LlmInsightsTableUpdateCompanionBuilder, + (LlmInsight, BaseReferences<_$AppDatabase, $LlmInsightsTable, LlmInsight>), + LlmInsight, + PrefetchHooks Function()>; +typedef $$UserSettingsTableCreateCompanionBuilder = UserSettingsCompanion + Function({ + Value id, + required String key, + required String value, +}); +typedef $$UserSettingsTableUpdateCompanionBuilder = UserSettingsCompanion + Function({ + Value id, + Value key, + Value value, +}); + +class $$UserSettingsTableFilterComposer + extends Composer<_$AppDatabase, $UserSettingsTable> { + $$UserSettingsTableFilterComposer({ + 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 key => $composableBuilder( + column: $table.key, builder: (column) => ColumnFilters(column)); + + ColumnFilters get value => $composableBuilder( + column: $table.value, builder: (column) => ColumnFilters(column)); +} + +class $$UserSettingsTableOrderingComposer + extends Composer<_$AppDatabase, $UserSettingsTable> { + $$UserSettingsTableOrderingComposer({ + 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 key => $composableBuilder( + column: $table.key, builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get value => $composableBuilder( + column: $table.value, builder: (column) => ColumnOrderings(column)); +} + +class $$UserSettingsTableAnnotationComposer + extends Composer<_$AppDatabase, $UserSettingsTable> { + $$UserSettingsTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); + + GeneratedColumn get key => + $composableBuilder(column: $table.key, builder: (column) => column); + + GeneratedColumn get value => + $composableBuilder(column: $table.value, builder: (column) => column); +} + +class $$UserSettingsTableTableManager extends RootTableManager< + _$AppDatabase, + $UserSettingsTable, + UserSetting, + $$UserSettingsTableFilterComposer, + $$UserSettingsTableOrderingComposer, + $$UserSettingsTableAnnotationComposer, + $$UserSettingsTableCreateCompanionBuilder, + $$UserSettingsTableUpdateCompanionBuilder, + ( + UserSetting, + BaseReferences<_$AppDatabase, $UserSettingsTable, UserSetting> + ), + UserSetting, + PrefetchHooks Function()> { + $$UserSettingsTableTableManager(_$AppDatabase db, $UserSettingsTable table) + : super(TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$UserSettingsTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + $$UserSettingsTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + $$UserSettingsTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + Value id = const Value.absent(), + Value key = const Value.absent(), + Value value = const Value.absent(), + }) => + UserSettingsCompanion( + id: id, + key: key, + value: value, + ), + createCompanionCallback: ({ + Value id = const Value.absent(), + required String key, + required String value, + }) => + UserSettingsCompanion.insert( + id: id, + key: key, + value: value, + ), + withReferenceMapper: (p0) => p0 + .map((e) => (e.readTable(table), BaseReferences(db, table, e))) + .toList(), + prefetchHooksCallback: null, + )); +} + +typedef $$UserSettingsTableProcessedTableManager = ProcessedTableManager< + _$AppDatabase, + $UserSettingsTable, + UserSetting, + $$UserSettingsTableFilterComposer, + $$UserSettingsTableOrderingComposer, + $$UserSettingsTableAnnotationComposer, + $$UserSettingsTableCreateCompanionBuilder, + $$UserSettingsTableUpdateCompanionBuilder, + ( + UserSetting, + BaseReferences<_$AppDatabase, $UserSettingsTable, UserSetting> + ), + UserSetting, + PrefetchHooks Function()>; + +class $AppDatabaseManager { + final _$AppDatabase _db; + $AppDatabaseManager(this._db); + $$MoodEntriesTableTableManager get moodEntries => + $$MoodEntriesTableTableManager(_db, _db.moodEntries); + $$ActivitiesTableTableManager get activities => + $$ActivitiesTableTableManager(_db, _db.activities); + $$EntryActivitiesTableTableManager get entryActivities => + $$EntryActivitiesTableTableManager(_db, _db.entryActivities); + $$TagsTableTableManager get tags => $$TagsTableTableManager(_db, _db.tags); + $$EntryTagsTableTableManager get entryTags => + $$EntryTagsTableTableManager(_db, _db.entryTags); + $$LlmInsightsTableTableManager get llmInsights => + $$LlmInsightsTableTableManager(_db, _db.llmInsights); + $$UserSettingsTableTableManager get userSettings => + $$UserSettingsTableTableManager(_db, _db.userSettings); +} diff --git a/lib/core/database/daos/activity_dao.dart b/lib/core/database/daos/activity_dao.dart new file mode 100644 index 0000000..8c5a276 --- /dev/null +++ b/lib/core/database/daos/activity_dao.dart @@ -0,0 +1,42 @@ +import 'package:drift/drift.dart'; +import '../app_database.dart'; +import '../tables.dart'; + +part 'activity_dao.g.dart'; + +@DriftAccessor(tables: [Activities, EntryActivities, MoodEntries]) +class ActivityDao extends DatabaseAccessor + with _$ActivityDaoMixin { + ActivityDao(super.db); + + Stream> watchAllActivities() => + (select(activities)..orderBy([(t) => OrderingTerm.asc(t.sortOrder)])) + .watch(); + + Future insertActivity(ActivitiesCompanion activity) => + into(activities).insert(activity); + + Future deleteActivity(int id) => + (delete(activities)..where((t) => t.id.equals(id))).go(); + + // How many times each activity was logged — used by charts + Future> getActivityFrequency( + DateTime start, DateTime end) async { + final entries = await (select(moodEntries) + ..where((t) => t.timestamp.isBetweenValues(start, end))) + .get(); + final entryIds = entries.map((e) => e.id).toList(); + + if (entryIds.isEmpty) return {}; + + final rows = await (select(entryActivities) + ..where((t) => t.entryId.isIn(entryIds))) + .get(); + + final Map freq = {}; + for (final r in rows) { + freq[r.activityId] = (freq[r.activityId] ?? 0) + 1; + } + return freq; + } +} diff --git a/lib/core/database/daos/activity_dao.g.dart b/lib/core/database/daos/activity_dao.g.dart new file mode 100644 index 0000000..953e1a3 --- /dev/null +++ b/lib/core/database/daos/activity_dao.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'activity_dao.dart'; + +// ignore_for_file: type=lint +mixin _$ActivityDaoMixin on DatabaseAccessor { + $ActivitiesTable get activities => attachedDatabase.activities; + $MoodEntriesTable get moodEntries => attachedDatabase.moodEntries; + $EntryActivitiesTable get entryActivities => attachedDatabase.entryActivities; + ActivityDaoManager get managers => ActivityDaoManager(this); +} + +class ActivityDaoManager { + final _$ActivityDaoMixin _db; + ActivityDaoManager(this._db); + $$ActivitiesTableTableManager get activities => + $$ActivitiesTableTableManager(_db.attachedDatabase, _db.activities); + $$MoodEntriesTableTableManager get moodEntries => + $$MoodEntriesTableTableManager(_db.attachedDatabase, _db.moodEntries); + $$EntryActivitiesTableTableManager get entryActivities => + $$EntryActivitiesTableTableManager( + _db.attachedDatabase, _db.entryActivities); +} diff --git a/lib/core/database/daos/insight_dao.dart b/lib/core/database/daos/insight_dao.dart new file mode 100644 index 0000000..ea43c9d --- /dev/null +++ b/lib/core/database/daos/insight_dao.dart @@ -0,0 +1,26 @@ +import 'package:drift/drift.dart'; +import '../app_database.dart'; +import '../tables.dart'; + +part 'insight_dao.g.dart'; + +@DriftAccessor(tables: [LlmInsights]) +class InsightDao extends DatabaseAccessor with _$InsightDaoMixin { + InsightDao(super.db); + + Future getCached(String promptHash) => (select(llmInsights) + ..where((t) => t.promptHash.equals(promptHash)) + ..limit(1)) + .getSingleOrNull(); + + Future upsertInsight(LlmInsightsCompanion insight) => + into(llmInsights).insertOnConflictUpdate(insight); + + // Purge cached insights older than 7 days + Future purgeStale() { + final cutoff = DateTime.now().subtract(const Duration(days: 7)); + return (delete(llmInsights) + ..where((t) => t.generatedAt.isSmallerThanValue(cutoff))) + .go(); + } +} diff --git a/lib/core/database/daos/insight_dao.g.dart b/lib/core/database/daos/insight_dao.g.dart new file mode 100644 index 0000000..7211dd7 --- /dev/null +++ b/lib/core/database/daos/insight_dao.g.dart @@ -0,0 +1,16 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'insight_dao.dart'; + +// ignore_for_file: type=lint +mixin _$InsightDaoMixin on DatabaseAccessor { + $LlmInsightsTable get llmInsights => attachedDatabase.llmInsights; + InsightDaoManager get managers => InsightDaoManager(this); +} + +class InsightDaoManager { + final _$InsightDaoMixin _db; + InsightDaoManager(this._db); + $$LlmInsightsTableTableManager get llmInsights => + $$LlmInsightsTableTableManager(_db.attachedDatabase, _db.llmInsights); +} diff --git a/lib/core/database/daos/mood_dao.dart b/lib/core/database/daos/mood_dao.dart new file mode 100644 index 0000000..ce37cef --- /dev/null +++ b/lib/core/database/daos/mood_dao.dart @@ -0,0 +1,92 @@ +import 'package:drift/drift.dart'; +import '../app_database.dart'; +import '../tables.dart'; + +part 'mood_dao.g.dart'; + +// Joined result — entry + its activities +class MoodEntryWithActivities { + final MoodEntry entry; + final List activities; + final List tags; + MoodEntryWithActivities({ + required this.entry, + required this.activities, + required this.tags, + }); +} + +@DriftAccessor( + tables: [MoodEntries, EntryActivities, Activities, EntryTags, Tags]) +class MoodDao extends DatabaseAccessor with _$MoodDaoMixin { + MoodDao(super.db); + + // ── Writes ────────────────────────────────────────────────────────────────── + + Future insertEntry(MoodEntriesCompanion entry) => + into(moodEntries).insert(entry); + + Future insertEntryWithActivities({ + required MoodEntriesCompanion entry, + required List activityIds, + required List tagIds, + }) async { + await transaction(() async { + final entryId = await into(moodEntries).insert(entry); + for (final actId in activityIds) { + await into(entryActivities).insert( + EntryActivitiesCompanion.insert(entryId: entryId, activityId: actId), + ); + } + for (final tagId in tagIds) { + await into(entryTags).insert( + EntryTagsCompanion.insert(entryId: entryId, tagId: tagId), + ); + } + }); + } + + Future deleteEntry(int id) => + (delete(moodEntries)..where((t) => t.id.equals(id))).go(); + + Future updateEntry(MoodEntriesCompanion entry) => + (update(moodEntries)..where((t) => t.id.equals(entry.id.value))) + .write(entry); + + // ── Reads ─────────────────────────────────────────────────────────────────── + + Stream> watchAllEntries() => + (select(moodEntries)..orderBy([(t) => OrderingTerm.desc(t.timestamp)])) + .watch(); + + Stream> watchEntriesForDay(DateTime day) { + final start = DateTime(day.year, day.month, day.day); + final end = start.add(const Duration(days: 1)); + return (select(moodEntries) + ..where((t) => t.timestamp.isBetweenValues(start, end)) + ..orderBy([(t) => OrderingTerm.desc(t.timestamp)])) + .watch(); + } + + Future> getEntriesInRange(DateTime start, DateTime end) => + (select(moodEntries) + ..where((t) => t.timestamp.isBetweenValues(start, end)) + ..orderBy([(t) => OrderingTerm.asc(t.timestamp)])) + .get(); + + // Average mood per day — used by calendar heatmap + Future> getDailyAverages( + DateTime start, DateTime end) async { + final entries = await getEntriesInRange(start, end); + final Map> grouped = {}; + for (final e in entries) { + final day = + DateTime(e.timestamp.year, e.timestamp.month, e.timestamp.day); + grouped.putIfAbsent(day, () => []).add(e.moodLevel); + } + return grouped.map( + (day, levels) => + MapEntry(day, levels.reduce((a, b) => a + b) / levels.length), + ); + } +} diff --git a/lib/core/database/daos/mood_dao.g.dart b/lib/core/database/daos/mood_dao.g.dart new file mode 100644 index 0000000..42e2c5f --- /dev/null +++ b/lib/core/database/daos/mood_dao.g.dart @@ -0,0 +1,29 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'mood_dao.dart'; + +// ignore_for_file: type=lint +mixin _$MoodDaoMixin on DatabaseAccessor { + $MoodEntriesTable get moodEntries => attachedDatabase.moodEntries; + $ActivitiesTable get activities => attachedDatabase.activities; + $EntryActivitiesTable get entryActivities => attachedDatabase.entryActivities; + $TagsTable get tags => attachedDatabase.tags; + $EntryTagsTable get entryTags => attachedDatabase.entryTags; + MoodDaoManager get managers => MoodDaoManager(this); +} + +class MoodDaoManager { + final _$MoodDaoMixin _db; + MoodDaoManager(this._db); + $$MoodEntriesTableTableManager get moodEntries => + $$MoodEntriesTableTableManager(_db.attachedDatabase, _db.moodEntries); + $$ActivitiesTableTableManager get activities => + $$ActivitiesTableTableManager(_db.attachedDatabase, _db.activities); + $$EntryActivitiesTableTableManager get entryActivities => + $$EntryActivitiesTableTableManager( + _db.attachedDatabase, _db.entryActivities); + $$TagsTableTableManager get tags => + $$TagsTableTableManager(_db.attachedDatabase, _db.tags); + $$EntryTagsTableTableManager get entryTags => + $$EntryTagsTableTableManager(_db.attachedDatabase, _db.entryTags); +} diff --git a/lib/core/database/daos/settings_dao.dart b/lib/core/database/daos/settings_dao.dart new file mode 100644 index 0000000..27a1f25 --- /dev/null +++ b/lib/core/database/daos/settings_dao.dart @@ -0,0 +1,27 @@ +import 'package:drift/drift.dart'; +import '../app_database.dart'; +import '../tables.dart'; + +part 'settings_dao.g.dart'; + +@DriftAccessor(tables: [UserSettings]) +class SettingsDao extends DatabaseAccessor + with _$SettingsDaoMixin { + SettingsDao(super.db); + + Future get(String key) async { + final row = await (select(userSettings) + ..where((t) => t.key.equals(key)) + ..limit(1)) + .getSingleOrNull(); + return row?.value; + } + + Future set(String key, String value) => + into(userSettings).insertOnConflictUpdate( + UserSettingsCompanion.insert(key: key, value: value), + ); + + Future deleteByKey(String key) => + (delete(userSettings)..where((t) => t.key.equals(key))).go(); +} diff --git a/lib/core/database/daos/settings_dao.g.dart b/lib/core/database/daos/settings_dao.g.dart new file mode 100644 index 0000000..23e8aa5 --- /dev/null +++ b/lib/core/database/daos/settings_dao.g.dart @@ -0,0 +1,16 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'settings_dao.dart'; + +// ignore_for_file: type=lint +mixin _$SettingsDaoMixin on DatabaseAccessor { + $UserSettingsTable get userSettings => attachedDatabase.userSettings; + SettingsDaoManager get managers => SettingsDaoManager(this); +} + +class SettingsDaoManager { + final _$SettingsDaoMixin _db; + SettingsDaoManager(this._db); + $$UserSettingsTableTableManager get userSettings => + $$UserSettingsTableTableManager(_db.attachedDatabase, _db.userSettings); +} diff --git a/lib/core/database/tables.dart b/lib/core/database/tables.dart new file mode 100644 index 0000000..f6e3589 --- /dev/null +++ b/lib/core/database/tables.dart @@ -0,0 +1,72 @@ +import 'package:drift/drift.dart'; + +// ─── Mood Entries ──────────────────────────────────────────────────────────── + +class MoodEntries extends Table { + IntColumn get id => integer().autoIncrement()(); + DateTimeColumn get timestamp => dateTime()(); + IntColumn get moodLevel => integer()(); // 1–5 + TextColumn get note => text().nullable()(); + DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); +} + +// ─── Activities ────────────────────────────────────────────────────────────── + +class Activities extends Table { + IntColumn get id => integer().autoIncrement()(); + TextColumn get name => text().withLength(min: 1, max: 50)(); + IntColumn get iconCodepoint => integer()(); // Icons codepoint value + TextColumn get colourHex => + text().withLength(min: 7, max: 7)(); // e.g. #FF5733 + BoolColumn get isCustom => boolean().withDefault(const Constant(false))(); + IntColumn get sortOrder => integer().withDefault(const Constant(0))(); +} + +// ─── Entry ↔ Activity (many-to-many) ───────────────────────────────────────── + +class EntryActivities extends Table { + IntColumn get entryId => integer().references(MoodEntries, #id)(); + IntColumn get activityId => integer().references(Activities, #id)(); + + @override + Set get primaryKey => {entryId, activityId}; +} + +// ─── Tags ──────────────────────────────────────────────────────────────────── + +class Tags extends Table { + IntColumn get id => integer().autoIncrement()(); + TextColumn get name => text().withLength(min: 1, max: 30)(); + TextColumn get colourHex => text().withLength(min: 7, max: 7)(); +} + +// ─── Entry ↔ Tag (many-to-many) ─────────────────────────────────────────────── + +class EntryTags extends Table { + IntColumn get entryId => integer().references(MoodEntries, #id)(); + IntColumn get tagId => integer().references(Tags, #id)(); + + @override + Set get primaryKey => {entryId, tagId}; +} + +// ─── LLM Insight Cache ─────────────────────────────────────────────────────── + +class LlmInsights extends Table { + IntColumn get id => integer().autoIncrement()(); + TextColumn get type => text()(); // 'weekly' | 'monthly' | 'query' + TextColumn get promptHash => text()(); // SHA256 of the prompt — cache key + TextColumn get responseText => text()(); + DateTimeColumn get generatedAt => + dateTime().withDefault(currentDateAndTime)(); + DateTimeColumn get rangeStart => dateTime().nullable()(); + DateTimeColumn get rangeEnd => dateTime().nullable()(); +} + +// ─── Settings ──────────────────────────────────────────────────────────────── + +class UserSettings extends Table { + IntColumn get id => integer().autoIncrement()(); + TextColumn get key => text().withLength(min: 1, max: 50).unique()(); + TextColumn get value => text()(); +} diff --git a/lib/core/llm/llm_service.dart b/lib/core/llm/llm_service.dart new file mode 100644 index 0000000..bccce5d --- /dev/null +++ b/lib/core/llm/llm_service.dart @@ -0,0 +1,5 @@ +abstract class LlmService { + Future initialise(); + Stream generateStream(String prompt); + void dispose(); +} diff --git a/lib/core/llm/mediapipe_llm_service.dart b/lib/core/llm/mediapipe_llm_service.dart new file mode 100644 index 0000000..347ba7c --- /dev/null +++ b/lib/core/llm/mediapipe_llm_service.dart @@ -0,0 +1,30 @@ +import 'package:flutter_mediapipe_chat/flutter_mediapipe_chat.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:path/path.dart' as p; +import 'llm_service.dart'; + +class MediapipeLlmService implements LlmService { + final _chat = FlutterMediapipeChat(); + bool _initialised = false; + + static const _modelFileName = 'gemma-2b-it-cpu-int4.bin'; + + @override + Future initialise() async { + if (_initialised) return; + final dir = await getApplicationSupportDirectory(); + final modelPath = p.join(dir.path, _modelFileName); + await _chat.loadModel(ModelConfig(path: modelPath)); + _initialised = true; + } + + @override + Stream generateStream(String prompt) { + return _chat.generateResponseAsync(prompt); + } + + @override + void dispose() { + _initialised = false; + } +} diff --git a/lib/core/providers/activity_provider.dart b/lib/core/providers/activity_provider.dart new file mode 100644 index 0000000..3836865 --- /dev/null +++ b/lib/core/providers/activity_provider.dart @@ -0,0 +1,75 @@ +import 'package:drift/drift.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../database/app_database.dart'; +import 'database_provider.dart'; + +// ── All activities stream ───────────────────────────────────────────────────── + +final activitiesProvider = StreamProvider.autoDispose>((ref) { + return ref.watch(activityDaoProvider).watchAllActivities(); +}); + +// ── Activity frequency for charts ──────────────────────────────────────────── + +final activityFrequencyProvider = FutureProvider.autoDispose + .family, ({DateTime start, DateTime end})>( + (ref, range) => + ref.watch(activityDaoProvider).getActivityFrequency(range.start, range.end), +); + +// ── Selected activities (used by log mood screen) ───────────────────────────── + +class SelectedActivities extends Notifier> { + @override + Set build() => {}; + + void toggle(int activityId) { + if (state.contains(activityId)) { + state = {...state}..remove(activityId); + } else { + state = {...state, activityId}; + } + } + + void clear() => state = {}; +} + +final selectedActivitiesProvider = + NotifierProvider.autoDispose>( + SelectedActivities.new); + +// ── Activity notifier (create / delete custom activities) ───────────────────── + +class ActivityNotifier extends Notifier> { + @override + AsyncValue build() => const AsyncData(null); + + Future addActivity({ + required String name, + required int iconCodepoint, + required String colourHex, + }) async { + state = const AsyncLoading(); + state = await AsyncValue.guard( + () => ref.read(activityDaoProvider).insertActivity( + ActivitiesCompanion.insert( + name: name, + iconCodepoint: iconCodepoint, + colourHex: colourHex, + isCustom: const Value(true), + ), + ), + ); + } + + Future deleteActivity(int id) async { + state = const AsyncLoading(); + state = await AsyncValue.guard( + () => ref.read(activityDaoProvider).deleteActivity(id), + ); + } +} + +final activityNotifierProvider = + NotifierProvider.autoDispose>( + ActivityNotifier.new); diff --git a/lib/core/providers/database_provider.dart b/lib/core/providers/database_provider.dart new file mode 100644 index 0000000..1b0c8b0 --- /dev/null +++ b/lib/core/providers/database_provider.dart @@ -0,0 +1,24 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../database/app_database.dart'; +import '../database/daos/mood_dao.dart'; +import '../database/daos/activity_dao.dart'; +import '../database/daos/insight_dao.dart'; +import '../database/daos/settings_dao.dart'; + +final appDatabaseProvider = Provider((ref) { + final db = AppDatabase(); + ref.onDispose(db.close); + return db; +}); + +final moodDaoProvider = + Provider((ref) => ref.watch(appDatabaseProvider).moodDao); + +final activityDaoProvider = + Provider((ref) => ref.watch(appDatabaseProvider).activityDao); + +final insightDaoProvider = + Provider((ref) => ref.watch(appDatabaseProvider).insightDao); + +final settingsDaoProvider = + Provider((ref) => ref.watch(appDatabaseProvider).settingsDao); diff --git a/lib/core/providers/insight_provider.dart b/lib/core/providers/insight_provider.dart new file mode 100644 index 0000000..12a5fae --- /dev/null +++ b/lib/core/providers/insight_provider.dart @@ -0,0 +1,73 @@ +import 'dart:convert'; +import 'package:crypto/crypto.dart'; +import 'package:drift/drift.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../database/app_database.dart'; +import 'database_provider.dart'; + +// ── Insight type enum ───────────────────────────────────────────────────────── + +enum InsightType { weekly, monthly, query } + +// ── Cached insight lookup ───────────────────────────────────────────────────── + +final cachedInsightProvider = + FutureProvider.autoDispose.family((ref, promptHash) { + return ref.watch(insightDaoProvider).getCached(promptHash); +}); + +// ── Insight notifier — triggers generation and caches results ───────────────── + +class InsightNotifier extends Notifier> { + @override + AsyncValue build() => const AsyncData(null); + + String _hashPrompt(String prompt) => + sha256.convert(utf8.encode(prompt)).toString(); + + Future generateInsight({ + required String prompt, + required InsightType type, + DateTime? rangeStart, + DateTime? rangeEnd, + }) async { + state = const AsyncLoading(); + + final hash = _hashPrompt(prompt); + final dao = ref.read(insightDaoProvider); + + final cached = await dao.getCached(hash); + if (cached != null) { + state = AsyncData(cached.responseText); + return; + } + + // Generation happens in LlmNotifier (see llm_provider.dart) + state = const AsyncData(null); + } + + Future saveInsight({ + required String promptHash, + required String responseText, + required InsightType type, + DateTime? rangeStart, + DateTime? rangeEnd, + }) async { + await ref.read(insightDaoProvider).upsertInsight( + LlmInsightsCompanion.insert( + type: type.name, + promptHash: promptHash, + responseText: responseText, + rangeStart: Value(rangeStart), + rangeEnd: Value(rangeEnd), + ), + ); + state = AsyncData(responseText); + } + + void clear() => state = const AsyncData(null); +} + +final insightNotifierProvider = + NotifierProvider.autoDispose>( + InsightNotifier.new); diff --git a/lib/core/providers/llm_provider.dart b/lib/core/providers/llm_provider.dart new file mode 100644 index 0000000..94f25e3 --- /dev/null +++ b/lib/core/providers/llm_provider.dart @@ -0,0 +1,55 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../llm/llm_service.dart'; +import '../llm/mediapipe_llm_service.dart'; + +// ── Service singleton ───────────────────────────────────────────────────────── + +final llmServiceProvider = Provider((ref) { + final service = MediapipeLlmService(); + ref.onDispose(service.dispose); + return service; +}); + +// ── Model initialisation state ──────────────────────────────────────────────── + +final llmReadyProvider = FutureProvider((ref) async { + await ref.watch(llmServiceProvider).initialise(); +}); + +// ── Streaming response notifier ─────────────────────────────────────────────── + +class LlmResponseNotifier extends Notifier> { + bool _cancelled = false; + + @override + AsyncValue build() => const AsyncData(''); + + Future generate(String prompt) async { + _cancelled = false; + state = const AsyncLoading(); + + final service = ref.read(llmServiceProvider); + final buffer = StringBuffer(); + + try { + await for (final token in service.generateStream(prompt)) { + if (_cancelled) break; + buffer.write(token); + state = AsyncData(buffer.toString()); + } + } catch (e, st) { + state = AsyncError(e, st); + } + } + + void cancel() { + _cancelled = true; + state = const AsyncData(''); + } + + void clear() => state = const AsyncData(''); +} + +final llmResponseNotifierProvider = + NotifierProvider.autoDispose>( + LlmResponseNotifier.new); diff --git a/lib/core/providers/mood_provider.dart b/lib/core/providers/mood_provider.dart new file mode 100644 index 0000000..7a01cd8 --- /dev/null +++ b/lib/core/providers/mood_provider.dart @@ -0,0 +1,103 @@ +import 'package:drift/drift.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../database/app_database.dart'; +import 'database_provider.dart'; + +// ── All entries stream ──────────────────────────────────────────────────────── + +final moodEntriesProvider = StreamProvider.autoDispose>((ref) { + return ref.watch(moodDaoProvider).watchAllEntries(); +}); + +// ── Entries for a specific day ──────────────────────────────────────────────── + +final moodEntriesForDayProvider = + StreamProvider.autoDispose.family, DateTime>((ref, day) { + return ref.watch(moodDaoProvider).watchEntriesForDay(day); +}); + +// ── Daily averages for calendar heatmap ────────────────────────────────────── + +final dailyAveragesProvider = FutureProvider.autoDispose + .family, ({DateTime start, DateTime end})>( + (ref, range) => + ref.watch(moodDaoProvider).getDailyAverages(range.start, range.end), +); + +// ── Selected day (drives calendar + day detail) ─────────────────────────────── + +class SelectedDay extends Notifier { + @override + DateTime build() => DateTime.now(); + + void select(DateTime day) { + state = DateTime(day.year, day.month, day.day); + } + + void selectToday() { + final now = DateTime.now(); + state = DateTime(now.year, now.month, now.day); + } +} + +final selectedDayProvider = + NotifierProvider.autoDispose(SelectedDay.new); + +// ── Mood entry notifier (create / update / delete) ──────────────────────────── + +class MoodEntryNotifier extends Notifier> { + @override + AsyncValue build() => const AsyncData(null); + + Future addEntry({ + required int moodLevel, + String? note, + List activityIds = const [], + List tagIds = const [], + DateTime? timestamp, + }) async { + state = const AsyncLoading(); + state = await AsyncValue.guard(() async { + final dao = ref.read(moodDaoProvider); + await dao.insertEntryWithActivities( + entry: MoodEntriesCompanion.insert( + moodLevel: moodLevel, + timestamp: timestamp ?? DateTime.now(), + note: Value(note), + ), + activityIds: activityIds, + tagIds: tagIds, + ); + }); + } + + Future deleteEntry(int id) async { + state = const AsyncLoading(); + state = await AsyncValue.guard( + () => ref.read(moodDaoProvider).deleteEntry(id), + ); + } + + Future updateEntry({ + required int id, + required int moodLevel, + String? note, + DateTime? timestamp, + }) async { + state = const AsyncLoading(); + state = await AsyncValue.guard( + () => ref.read(moodDaoProvider).updateEntry( + MoodEntriesCompanion( + id: Value(id), + moodLevel: Value(moodLevel), + note: Value(note), + timestamp: Value(timestamp ?? DateTime.now()), + ), + ), + ); + } +} + +final moodEntryNotifierProvider = + NotifierProvider.autoDispose>( + MoodEntryNotifier.new); diff --git a/lib/core/providers/settings_provider.dart b/lib/core/providers/settings_provider.dart new file mode 100644 index 0000000..88581ac --- /dev/null +++ b/lib/core/providers/settings_provider.dart @@ -0,0 +1,69 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'database_provider.dart'; + +// ── Key constants ───────────────────────────────────────────────────────────── + +abstract class SettingsKeys { + static const reminderEnabled = 'reminder_enabled'; + static const reminderTime = 'reminder_time'; // stored as 'HH:mm' + static const biometricEnabled = 'biometric_enabled'; + static const themMode = 'theme_mode'; // 'system' | 'light' | 'dark' + static const modelDownloaded = 'model_downloaded'; + static const onboardingComplete = 'onboarding_complete'; +} + +// ── Generic setting reader ──────────────────────────────────────────────────── + +final settingProvider = + FutureProvider.autoDispose.family((ref, key) { + return ref.watch(settingsDaoProvider).get(key); +}); + +// ── Settings notifier ───────────────────────────────────────────────────────── + +class SettingsNotifier extends Notifier> { + @override + AsyncValue build() => const AsyncData(null); + + Future set(String key, String value) async { + await ref.read(settingsDaoProvider).set(key, value); + ref.invalidate(settingProvider(key)); + } + + Future setReminderEnabled(bool enabled) => + set(SettingsKeys.reminderEnabled, enabled.toString()); + + Future setReminderTime(int hour, int minute) => set( + SettingsKeys.reminderTime, + '${hour.toString().padLeft(2, '0')}:${minute.toString().padLeft(2, '0')}'); + + Future setBiometricEnabled(bool enabled) => + set(SettingsKeys.biometricEnabled, enabled.toString()); + + Future setThemeMode(String mode) => set(SettingsKeys.themMode, mode); + + Future markModelDownloaded() => + set(SettingsKeys.modelDownloaded, 'true'); + + Future markOnboardingComplete() => + set(SettingsKeys.onboardingComplete, 'true'); +} + +final settingsNotifierProvider = + NotifierProvider.autoDispose>( + SettingsNotifier.new); + +// ── Convenience bool readers ────────────────────────────────────────────────── + +final isOnboardingCompleteProvider = + FutureProvider.autoDispose((ref) async { + final val = + await ref.watch(settingProvider(SettingsKeys.onboardingComplete).future); + return val == 'true'; +}); + +final isModelDownloadedProvider = FutureProvider.autoDispose((ref) async { + final val = + await ref.watch(settingProvider(SettingsKeys.modelDownloaded).future); + return val == 'true'; +}); diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..29a51f8 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +void main() { + runApp(const App()); +} + +class App extends StatelessWidget { + const App({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Lumina', + debugShowCheckedModeBanner: false, + theme: ThemeData(useMaterial3: true), + home: const Scaffold(body: Center(child: Text('Lumina'))), + ); + } +} diff --git a/linux/.gitignore b/linux/.gitignore new file mode 100644 index 0000000..d3896c9 --- /dev/null +++ b/linux/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt new file mode 100644 index 0000000..d640e52 --- /dev/null +++ b/linux/CMakeLists.txt @@ -0,0 +1,128 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.13) +project(runner LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "dailyou") +# The unique GTK application identifier for this application. See: +# https://wiki.gnome.org/HowDoI/ChooseApplicationID +set(APPLICATION_ID "com.example.dailyou") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Load bundled libraries from the lib/ directory relative to the binary. +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Root filesystem for cross-building. +if(FLUTTER_TARGET_PLATFORM_SYSROOT) + set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +# Define build configuration options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) + +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "${bundled_library}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endforeach(bundled_library) + +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/linux/flutter/CMakeLists.txt b/linux/flutter/CMakeLists.txt new file mode 100644 index 0000000..d5bd016 --- /dev/null +++ b/linux/flutter/CMakeLists.txt @@ -0,0 +1,88 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..e71a16d --- /dev/null +++ b/linux/flutter/generated_plugin_registrant.cc @@ -0,0 +1,11 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + + +void fl_register_plugins(FlPluginRegistry* registry) { +} diff --git a/linux/flutter/generated_plugin_registrant.h b/linux/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..e0f0a47 --- /dev/null +++ b/linux/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void fl_register_plugins(FlPluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake new file mode 100644 index 0000000..2e1de87 --- /dev/null +++ b/linux/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/linux/runner/CMakeLists.txt b/linux/runner/CMakeLists.txt new file mode 100644 index 0000000..e97dabc --- /dev/null +++ b/linux/runner/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.13) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the application ID. +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Add dependency libraries. Add any application-specific dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") diff --git a/linux/runner/main.cc b/linux/runner/main.cc new file mode 100644 index 0000000..e7c5c54 --- /dev/null +++ b/linux/runner/main.cc @@ -0,0 +1,6 @@ +#include "my_application.h" + +int main(int argc, char** argv) { + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/linux/runner/my_application.cc b/linux/runner/my_application.cc new file mode 100644 index 0000000..ef6818d --- /dev/null +++ b/linux/runner/my_application.cc @@ -0,0 +1,148 @@ +#include "my_application.h" + +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// Called when first Flutter frame received. +static void first_frame_cb(MyApplication* self, FlView* view) { + gtk_widget_show(gtk_widget_get_toplevel(GTK_WIDGET(view))); +} + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen* screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "dailyou"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + } else { + gtk_window_set_title(window, "dailyou"); + } + + gtk_window_set_default_size(window, 1280, 720); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments( + project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + GdkRGBA background_color; + // Background defaults to black, override it here if necessary, e.g. #00000000 + // for transparent. + gdk_rgba_parse(&background_color, "#000000"); + fl_view_set_background_color(view, &background_color); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + // Show the window when Flutter renders. + // Requires the view to be realized so we can start rendering. + g_signal_connect_swapped(view, "first-frame", G_CALLBACK(first_frame_cb), + self); + gtk_widget_realize(GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +// Implements GApplication::local_command_line. +static gboolean my_application_local_command_line(GApplication* application, + gchar*** arguments, + int* exit_status) { + MyApplication* self = MY_APPLICATION(application); + // Strip out the first argument as it is the binary name. + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + +// Implements GApplication::startup. +static void my_application_startup(GApplication* application) { + // MyApplication* self = MY_APPLICATION(object); + + // Perform any actions required at application startup. + + G_APPLICATION_CLASS(my_application_parent_class)->startup(application); +} + +// Implements GApplication::shutdown. +static void my_application_shutdown(GApplication* application) { + // MyApplication* self = MY_APPLICATION(object); + + // Perform any actions required at application shutdown. + + G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application); +} + +// Implements GObject::dispose. +static void my_application_dispose(GObject* object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = + my_application_local_command_line; + G_APPLICATION_CLASS(klass)->startup = my_application_startup; + G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + // Set the program name to the application ID, which helps various systems + // like GTK and desktop environments map this running application to its + // corresponding .desktop file. This ensures better integration by allowing + // the application to be recognized beyond its binary name. + g_set_prgname(APPLICATION_ID); + + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, "flags", + G_APPLICATION_NON_UNIQUE, nullptr)); +} diff --git a/linux/runner/my_application.h b/linux/runner/my_application.h new file mode 100644 index 0000000..db16367 --- /dev/null +++ b/linux/runner/my_application.h @@ -0,0 +1,21 @@ +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, + my_application, + MY, + APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/macos/.gitignore b/macos/.gitignore new file mode 100644 index 0000000..746adbb --- /dev/null +++ b/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/macos/Flutter/Flutter-Debug.xcconfig b/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000..c2efd0b --- /dev/null +++ b/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/Flutter-Release.xcconfig b/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000..c2efd0b --- /dev/null +++ b/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 0000000..cccf817 --- /dev/null +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,10 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { +} diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..e4d070a --- /dev/null +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,705 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC10EC2044A3C60003C045; + remoteInfo = Runner; + }; + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* dailyou.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "dailyou.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C80D7294CF71000263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* dailyou.app */, + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C80D4294CF70F00263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C80D1294CF70F00263BE5 /* Sources */, + 331C80D2294CF70F00263BE5 /* Frameworks */, + 331C80D3294CF70F00263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C80DA294CF71000263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* dailyou.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C80D4294CF70F00263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 33CC10EC2044A3C60003C045; + }; + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 331C80D4294CF70F00263BE5 /* RunnerTests */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C80D3294CF70F00263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C80D1294CF70F00263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC10EC2044A3C60003C045 /* Runner */; + targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; + }; + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 331C80DB294CF71000263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.dailyou.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/dailyou.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/dailyou"; + }; + name = Debug; + }; + 331C80DC294CF71000263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.dailyou.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/dailyou.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/dailyou"; + }; + name = Release; + }; + 331C80DD294CF71000263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.dailyou.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/dailyou.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/dailyou"; + }; + name = Profile; + }; + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + 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_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + 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_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + 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_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + 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_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + 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_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + 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_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + 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_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C80DB294CF71000263BE5 /* Debug */, + 331C80DC294CF71000263BE5 /* Release */, + 331C80DD294CF71000263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..9350c5e --- /dev/null +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/macos/Runner.xcworkspace/contents.xcworkspacedata b/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000..b3c1761 --- /dev/null +++ b/macos/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Cocoa +import FlutterMacOS + +@main +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } +} diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a2ec33f --- /dev/null +++ b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000..82b6f9d Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000..13b35eb Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000..0a3f5fa Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 0000000..bdb5722 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 0000000..f083318 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 0000000..326c0e7 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000..2f1632c Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/macos/Runner/Base.lproj/MainMenu.xib b/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 0000000..80e867a --- /dev/null +++ b/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/macos/Runner/Configs/AppInfo.xcconfig b/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000..39eac09 --- /dev/null +++ b/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = dailyou + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.example.dailyou + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2026 com.example. All rights reserved. diff --git a/macos/Runner/Configs/Debug.xcconfig b/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000..36b0fd9 --- /dev/null +++ b/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/macos/Runner/Configs/Release.xcconfig b/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000..dff4f49 --- /dev/null +++ b/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/macos/Runner/Configs/Warnings.xcconfig b/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000..42bcbf4 --- /dev/null +++ b/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/macos/Runner/DebugProfile.entitlements b/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000..dddb8a3 --- /dev/null +++ b/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/macos/Runner/Info.plist b/macos/Runner/Info.plist new file mode 100644 index 0000000..4789daa --- /dev/null +++ b/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/macos/Runner/MainFlutterWindow.swift b/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000..3cc05eb --- /dev/null +++ b/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/macos/RunnerTests/RunnerTests.swift b/macos/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..61f3bd1 --- /dev/null +++ b/macos/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Cocoa +import FlutterMacOS +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/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..e8880df --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,1146 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "8d7ff3948166b8ec5da0fbb5962000926b8e02f2ed9b3e51d1738905fbd4c98d" + url: "https://pub.dev" + source: hosted + version: "93.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: de7148ed2fcec579b19f122c1800933dfa028f6d9fd38a152b04b1516cec120b + url: "https://pub.dev" + source: hosted + version: "10.0.1" + archive: + dependency: transitive + description: + name: archive + sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff + url: "https://pub.dev" + source: hosted + version: "4.0.9" + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" + async: + dependency: transitive + description: + name: async + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 + url: "https://pub.dev" + source: hosted + version: "2.13.1" + barcode: + dependency: transitive + description: + name: barcode + sha256: "7b6729c37e3b7f34233e2318d866e8c48ddb46c1f7ad01ff7bb2a8de1da2b9f4" + url: "https://pub.dev" + source: hosted + version: "2.2.9" + bidi: + dependency: transitive + description: + name: bidi + sha256: "77f475165e94b261745cf1032c751e2032b8ed92ccb2bf5716036db79320637d" + url: "https://pub.dev" + source: hosted + version: "2.0.13" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + build: + dependency: transitive + description: + name: build + sha256: aadd943f4f8cc946882c954c187e6115a84c98c81ad1d9c6cbf0895a8c85da9c + url: "https://pub.dev" + source: hosted + version: "4.0.5" + build_config: + dependency: transitive + description: + name: build_config + sha256: "4070d2a59f8eec34c97c86ceb44403834899075f66e8a9d59706f8e7834f6f71" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: bf05f6e12cfea92d3c09308d7bcdab1906cd8a179b023269eed00c071004b957 + url: "https://pub.dev" + source: hosted + version: "4.1.1" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: "22fdcc3cfeb9d974d7408718c4be15ec5e9b1b350088f3a6c88f154e74dd700d" + url: "https://pub.dev" + source: hosted + version: "2.14.1" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "0730c18c770d05636a8f945c32a4d7d81cb6e0f0148c8db4ad12e7748f7e49af" + url: "https://pub.dev" + source: hosted + version: "8.12.5" + characters: + dependency: transitive + description: + name: characters + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + url: "https://pub.dev" + source: hosted + version: "1.4.1" + charcode: + dependency: transitive + description: + name: charcode + sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a + url: "https://pub.dev" + source: hosted + version: "1.4.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" + url: "https://pub.dev" + source: hosted + version: "2.0.4" + cli_config: + dependency: transitive + description: + name: cli_config + sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec + url: "https://pub.dev" + source: hosted + version: "0.2.0" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c + url: "https://pub.dev" + source: hosted + version: "0.4.2" + clock: + dependency: transitive + description: + name: clock + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + url: "https://pub.dev" + source: hosted + version: "1.1.2" + code_assets: + dependency: transitive + description: + name: code_assets + sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + collection: + dependency: transitive + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + coverage: + dependency: transitive + description: + name: coverage + sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d" + url: "https://pub.dev" + source: hosted + version: "1.15.0" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937" + url: "https://pub.dev" + source: hosted + version: "0.3.5+2" + crypto: + dependency: "direct main" + description: + name: crypto + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf + url: "https://pub.dev" + source: hosted + version: "3.0.7" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "29f7ecc274a86d32920b1d9cfc7502fa87220da41ec60b55f329559d5732e2b2" + url: "https://pub.dev" + source: hosted + version: "3.1.7" + dbus: + dependency: transitive + description: + name: dbus + sha256: d0c98dcd4f5169878b6cf8f6e0a52403a9dff371a3e2f019697accbf6f44a270 + url: "https://pub.dev" + source: hosted + version: "0.7.12" + drift: + dependency: "direct main" + description: + name: drift + sha256: "055c249d1f91be5a47fe447f88afc24c4ca6f4cd6c5ed66767b4797d48acc2e5" + url: "https://pub.dev" + source: hosted + version: "2.32.1" + drift_dev: + dependency: "direct dev" + description: + name: drift_dev + sha256: "88a9de3af8571518148a6d8a513b57779fd1e60a026d3ab8a481a878fba01d91" + url: "https://pub.dev" + source: hosted + version: "2.32.1" + drift_flutter: + dependency: "direct main" + description: + name: drift_flutter + sha256: "887fdec622174dc7eaefd0048403e34ee07cc18626ac8a7544cc3b8a4a172166" + url: "https://pub.dev" + source: hosted + version: "0.3.0" + equatable: + dependency: transitive + description: + name: equatable + sha256: "3e0141505477fd8ad55d6eb4e7776d3fe8430be8e497ccb1521370c3f21a3e2b" + url: "https://pub.dev" + source: hosted + version: "2.0.8" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + ffi_leak_tracker: + dependency: transitive + description: + name: ffi_leak_tracker + sha256: "4093d4ef9ca06ffe2786e73bfb25e22aa92112b9bb4ec941f11e3e6b61489a97" + url: "https://pub.dev" + source: hosted + version: "0.1.2" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.dev" + source: hosted + version: "1.1.1" + fl_chart: + dependency: "direct main" + description: + name: fl_chart + sha256: b938f77d042cbcd822936a7a359a7235bad8bd72070de1f827efc2cc297ac888 + url: "https://pub.dev" + source: hosted + version: "1.2.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" + url: "https://pub.dev" + source: hosted + version: "6.0.0" + flutter_local_notifications: + dependency: "direct main" + description: + name: flutter_local_notifications + sha256: "0d9035862236fe38250fe1644d7ed3b8254e34a21b2c837c9f539fbb3bba5ef1" + url: "https://pub.dev" + source: hosted + version: "21.0.0" + flutter_local_notifications_linux: + dependency: transitive + description: + name: flutter_local_notifications_linux + sha256: e0f25e243c6c44c825bbbc6b2b2e76f7d9222362adcfe9fd780bf01923c840bd + url: "https://pub.dev" + source: hosted + version: "8.0.0" + flutter_local_notifications_platform_interface: + dependency: transitive + description: + name: flutter_local_notifications_platform_interface + sha256: e7db3d5b49c2b7ecc68deba4aaaa67a348f92ee0fef34c8e4b4459dbef0d7307 + url: "https://pub.dev" + source: hosted + version: "11.0.0" + flutter_local_notifications_windows: + dependency: transitive + description: + name: flutter_local_notifications_windows + sha256: "3a2654ba104fbb52c618ebed9def24ef270228470718c43b3a6afcd5c81bef0c" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + flutter_markdown_plus: + dependency: "direct main" + description: + name: flutter_markdown_plus + sha256: "039177906850278e8fb1cd364115ee0a46281135932fa8ecea8455522166d2de" + url: "https://pub.dev" + source: hosted + version: "1.0.7" + flutter_mediapipe_chat: + dependency: "direct main" + description: + name: flutter_mediapipe_chat + sha256: "986ea27d26bef04e7516e055816844ad1d1a3578b77a357f54c2e0735ec31aa4" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "38d1c268de9097ff59cf0e844ac38759fc78f76836d37edad06fa21e182055a0" + url: "https://pub.dev" + source: hosted + version: "2.0.34" + flutter_riverpod: + dependency: "direct main" + description: + name: flutter_riverpod + sha256: "4e166be88e1dbbaa34a280bdb744aeae73b7ef25fdf8db7a3bb776760a3648e2" + url: "https://pub.dev" + source: hosted + version: "3.3.1" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.dev" + source: hosted + version: "4.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + url: "https://pub.dev" + source: hosted + version: "2.1.3" + graphs: + dependency: transitive + description: + name: graphs + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + hooks: + dependency: transitive + description: + name: hooks + sha256: "025f060e86d2d4c3c47b56e33caf7f93bf9283340f26d23424ebcfccf34f621e" + url: "https://pub.dev" + source: hosted + version: "1.0.3" + http: + dependency: transitive + description: + name: http + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" + url: "https://pub.dev" + source: hosted + version: "1.6.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + url: "https://pub.dev" + source: hosted + version: "3.2.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" + image: + dependency: transitive + description: + name: image + sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce + url: "https://pub.dev" + source: hosted + version: "4.8.0" + intl: + dependency: transitive + description: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.dev" + source: hosted + version: "0.20.2" + io: + dependency: transitive + description: + name: io + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + url: "https://pub.dev" + source: hosted + version: "1.0.5" + jni: + dependency: transitive + description: + name: jni + sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f + url: "https://pub.dev" + source: hosted + version: "1.0.0" + jni_flutter: + dependency: transitive + description: + name: jni_flutter + sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8 + url: "https://pub.dev" + source: hosted + version: "4.11.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + url: "https://pub.dev" + source: hosted + version: "11.0.2" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + lints: + dependency: transitive + description: + name: lints + sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df" + url: "https://pub.dev" + source: hosted + version: "6.1.0" + local_auth: + dependency: "direct main" + description: + name: local_auth + sha256: ae6f382f638108c6becd134318d7c3f0a93875383a54010f61d7c97ac05d5137 + url: "https://pub.dev" + source: hosted + version: "3.0.1" + local_auth_android: + dependency: transitive + description: + name: local_auth_android + sha256: b201c006fa769c23386f89aa6837ec0eb8179fcfb212eadcf87b422b3f9a6a78 + url: "https://pub.dev" + source: hosted + version: "2.0.8" + local_auth_darwin: + dependency: transitive + description: + name: local_auth_darwin + sha256: a8c3d4e17454111f7fd31ff72a31222359f6059f7fe956c2dcfe0f88f49826d4 + url: "https://pub.dev" + source: hosted + version: "2.0.3" + local_auth_platform_interface: + dependency: transitive + description: + name: local_auth_platform_interface + sha256: f98b8e388588583d3f781f6806e4f4c9f9e189d898d27f0c249b93a1973dd122 + url: "https://pub.dev" + source: hosted + version: "1.1.0" + local_auth_windows: + dependency: transitive + description: + name: local_auth_windows + sha256: be12c5b8ba5e64896983123655c5f67d2484ecfcc95e367952ad6e3bff94cb16 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + markdown: + dependency: transitive + description: + name: markdown + sha256: ee85086ad7698b42522c6ad42fe195f1b9898e4d974a1af4576c1a3a176cada9 + url: "https://pub.dev" + source: hosted + version: "7.3.1" + matcher: + dependency: transitive + description: + name: matcher + sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 + url: "https://pub.dev" + source: hosted + version: "0.12.19" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + url: "https://pub.dev" + source: hosted + version: "0.13.0" + meta: + dependency: transitive + description: + name: meta + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + url: "https://pub.dev" + source: hosted + version: "1.17.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + native_toolchain_c: + dependency: transitive + description: + name: native_toolchain_c + sha256: "6ba77bb18063eebe9de401f5e6437e95e1438af0a87a3a39084fbd37c90df572" + url: "https://pub.dev" + source: hosted + version: "0.17.6" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + objective_c: + dependency: transitive + description: + name: objective_c + sha256: "100a1c87616ab6ed41ec263b083c0ef3261ee6cd1dc3b0f35f8ddfa4f996fe52" + url: "https://pub.dev" + source: hosted + version: "9.3.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + url: "https://pub.dev" + source: hosted + version: "2.2.0" + path: + dependency: "direct main" + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd" + url: "https://pub.dev" + source: hosted + version: "2.3.1" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699" + url: "https://pub.dev" + source: hosted + version: "2.6.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + pdf: + dependency: "direct main" + description: + name: pdf + sha256: e47a275b267873d5944ad5f5ff0dcc7ac2e36c02b3046a0ffac9b72fd362c44b + url: "https://pub.dev" + source: hosted + version: "3.12.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675" + url: "https://pub.dev" + source: hosted + version: "7.0.2" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + pool: + dependency: transitive + description: + name: pool + sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" + url: "https://pub.dev" + source: hosted + version: "1.5.2" + posix: + dependency: transitive + description: + name: posix + sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07" + url: "https://pub.dev" + source: hosted + version: "6.5.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" + url: "https://pub.dev" + source: hosted + version: "1.5.0" + qr: + dependency: transitive + description: + name: qr + sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + recase: + dependency: transitive + description: + name: recase + sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 + url: "https://pub.dev" + source: hosted + version: "4.1.0" + record_use: + dependency: transitive + description: + name: record_use + sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed" + url: "https://pub.dev" + source: hosted + version: "0.6.0" + riverpod: + dependency: transitive + description: + name: riverpod + sha256: "8c22216be8ad3ef2b44af3a329693558c98eca7b8bd4ef495c92db0bba279f83" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + share_plus: + dependency: "direct main" + description: + name: share_plus + sha256: a857d8b1479250aff6b57a51b2c02d31ca05848d441817c43f1640c885c286c0 + url: "https://pub.dev" + source: hosted + version: "13.1.0" + share_plus_platform_interface: + dependency: transitive + description: + name: share_plus_platform_interface + sha256: "7f7ae28cf400d13f811e297ff37742dba83b79e0a6f5dce14eec0248274e6ce9" + url: "https://pub.dev" + source: hosted + version: "7.1.0" + shelf: + dependency: transitive + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.dev" + source: hosted + version: "1.4.2" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + shelf_static: + dependency: transitive + description: + name: shelf_static + sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 + url: "https://pub.dev" + source: hosted + version: "1.1.3" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "732792cfd197d2161a65bb029606a46e0a18ff30ef9e141a7a82172b05ea8ecd" + url: "https://pub.dev" + source: hosted + version: "4.2.2" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" + url: "https://pub.dev" + source: hosted + version: "0.10.13" + source_span: + dependency: transitive + description: + name: source_span + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" + url: "https://pub.dev" + source: hosted + version: "1.10.2" + sqlcipher_flutter_libs: + dependency: transitive + description: + name: sqlcipher_flutter_libs + sha256: "38d62d659d2fb8739bf25a42c9a350d1fdd6c29a5a61f13a946778ec75d27929" + url: "https://pub.dev" + source: hosted + version: "0.7.0+eol" + sqlite3: + dependency: transitive + description: + name: sqlite3 + sha256: "56da3e13ed7d28a66f930aa2b2b29db6736a233f08283326e96321dd812030f5" + url: "https://pub.dev" + source: hosted + version: "3.3.1" + sqlite3_flutter_libs: + dependency: "direct main" + description: + name: sqlite3_flutter_libs + sha256: "3ed7553eee7bb368f8950f58ba29f634e06e813c029aff6a0d60862b96de8454" + url: "https://pub.dev" + source: hosted + version: "0.6.0+eol" + sqlparser: + dependency: transitive + description: + name: sqlparser + sha256: ab2b467425f1d4f3acfa5fd11a08226f7d6c26ff102c06be1807e1dff34e050b + url: "https://pub.dev" + source: hosted + version: "0.44.3" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.dev" + source: hosted + version: "1.12.1" + state_notifier: + dependency: transitive + description: + name: state_notifier + sha256: b8677376aa54f2d7c58280d5a007f9e8774f1968d1fb1c096adcb4792fba29bb + url: "https://pub.dev" + source: hosted + version: "1.0.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + url: "https://pub.dev" + source: hosted + version: "2.1.1" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test: + dependency: transitive + description: + name: test + sha256: "280d6d890011ca966ad08df7e8a4ddfab0fb3aa49f96ed6de56e3521347a9ae7" + url: "https://pub.dev" + source: hosted + version: "1.30.0" + test_api: + dependency: transitive + description: + name: test_api + sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" + url: "https://pub.dev" + source: hosted + version: "0.7.10" + test_core: + dependency: transitive + description: + name: test_core + sha256: "0381bd1585d1a924763c308100f2138205252fb90c9d4eeaf28489ee65ccde51" + url: "https://pub.dev" + source: hosted + version: "0.6.16" + timezone: + dependency: transitive + description: + name: timezone + sha256: "784a5e34d2eb62e1326f24d6f600aaaee452eb8ca8ef2f384a59244e292d158b" + url: "https://pub.dev" + source: hosted + version: "0.11.0" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a + url: "https://pub.dev" + source: hosted + version: "3.2.2" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f + url: "https://pub.dev" + source: hosted + version: "2.4.2" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" + url: "https://pub.dev" + source: hosted + version: "3.1.5" + uuid: + dependency: transitive + description: + name: uuid + sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489" + url: "https://pub.dev" + source: hosted + version: "4.5.3" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + url: "https://pub.dev" + source: hosted + version: "2.2.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "046d3928e16fa4dc46e8350415661755ab759d9fc97fc21b5ab295f71e4f0499" + url: "https://pub.dev" + source: hosted + version: "15.1.0" + watcher: + dependency: transitive + description: + name: watcher + sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 + url: "https://pub.dev" + source: hosted + version: "3.0.3" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + win32: + dependency: transitive + description: + name: win32 + sha256: ba7d5750e3441caa1bbe31d9e516348fcf8dfcb32aa29ef87a844a59f4d1f1d0 + url: "https://pub.dev" + source: hosted + version: "6.1.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + url: "https://pub.dev" + source: hosted + version: "6.6.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" +sdks: + dart: ">=3.10.3 <4.0.0" + flutter: ">=3.38.4" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..f3410d7 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,105 @@ +name: dailyou +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 + +environment: + sdk: '>=3.3.0 <4.0.0' + +dependencies: + crypto: ^3.0.5 + flutter: + sdk: flutter + + # State management + flutter_riverpod: ^3.3.1 + + # Database + drift: ^2.32.1 + drift_flutter: ^0.3.0 + sqlite3_flutter_libs: ^0.6.0 + path_provider: ^2.1.5 + path: ^1.9.0 + + # Charts + fl_chart: ^1.2.0 + + # On-device LLM + flutter_mediapipe_chat: ^1.0.0 + + # Markdown rendering + flutter_markdown_plus: ^1.0.0 + + # Reminders + flutter_local_notifications: ^21.0.0 + + # Export & share + pdf: ^3.11.1 + share_plus: ^13.1.0 + + # Biometric lock + local_auth: ^3.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^6.0.0 + build_runner: ^2.4.11 + drift_dev: ^2.32.0 + +# 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 diff --git a/web/favicon.png b/web/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/web/favicon.png differ diff --git a/web/icons/Icon-192.png b/web/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/web/icons/Icon-192.png differ diff --git a/web/icons/Icon-512.png b/web/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/web/icons/Icon-512.png differ diff --git a/web/icons/Icon-maskable-192.png b/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000..eb9b4d7 Binary files /dev/null and b/web/icons/Icon-maskable-192.png differ diff --git a/web/icons/Icon-maskable-512.png b/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000..d69c566 Binary files /dev/null and b/web/icons/Icon-maskable-512.png differ diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..5a7d0b5 --- /dev/null +++ b/web/index.html @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + dailyou + + + + + + + diff --git a/web/manifest.json b/web/manifest.json new file mode 100644 index 0000000..ac826b2 --- /dev/null +++ b/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "dailyou", + "short_name": "dailyou", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/windows/.gitignore b/windows/.gitignore new file mode 100644 index 0000000..d492d0d --- /dev/null +++ b/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt new file mode 100644 index 0000000..cce92c0 --- /dev/null +++ b/windows/CMakeLists.txt @@ -0,0 +1,108 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.14) +project(dailyou LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "dailyou") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(VERSION 3.14...3.25) + +# Define build configuration option. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() +# Define settings for the Profile build mode. +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/windows/flutter/CMakeLists.txt b/windows/flutter/CMakeLists.txt new file mode 100644 index 0000000..903f489 --- /dev/null +++ b/windows/flutter/CMakeLists.txt @@ -0,0 +1,109 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# Set fallback configurations for older versions of the flutter tool. +if (NOT DEFINED FLUTTER_TARGET_PLATFORM) + set(FLUTTER_TARGET_PLATFORM "windows-x64") +endif() + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + ${FLUTTER_TARGET_PLATFORM} $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..8b6d468 --- /dev/null +++ b/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,11 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + + +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/windows/flutter/generated_plugin_registrant.h b/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..dc139d8 --- /dev/null +++ b/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake new file mode 100644 index 0000000..b93c4c3 --- /dev/null +++ b/windows/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/windows/runner/CMakeLists.txt b/windows/runner/CMakeLists.txt new file mode 100644 index 0000000..394917c --- /dev/null +++ b/windows/runner/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the build version. +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") + +# Disable Windows macros that collide with C++ standard library functions. +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") + +# Add dependency libraries and include directories. Add any application-specific +# dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc new file mode 100644 index 0000000..bfd5cf0 --- /dev/null +++ b/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) +#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD +#else +#define VERSION_AS_NUMBER 1,0,0,0 +#endif + +#if defined(FLUTTER_VERSION) +#define VERSION_AS_STRING FLUTTER_VERSION +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.example" "\0" + VALUE "FileDescription", "dailyou" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "dailyou" "\0" + VALUE "LegalCopyright", "Copyright (C) 2026 com.example. All rights reserved." "\0" + VALUE "OriginalFilename", "dailyou.exe" "\0" + VALUE "ProductName", "dailyou" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/windows/runner/flutter_window.cpp b/windows/runner/flutter_window.cpp new file mode 100644 index 0000000..955ee30 --- /dev/null +++ b/windows/runner/flutter_window.cpp @@ -0,0 +1,71 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + + flutter_controller_->engine()->SetNextFrameCallback([&]() { + this->Show(); + }); + + // Flutter can complete the first frame before the "show window" callback is + // registered. The following call ensures a frame is pending to ensure the + // window is shown. It is a no-op if the first frame hasn't completed yet. + flutter_controller_->ForceRedraw(); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/windows/runner/flutter_window.h b/windows/runner/flutter_window.h new file mode 100644 index 0000000..6da0652 --- /dev/null +++ b/windows/runner/flutter_window.h @@ -0,0 +1,33 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp new file mode 100644 index 0000000..7687e8f --- /dev/null +++ b/windows/runner/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.Create(L"dailyou", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/windows/runner/resource.h b/windows/runner/resource.h new file mode 100644 index 0000000..66a65d1 --- /dev/null +++ b/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/windows/runner/resources/app_icon.ico b/windows/runner/resources/app_icon.ico new file mode 100644 index 0000000..c04e20c Binary files /dev/null and b/windows/runner/resources/app_icon.ico differ diff --git a/windows/runner/runner.exe.manifest b/windows/runner/runner.exe.manifest new file mode 100644 index 0000000..153653e --- /dev/null +++ b/windows/runner/runner.exe.manifest @@ -0,0 +1,14 @@ + + + + + PerMonitorV2 + + + + + + + + + diff --git a/windows/runner/utils.cpp b/windows/runner/utils.cpp new file mode 100644 index 0000000..3a0b465 --- /dev/null +++ b/windows/runner/utils.cpp @@ -0,0 +1,65 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + unsigned int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr) + -1; // remove the trailing null character + int input_length = (int)wcslen(utf16_string); + std::string utf8_string; + if (target_length == 0 || target_length > utf8_string.max_size()) { + return utf8_string; + } + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + input_length, utf8_string.data(), target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/windows/runner/utils.h b/windows/runner/utils.h new file mode 100644 index 0000000..3879d54 --- /dev/null +++ b/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/windows/runner/win32_window.cpp b/windows/runner/win32_window.cpp new file mode 100644 index 0000000..60608d0 --- /dev/null +++ b/windows/runner/win32_window.cpp @@ -0,0 +1,288 @@ +#include "win32_window.h" + +#include +#include + +#include "resource.h" + +namespace { + +/// Window attribute that enables dark mode window decorations. +/// +/// Redefined in case the developer's machine has a Windows SDK older than +/// version 10.0.22000.0. +/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +/// Registry key for app theme preference. +/// +/// A value of 0 indicates apps should use dark mode. A non-zero or missing +/// value indicates apps should use light mode. +constexpr const wchar_t kGetPreferredBrightnessRegKey[] = + L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; +constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + } + FreeLibrary(user32_module); +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registrar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::Create(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + UpdateTheme(window); + + return OnCreate(); +} + +bool Win32Window::Show() { + return ShowWindow(window_handle_, SW_SHOWNORMAL); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + + case WM_DWMCOLORIZATIONCOLORCHANGED: + UpdateTheme(hwnd); + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} + +void Win32Window::UpdateTheme(HWND const window) { + DWORD light_mode; + DWORD light_mode_size = sizeof(light_mode); + LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, + kGetPreferredBrightnessRegValue, + RRF_RT_REG_DWORD, nullptr, &light_mode, + &light_mode_size); + + if (result == ERROR_SUCCESS) { + BOOL enable_dark_mode = light_mode == 0; + DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, + &enable_dark_mode, sizeof(enable_dark_mode)); + } +} diff --git a/windows/runner/win32_window.h b/windows/runner/win32_window.h new file mode 100644 index 0000000..e901dde --- /dev/null +++ b/windows/runner/win32_window.h @@ -0,0 +1,102 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates a win32 window with |title| that is positioned and sized using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size this function will scale the inputted width and height as + // as appropriate for the default monitor. The window is invisible until + // |Show| is called. Returns true if the window was created successfully. + bool Create(const std::wstring& title, const Point& origin, const Size& size); + + // Show the current window. Returns true if the window was successfully shown. + bool Show(); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + // Update the window frame's theme to match the system theme. + static void UpdateTheme(HWND const window); + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_