From 94d204e8e8845228fafcdd63631464c8ddb4385e Mon Sep 17 00:00:00 2001 From: SomnusVeritas Date: Mon, 6 Nov 2023 16:52:51 +0100 Subject: [PATCH 01/10] added gitignore and cleaned up repo --- .gitignore | 846 ++++++++++++++++++- linux/flutter/CMakeLists.txt | 88 -- linux/flutter/generated_plugin_registrant.cc | 11 - linux/flutter/generated_plugin_registrant.h | 15 - linux/flutter/generated_plugins.cmake | 23 - pubspec.lock | 205 ----- 6 files changed, 834 insertions(+), 354 deletions(-) delete mode 100644 linux/flutter/CMakeLists.txt delete mode 100644 linux/flutter/generated_plugin_registrant.cc delete mode 100644 linux/flutter/generated_plugin_registrant.h delete mode 100644 linux/flutter/generated_plugins.cmake delete mode 100644 pubspec.lock diff --git a/.gitignore b/.gitignore index 24476c5..580259d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ + # Miscellaneous *.class +*.lock *.log *.pyc *.swp @@ -8,7 +10,6 @@ .buildlog/ .history .svn/ -migrate_working_dir/ # IntelliJ related *.iml @@ -16,29 +17,850 @@ migrate_working_dir/ *.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/ +# Visual Studio Code related +.classpath +.project +.settings/ +.vscode/ + +# Flutter repo-specific +/bin/cache/ +/bin/internal/bootstrap.bat +/bin/internal/bootstrap.sh +/bin/mingit/ +/dev/benchmarks/mega_gallery/ +/dev/bots/.recipe_deps +/dev/bots/android_tools/ +/dev/devicelab/ABresults*.json +/dev/docs/doc/ +/dev/docs/flutter.docs.zip +/dev/docs/lib/ +/dev/docs/pubspec.yaml +/dev/integration_tests/**/xcuserdata +/dev/integration_tests/**/Pods +/packages/flutter/coverage/ +version +analysis_benchmark.json + +# packages file containing multi-root paths +.packages.generated # Flutter/Dart/Pub related **/doc/api/ -**/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies +**/generated_plugin_registrant.dart .packages .pub-cache/ .pub/ -/build/ +build/ +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds -# Symbolication related +# Android related +**/android/**/gradle-wrapper.jar +.gradle/ +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java +**/android/key.properties +# *.jks + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# macOS +**/macos/Flutter/GeneratedPluginRegistrant.swift + +# Coverage +coverage/ + +# Symbols app.*.symbols +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +!/dev/ci/**/Gemfile.lock + + +## Related .gitignores ## + +# Firebase configuration files / Google Services (e.g. APIs or Firebase) +ios/Runner/GoogleService-Info.plist +android/app/google-services.json + +# Google Maps API +google_maps_api.xml + +# Web related +lib/generated_plugin_registrant.dart + # Obfuscation related app.*.map.json -# Android Studio will place build artifacts here -/android/app/debug -/android/app/profile -/android/app/release + +### --------------------------- Dart.gitignore ------------------------- ### + +# See https://www.dartlang.org/guides/libraries/private-files + +# Files and directories created by pub +#.dart_tool/ +#.packages +#build/ +# If you're building an application, you may want to check-in your pubspec.lock +#pubspec.lock + +# Directory created by dartdoc +# If you don't generate documentation locally you can remove this line. +doc/api/ + +# dotenv environment variables file +.env* + +# Avoid committing generated Javascript files: +*.dart.js +*.info.json # Produced by the --dump-info flag. +*.js # When generated by dart2js. Don't specify *.js if your + # project includes source files written in JavaScript. +*.js_ +*.js.deps +*.js.map + +#.flutter-plugins +#.flutter-plugins-dependencies + + +### -------------------------- Swift.gitignore ------------------------ ### + +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings +#xcuserdata/ + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +#*.xcscmblueprint +#*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +#build/ +#DerivedData/ +#*.moved-aside +#*.pbxuser +#!default.pbxuser +#*.mode1v3 +#!default.mode1v3 +#*.mode2v3 +#!default.mode2v3 +#*.perspectivev3 +#!default.perspectivev3 + +## Obj-C/Swift specific +*.hmap + +## App packaging +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager + +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. + Packages/ + Package.pins + Package.resolved + *.xcodeproj + +# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata +# hence it is not needed unless you have added a package configuration file to your project + .swiftpm + +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ +# +# Add this line if you want to avoid checking in source code from the Xcode workspace +# *.xcworkspace + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build/ + +# Accio dependency management +Dependencies/ +.accio/ + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. +# Instead, use fastlane to re-generate the screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output + +# Code Injection +# +# After new code Injection tools there's a generated folder /iOSInjectionProject +# https://github.com/johnno1962/injectionforxcode + +iOSInjectionProject/ + + +### -------------------------- Java.gitignore -------------------------- ### + +# Compiled class file +#*.class + +# Log file +#*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +#*.jar +*.war +*.nar +*.ear +#*.zip +*.tar.gz +#*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + + +### -------------------------- Kotlin.gitignore ------------------------ ### + +#.DS_Store +.idea/shelf +/confluence/target +/dependencies/repo +/android.tests.dependencies +/dependencies/android.tests.dependencies +/dist +/local +/gh-pages +/ideaSDK +/clionSDK +/android-studio/sdk +#out/ +/tmp +/intellij +workspace.xml +*.versionsBackup +/idea/testData/debugger/tinyApp/classes* +/jps-plugin/testData/kannotator +/js/js.translator/testData/out/ +/js/js.translator/testData/out-min/ +/js/js.translator/testData/out-pir/ +#.gradle/ +#build/ +!**/src/**/build +!**/test/**/build +#*.iml +!**/testData/**/*.iml +.idea/remote-targets.xml +.idea/libraries/Gradle*.xml +.idea/libraries/Maven*.xml +.idea/artifacts/PILL_*.xml +.idea/artifacts/KotlinPlugin.xml +#.idea/modules +.idea/runConfigurations/JPS_*.xml +.idea/runConfigurations/PILL_*.xml +.idea/runConfigurations/_FP_*.xml +.idea/runConfigurations/_MT_*.xml +#.idea/libraries +#.idea/modules.xml +#.idea/gradle.xml +#.idea/compiler.xml +.idea/inspectionProfiles/profiles_settings.xml +.idea/.name +.idea/artifacts/dist_auto_* +.idea/artifacts/dist.xml +.idea/artifacts/ideaPlugin.xml +.idea/artifacts/kotlinc.xml +.idea/artifacts/kotlin_compiler_jar.xml +.idea/artifacts/kotlin_plugin_jar.xml +.idea/artifacts/kotlin_jps_plugin_jar.xml +.idea/artifacts/kotlin_daemon_client_jar.xml +.idea/artifacts/kotlin_imports_dumper_compiler_plugin_jar.xml +.idea/artifacts/kotlin_main_kts_jar.xml +.idea/artifacts/kotlin_compiler_client_embeddable_jar.xml +.idea/artifacts/kotlin_reflect_jar.xml +.idea/artifacts/kotlin_stdlib_js_ir_* +.idea/artifacts/kotlin_test_js_ir_* +.idea/artifacts/kotlin_stdlib_wasm_* +.idea/artifacts/kotlinx_atomicfu_runtime_* +#.idea/jarRepositories.xml +.idea/csv-plugin.xml +.idea/libraries-with-intellij-classes.xml +.idea/misc.xml +node_modules/ +.rpt2_cache/ +libraries/tools/kotlin-test-js-runner/lib/ +#local.properties +buildSrcTmp/ +distTmp/ +outTmp/ +/test.output +/kotlin-native/dist +kotlin-ide/ + + +### ------------------------- Android.gitignore ------------------------ ### + +# Built application files +*.apk +*.ap_ + +# Files for the ART/Dalvik VM +*.dex + +# Generated files +bin/ +gen/ +out/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +.idea/caches + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +#fastlane/report.xml +#fastlane/Preview.html +fastlane/screenshots +#fastlane/test_output +fastlane/readme.md + +# Keystore files +*.jks +*.keystore + + +### ------------------------- Gradle.gitignore ------------------------- ### + +.gradle +**/build/ +!src/**/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# Eclipse Gradle plugin generated files +# Eclipse Core +#.project +# JDT-specific (Eclipse Java Development Tools) +#.classpath + + +### ------------------------- Maven.gitignore -------------------------- ### + +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +# https://github.com/takari/maven-wrapper#usage-without-binary-jar +.mvn/wrapper/maven-wrapper.jar + +# Eclipse m2e generated files +# Eclipse Core +#.project +# JDT-specific (Eclipse Java Development Tools) +#.classpath + + +### ------------------------ JetBrains.gitignore ----------------------- ### + +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. + .idea/artifacts + .idea/compiler.xml + .idea/jarRepositories.xml + .idea/modules.xml + .idea/*.iml + .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +#*.iws + +# IntelliJ +#out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + + +### ------------------------- Xcode.gitignore -------------------------- ### + +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings +xcuserdata/ + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +#build/ +DerivedData/ +*.moved-aside +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 + +## Gcc Patch +/*.gcno + + +### -------------------- VisualStudioCode.gitignore ------------------- ### + +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + + +### ----------------------- SublimeText.gitignore ---------------------- ### + +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are user-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +# *.sublime-project + +# SFTP configuration file +sftp-config.json +sftp-config-alt*.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.user-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings + + +### -------------------------- Emacs.gitignore ------------------------- ### + +# -*- mode: gitignore; -*- +#*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + + +### -------------------------- Vim.gitignore -------------------------- ### + +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +#*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + + +### ------------------------ Windows.gitignore ------------------------ ### + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + + +### ------------------------- macOS.gitignore -------------------------- ### + +# General +#.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + + +### -------------------------- Linux.gitignore ------------------------- ### + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + + +### ------------------------ Archives.gitignore ------------------------ ### + +# It's better to unpack these files and commit the raw source because +# git has its own built in compression methods. +*.7z +*.jar +*.rar +*.zip +*.gz +*.gzip +*.tgz +*.bzip +*.bzip2 +*.bz2 +*.xz +*.lzma +#*.cab +*.xar + +# Packing-only formats +*.iso +*.tar + +# Package management formats +*.dmg +*.xpi +*.gem +*.egg +*.deb +*.rpm +#*.msi +#*.msm +#*.msp +*.txz + + +### ------------------------- Backup.gitignore ------------------------- ### + +*.bak +*.gho +*.ori +*.orig +*.tmp + + +### -------------------------- JEnv.gitignore -------------------------- ### + +# JEnv local Java version configuration file +.java-version + +# Used by previous versions of JEnv +.jenv-version + + +### ------------------------- Project Specific ------------------------- ### + +# Include any specific files here. +linux/flutter/generated_plugin_registrant.cc +linux/flutter/generated_plugin_registrant.h +linux/flutter/generated_plugins.cmake +linux/flutter/CMakeLists.txt + + +### ---------------------------- References ---------------------------- ### + +# Flutter - https://github.com/flutter/flutter/blob/master/.gitignore +# Dart - https://github.com/github/gitignore/blob/main/Dart.gitignore +# Swift - https://github.com/github/gitignore/blob/main/Swift.gitignore +# Java - https://github.com/github/gitignore/blob/main/Java.gitignore +# Kotlin - https://github.com/JetBrains/kotlin/blob/master/.gitignore +# Android - https://github.com/github/gitignore/blob/main/Android.gitignore +# Gradle - https://github.com/github/gitignore/blob/main/Gradle.gitignore +# Maven - https://github.com/github/gitignore/blob/main/Maven.gitignore + +# JetBrains - https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# Xcode - https://github.com/github/gitignore/blob/main/Global/Xcode.gitignore +# VisualStudioCode - https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore +# SublimeText - https://github.com/github/gitignore/blob/main/Global/SublimeText.gitignore +# Emacs - https://github.com/github/gitignore/blob/main/Global/Emacs.gitignore +# Vim - https://github.com/github/gitignore/blob/main/Global/Vim.gitignore + +# Windows - https://github.com/github/gitignore/blob/main/Global/Windows.gitignore +# macOS - https://github.com/github/gitignore/blob/main/Global/macOS.gitignore +# Linux - https://github.com/github/gitignore/blob/main/Global/Linux.gitignore + +# Archives - https://github.com/github/gitignore/blob/main/Global/Archives.gitignore +# Backup - https://github.com/github/gitignore/blob/main/Global/Backup.gitignore +# JEnv - https://github.com/github/gitignore/blob/main/Global/JEnv.gitignore \ No newline at end of file diff --git a/linux/flutter/CMakeLists.txt b/linux/flutter/CMakeLists.txt deleted file mode 100644 index d5bd016..0000000 --- a/linux/flutter/CMakeLists.txt +++ /dev/null @@ -1,88 +0,0 @@ -# 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 deleted file mode 100644 index e71a16d..0000000 --- a/linux/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,11 +0,0 @@ -// -// 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 deleted file mode 100644 index e0f0a47..0000000 --- a/linux/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// 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 deleted file mode 100644 index 2e1de87..0000000 --- a/linux/flutter/generated_plugins.cmake +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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/pubspec.lock b/pubspec.lock deleted file mode 100644 index 5bec6c9..0000000 --- a/pubspec.lock +++ /dev/null @@ -1,205 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" - source: hosted - version: "2.11.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - characters: - dependency: transitive - description: - name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" - source: hosted - version: "1.3.0" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - collection: - dependency: transitive - description: - name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 - url: "https://pub.dev" - source: hosted - version: "1.17.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d - url: "https://pub.dev" - source: hosted - version: "1.0.6" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 - url: "https://pub.dev" - source: hosted - version: "2.0.3" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - lints: - dependency: transitive - description: - name: lints - sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - matcher: - dependency: transitive - description: - name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" - url: "https://pub.dev" - source: hosted - version: "0.12.16" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" - url: "https://pub.dev" - source: hosted - version: "0.5.0" - meta: - dependency: transitive - description: - name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" - url: "https://pub.dev" - source: hosted - version: "1.9.1" - nested: - dependency: transitive - description: - name: nested - sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - path: - dependency: transitive - description: - name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" - url: "https://pub.dev" - source: hosted - version: "1.8.3" - provider: - dependency: "direct main" - description: - name: provider - sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f - url: "https://pub.dev" - source: hosted - version: "6.0.5" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" - source: hosted - version: "1.10.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 - url: "https://pub.dev" - source: hosted - version: "1.11.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" - url: "https://pub.dev" - source: hosted - version: "0.6.0" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - web: - dependency: transitive - description: - name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 - url: "https://pub.dev" - source: hosted - version: "0.1.4-beta" -sdks: - dart: ">=3.1.0 <4.0.0" - flutter: ">=1.16.0" From da4dc831930afacbf17403c1f6edf63925c31260 Mon Sep 17 00:00:00 2001 From: SomnusVeritas Date: Mon, 6 Nov 2023 16:53:07 +0100 Subject: [PATCH 02/10] added dependencies for Hive --- pubspec.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index c1da76d..71cc39f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,8 +10,10 @@ dependencies: flutter: sdk: flutter - cupertino_icons: ^1.0.2 provider: ^6.0.5 + hive: ^4.0.0-dev.2 + isar_flutter_libs: ^4.0.0-dev.13 + path_provider: ^2.1.0 dev_dependencies: flutter_test: From d1da47499811fb5dbad14ecf0f6b8c173bb02445 Mon Sep 17 00:00:00 2001 From: SomnusVeritas Date: Mon, 6 Nov 2023 18:19:52 +0100 Subject: [PATCH 03/10] barely functional database with hive --- android/app/build.gradle | 2 +- lib/main.dart | 5 +++- lib/models/cooking_step.dart | 10 +++++++ lib/models/ingredient.dart | 15 ++++++++++ lib/models/ingredient_list_entry.dart | 15 ++++++++++ lib/models/recipe.dart | 28 ++++++++++++++++-- lib/models/unit.dart | 12 ++++++++ lib/services/providers/db/dbhelper.dart | 29 +++++++++++++++++++ .../providers/recipe_list_provider.dart | 3 +- 9 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 lib/services/providers/db/dbhelper.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index 145f023..a4dd702 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -45,7 +45,7 @@ android { applicationId "com.example.rezepte" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion flutter.minSdkVersion + minSdkVersion 23 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/lib/main.dart b/lib/main.dart index 491726d..d625ea2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,9 +6,12 @@ import 'package:rezepte/services/providers/recipe_list_provider.dart'; import 'package:rezepte/services/providers/recipe_provider.dart'; import 'pages/recipe_detail_page.dart'; +import 'services/providers/db/dbhelper.dart'; import 'theme.dart'; -void main() { +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await DbHelper.init(); runApp(MultiProvider(providers: [ ChangeNotifierProvider( create: (_) => RecipeListProvider(), diff --git a/lib/models/cooking_step.dart b/lib/models/cooking_step.dart index a1258f2..df8e549 100644 --- a/lib/models/cooking_step.dart +++ b/lib/models/cooking_step.dart @@ -3,4 +3,14 @@ class CookingStep { final String description; CookingStep({required this.title, this.description = ''}); + + factory CookingStep.fromJson(Map json) => CookingStep( + title: json['title'] as String, + description: json['description'] as String, + ); + + Map toJson() => { + 'title': title, + 'description': description, + }; } diff --git a/lib/models/ingredient.dart b/lib/models/ingredient.dart index 4870f13..d7244ba 100644 --- a/lib/models/ingredient.dart +++ b/lib/models/ingredient.dart @@ -11,6 +11,18 @@ class Ingredient { this.preferredBrands = const [], }); + factory Ingredient.fromJson(Map json) => Ingredient( + title: json['title'] as String, + possibleUnits: _unitsFromJson(json['possibleUnits']), + preferredBrands: json['preferredBrands'] as List, + ); + + Map toJson() => { + 'title': title, + 'possibleUnits': possibleUnits.map((e) => e.toJson()).toList(), + 'preferredBrands': preferredBrands, + }; + @override bool operator ==(other) { Ingredient i = other as Ingredient; @@ -21,4 +33,7 @@ class Ingredient { int get hashCode { return Object.hash(title, null); } + + static List _unitsFromJson(List> jsonList) => + jsonList.map((e) => Unit.fromJson(e)).toList(); } diff --git a/lib/models/ingredient_list_entry.dart b/lib/models/ingredient_list_entry.dart index ccb5531..03888f1 100644 --- a/lib/models/ingredient_list_entry.dart +++ b/lib/models/ingredient_list_entry.dart @@ -9,6 +9,21 @@ class IngredientListEntry { IngredientListEntry(this.ingredient, this.amount, this.unit, this.optional); + factory IngredientListEntry.fromJson(Map json) => + IngredientListEntry( + Ingredient.fromJson(json['ingredient']), + json['amount'] as int, + Unit.fromJson(json['unit']), + json['optional'] as bool, + ); + + Map toJson() => { + 'ingredient': ingredient.toJson(), + 'amount': amount, + 'unit': unit.toJson(), + 'optional': optional, + }; + @override operator ==(Object other) { final i = other as IngredientListEntry; diff --git a/lib/models/recipe.dart b/lib/models/recipe.dart index 69ccaf0..d8485f4 100644 --- a/lib/models/recipe.dart +++ b/lib/models/recipe.dart @@ -6,8 +6,8 @@ class Recipe { String title; String description; Difficulty? difficulty; - final List ingredients = []; - final List steps = []; + List ingredients = []; + List steps = []; Recipe({ required this.title, @@ -15,6 +15,23 @@ class Recipe { this.difficulty, }); + factory Recipe.fromJson(json) => Recipe( + title: json['title'] as String, + description: json['description'] as String, + // difficulty: json['difficulty'] as Difficulty?, + ); + // ..ingredients = _ingredientsFromMap( + // json['ingredients'] as List>) + // ..steps = _stepsFromMap(json['steps']); + + Map toJson() => { + 'title': title, + 'description': description, + // 'difficulty': difficulty, + // 'ingredients': ingredients.map((e) => e.toJson()).toList(), + // 'steps': steps.map((e) => e.toJson()).toList(), + }; + void addIngredient(IngredientListEntry ingredient) => ingredients.add(ingredient); @@ -51,4 +68,11 @@ class Recipe { ingredients.clear(); steps.clear(); } + + static List _ingredientsFromMap( + List> jsonList) => + jsonList.map((e) => IngredientListEntry.fromJson(e)).toList(); + + static List _stepsFromMap(List> jsonList) => + jsonList.map((e) => CookingStep.fromJson(e)).toList(); } diff --git a/lib/models/unit.dart b/lib/models/unit.dart index eb584ab..e287460 100644 --- a/lib/models/unit.dart +++ b/lib/models/unit.dart @@ -4,6 +4,18 @@ class Unit { final System system; Unit(this.name, this.type, {this.system = System.metric}); + + factory Unit.fromJson(Map json) => Unit( + json['name'] as String, + json['type'] as UnitType, + system: json['system'] as System, + ); + + Map toJson() => { + 'name': name, + 'type': type, + 'system': system, + }; } enum System { metric, imperial, neutral } diff --git a/lib/services/providers/db/dbhelper.dart b/lib/services/providers/db/dbhelper.dart new file mode 100644 index 0000000..2169b08 --- /dev/null +++ b/lib/services/providers/db/dbhelper.dart @@ -0,0 +1,29 @@ +import 'package:hive/hive.dart'; +import 'package:path_provider/path_provider.dart'; + +import '../../../models/recipe.dart'; +import '../../../example_data.dart' as e; + +class DbHelper { + static Box get _recipesBox => Hive.box(name: 'recipes'); + + static Future init() async { + final dir = await getApplicationDocumentsDirectory(); + Hive.defaultDirectory = dir.path; + Hive.registerAdapter('Recipe', Recipe.fromJson); + _recipesBox.clear(); + for (final recipe in e.exampleRecipes) { + insertRecipe(recipe); + } + } + + static List fetchRecipes() { + List recipes = _recipesBox.getAll(['0', '1']).cast(); + + return recipes; + } + + static void insertRecipe(Recipe recipe) { + _recipesBox.put(_recipesBox.length.toString(), recipe); + } +} diff --git a/lib/services/providers/recipe_list_provider.dart b/lib/services/providers/recipe_list_provider.dart index b400d12..ddd8f68 100644 --- a/lib/services/providers/recipe_list_provider.dart +++ b/lib/services/providers/recipe_list_provider.dart @@ -1,4 +1,5 @@ import 'package:flutter/foundation.dart'; +import 'package:rezepte/services/providers/db/dbhelper.dart'; import '../../models/recipe.dart'; import 'package:rezepte/example_data.dart' as e; @@ -12,7 +13,7 @@ class RecipeListProvider extends ChangeNotifier { notifyListeners(); } - List get recipes => _recipes; + List get recipes => DbHelper.fetchRecipes(); void clearRecipes({silent = false}) { _recipes.clear(); From 17d3a125fb6070de397cb7cac042210d4a701152 Mon Sep 17 00:00:00 2001 From: SomnusVeritas Date: Tue, 7 Nov 2023 23:24:18 +0100 Subject: [PATCH 04/10] barely working example with Isar --- .gitignore | 1 + lib/example_data.dart | 3 ++ lib/models/cooking_step.dart | 5 +++ lib/models/difficulty.dart | 2 +- lib/models/ingredient.dart | 5 +++ lib/models/ingredient_list_entry.dart | 5 +++ lib/models/recipe.dart | 35 +++++++++++------ lib/models/unit.dart | 5 +++ lib/pages/create_recipe_page.dart | 5 ++- lib/services/providers/db/dbhelper.dart | 39 +++++++++++-------- .../providers/recipe_list_provider.dart | 2 +- lib/services/providers/recipe_provider.dart | 2 +- pubspec.yaml | 3 +- 13 files changed, 78 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 580259d..def5b98 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ .buildlog/ .history .svn/ +/lib/models/*.g.dart # IntelliJ related *.iml diff --git a/lib/example_data.dart b/lib/example_data.dart index 08754e1..58958a9 100644 --- a/lib/example_data.dart +++ b/lib/example_data.dart @@ -1,5 +1,6 @@ import 'package:rezepte/models/difficulty.dart'; import 'package:rezepte/models/unit.dart'; +import 'package:rezepte/services/providers/db/dbhelper.dart'; import 'models/ingredient.dart'; import 'constants.dart' as constants; @@ -30,10 +31,12 @@ final List exampleIngredients = [ final List exampleRecipes = [ Recipe( + id: DbHelper.nextRecipeId, title: 'Wraps', description: 'Nur ein paar Wraps', difficulty: Difficulty.hard), Recipe( + id: DbHelper.nextRecipeId, title: 'Burritos', description: 'Nur ein paar Burritos', difficulty: Difficulty.easy), diff --git a/lib/models/cooking_step.dart b/lib/models/cooking_step.dart index df8e549..453d017 100644 --- a/lib/models/cooking_step.dart +++ b/lib/models/cooking_step.dart @@ -1,3 +1,8 @@ +import 'package:isar/isar.dart'; + +part 'cooking_step.g.dart'; + +@embedded class CookingStep { final String title; final String description; diff --git a/lib/models/difficulty.dart b/lib/models/difficulty.dart index 8465717..b49eca8 100644 --- a/lib/models/difficulty.dart +++ b/lib/models/difficulty.dart @@ -21,4 +21,4 @@ class DifficultyUtil { } // Only use camelCase or UpperCamelCase for names -enum Difficulty { veryEasy, easy, intermediate, hard, veryHard } +enum Difficulty { notSelected, veryEasy, easy, intermediate, hard, veryHard } diff --git a/lib/models/ingredient.dart b/lib/models/ingredient.dart index d7244ba..9efaae8 100644 --- a/lib/models/ingredient.dart +++ b/lib/models/ingredient.dart @@ -1,5 +1,10 @@ +import 'package:isar/isar.dart'; + import 'unit.dart'; +part 'ingredient.g.dart'; + +@embedded class Ingredient { final String title; List possibleUnits; diff --git a/lib/models/ingredient_list_entry.dart b/lib/models/ingredient_list_entry.dart index 03888f1..769f5bc 100644 --- a/lib/models/ingredient_list_entry.dart +++ b/lib/models/ingredient_list_entry.dart @@ -1,6 +1,11 @@ +import 'package:isar/isar.dart'; + import 'ingredient.dart'; import 'unit.dart'; +part 'ingredient_list_entry.g.dart'; + +@embedded class IngredientListEntry { final Ingredient ingredient; final int amount; diff --git a/lib/models/recipe.dart b/lib/models/recipe.dart index d8485f4..8bf135f 100644 --- a/lib/models/recipe.dart +++ b/lib/models/recipe.dart @@ -1,35 +1,46 @@ +import 'package:isar/isar.dart'; +import 'package:rezepte/models/ingredient.dart'; +import 'package:rezepte/models/unit.dart'; + import 'difficulty.dart'; import 'cooking_step.dart'; import 'ingredient_list_entry.dart'; +part 'recipe.g.dart'; + +@collection class Recipe { + final int id; String title; String description; - Difficulty? difficulty; + Difficulty difficulty; List ingredients = []; List steps = []; Recipe({ + required this.id, required this.title, this.description = '', - this.difficulty, + this.difficulty = Difficulty.notSelected, }); factory Recipe.fromJson(json) => Recipe( + id: json['id'] as int, title: json['title'] as String, description: json['description'] as String, - // difficulty: json['difficulty'] as Difficulty?, - ); - // ..ingredients = _ingredientsFromMap( - // json['ingredients'] as List>) - // ..steps = _stepsFromMap(json['steps']); + difficulty: json['difficulty'] as Difficulty, + ) + ..ingredients = _ingredientsFromMap( + json['ingredients'] as List>) + ..steps = _stepsFromMap(json['steps']); Map toJson() => { + 'id': id, 'title': title, 'description': description, - // 'difficulty': difficulty, - // 'ingredients': ingredients.map((e) => e.toJson()).toList(), - // 'steps': steps.map((e) => e.toJson()).toList(), + 'difficulty': difficulty, + 'ingredients': ingredients.map((e) => e.toJson()).toList(), + 'steps': steps.map((e) => e.toJson()).toList(), }; void addIngredient(IngredientListEntry ingredient) => @@ -52,7 +63,7 @@ class Recipe { bool get isEmpty { return title.isEmpty && description.isEmpty && - difficulty == null && + difficulty == Difficulty.notSelected && ingredients.isEmpty && steps.isEmpty; } @@ -64,7 +75,7 @@ class Recipe { void clear() { title = ''; description = ''; - difficulty = null; + difficulty = Difficulty.notSelected; ingredients.clear(); steps.clear(); } diff --git a/lib/models/unit.dart b/lib/models/unit.dart index e287460..54ea17f 100644 --- a/lib/models/unit.dart +++ b/lib/models/unit.dart @@ -1,3 +1,8 @@ +import 'package:isar/isar.dart'; + +part 'unit.g.dart'; + +@embedded class Unit { final String name; final UnitType type; diff --git a/lib/pages/create_recipe_page.dart b/lib/pages/create_recipe_page.dart index 15c048e..217b474 100644 --- a/lib/pages/create_recipe_page.dart +++ b/lib/pages/create_recipe_page.dart @@ -76,9 +76,10 @@ class _CreateRecipeState extends State { style: TextStyle( color: Theme.of(context).colorScheme.onBackground), ), - DropdownMenu( + DropdownMenu( dropdownMenuEntries: DifficultyUtil.getDropdownList(), - onSelected: (value) => recipe.difficulty = value, + onSelected: (value) => + recipe.difficulty = value ?? Difficulty.notSelected, label: const Text('Difficulty'), textStyle: TextStyle( color: Theme.of(context).colorScheme.onBackground), diff --git a/lib/services/providers/db/dbhelper.dart b/lib/services/providers/db/dbhelper.dart index 2169b08..53b12e3 100644 --- a/lib/services/providers/db/dbhelper.dart +++ b/lib/services/providers/db/dbhelper.dart @@ -1,29 +1,36 @@ -import 'package:hive/hive.dart'; -import 'package:path_provider/path_provider.dart'; +import 'dart:io'; +import 'package:flutter/foundation.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:isar/isar.dart'; import '../../../models/recipe.dart'; import '../../../example_data.dart' as e; class DbHelper { - static Box get _recipesBox => Hive.box(name: 'recipes'); + static late Directory _dir; + static Isar get _isar => Isar.open( + schemas: _schemas, + directory: _dir.path, + ); + + static const List _schemas = [ + RecipeSchema, + ]; + static int get nextRecipeId => _isar.recipes.autoIncrement(); static Future init() async { - final dir = await getApplicationDocumentsDirectory(); - Hive.defaultDirectory = dir.path; - Hive.registerAdapter('Recipe', Recipe.fromJson); - _recipesBox.clear(); - for (final recipe in e.exampleRecipes) { - insertRecipe(recipe); + _dir = await getApplicationDocumentsDirectory(); + + if (kDebugMode) { + _isar.write((isar) => _isar.recipes.putAll(e.exampleRecipes)); } } static List fetchRecipes() { - List recipes = _recipesBox.getAll(['0', '1']).cast(); - - return recipes; - } - - static void insertRecipe(Recipe recipe) { - _recipesBox.put(_recipesBox.length.toString(), recipe); + return _isar.recipes + .getAll([1, 2]) + .where((element) => element != null) + .cast() + .toList(); } } diff --git a/lib/services/providers/recipe_list_provider.dart b/lib/services/providers/recipe_list_provider.dart index ddd8f68..73f59d9 100644 --- a/lib/services/providers/recipe_list_provider.dart +++ b/lib/services/providers/recipe_list_provider.dart @@ -13,7 +13,7 @@ class RecipeListProvider extends ChangeNotifier { notifyListeners(); } - List get recipes => DbHelper.fetchRecipes(); + List get recipes => DbHelper.fetchRecipes(); // _recipes; void clearRecipes({silent = false}) { _recipes.clear(); diff --git a/lib/services/providers/recipe_provider.dart b/lib/services/providers/recipe_provider.dart index f811207..e396221 100644 --- a/lib/services/providers/recipe_provider.dart +++ b/lib/services/providers/recipe_provider.dart @@ -5,7 +5,7 @@ import '../../models/recipe.dart'; class RecipeProvider extends ChangeNotifier { Recipe? _recipe; - Recipe get recipe => _recipe ??= Recipe(title: ''); + Recipe get recipe => _recipe ??= Recipe(id: 0, title: ''); set recipe(Recipe recipe) { _recipe = recipe; diff --git a/pubspec.yaml b/pubspec.yaml index 71cc39f..4deb5ab 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: sdk: flutter provider: ^6.0.5 - hive: ^4.0.0-dev.2 + isar: ^4.0.0-dev.13 isar_flutter_libs: ^4.0.0-dev.13 path_provider: ^2.1.0 @@ -20,6 +20,7 @@ dev_dependencies: sdk: flutter flutter_lints: ^2.0.0 + build_runner: ^2.4.6 flutter: From c0fd6283c352144a59b0b4dd4fe5a2c1d34afce9 Mon Sep 17 00:00:00 2001 From: SomnusVeritas Date: Mon, 13 Nov 2023 17:32:05 +0100 Subject: [PATCH 05/10] added db functions to delete and add recipes --- lib/services/providers/db/dbhelper.dart | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/services/providers/db/dbhelper.dart b/lib/services/providers/db/dbhelper.dart index 53b12e3..66f53a5 100644 --- a/lib/services/providers/db/dbhelper.dart +++ b/lib/services/providers/db/dbhelper.dart @@ -1,10 +1,7 @@ import 'dart:io'; - -import 'package:flutter/foundation.dart'; import 'package:path_provider/path_provider.dart'; import 'package:isar/isar.dart'; import '../../../models/recipe.dart'; -import '../../../example_data.dart' as e; class DbHelper { static late Directory _dir; @@ -20,17 +17,17 @@ class DbHelper { static Future init() async { _dir = await getApplicationDocumentsDirectory(); - - if (kDebugMode) { - _isar.write((isar) => _isar.recipes.putAll(e.exampleRecipes)); - } } static List fetchRecipes() { - return _isar.recipes - .getAll([1, 2]) - .where((element) => element != null) - .cast() - .toList(); + return _isar.recipes.where().findAll().cast().toList(); + } + + static void putRecipe(Recipe recipe) { + _isar.write((isar) => isar.recipes.put(recipe)); + } + + static bool deleteRecipe(Recipe recipe) { + return _isar.write((isar) => isar.recipes.delete(recipe.id)); } } From 384744729bbd4056a27ea2043c7714fa3c836560 Mon Sep 17 00:00:00 2001 From: SomnusVeritas Date: Mon, 13 Nov 2023 17:34:57 +0100 Subject: [PATCH 06/10] changed provider to work with database --- .../providers/recipe_list_provider.dart | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/services/providers/recipe_list_provider.dart b/lib/services/providers/recipe_list_provider.dart index 73f59d9..45b451e 100644 --- a/lib/services/providers/recipe_list_provider.dart +++ b/lib/services/providers/recipe_list_provider.dart @@ -2,27 +2,26 @@ import 'package:flutter/foundation.dart'; import 'package:rezepte/services/providers/db/dbhelper.dart'; import '../../models/recipe.dart'; -import 'package:rezepte/example_data.dart' as e; class RecipeListProvider extends ChangeNotifier { - final List _recipes = kDebugMode ? e.exampleRecipes : []; + // final List _recipes = []; - set recipes(List recipes) { - _recipes.clear(); - _recipes.addAll(recipes); - notifyListeners(); - } + // set recipes(List recipes) { + // _recipes.clear(); + // _recipes.addAll(recipes); + // notifyListeners(); + // } List get recipes => DbHelper.fetchRecipes(); // _recipes; - void clearRecipes({silent = false}) { - _recipes.clear(); + // void clearRecipes({silent = false}) { + // _recipes.clear(); - if (!silent) notifyListeners(); - } + // if (!silent) notifyListeners(); + // } void addRecipe(Recipe recipe, {silent = false}) { - _recipes.add(recipe); + DbHelper.putRecipe(recipe); if (!silent) notifyListeners(); } } From 64e983bc59b1f16fa5444c64752fdb3618d7d210 Mon Sep 17 00:00:00 2001 From: SomnusVeritas Date: Mon, 13 Nov 2023 17:57:38 +0100 Subject: [PATCH 07/10] recipes can be added to db from createpage --- lib/pages/create_recipe_page.dart | 12 ++++++++++-- lib/pages/recipe_detail_page.dart | 5 +++++ lib/services/providers/db/dbhelper.dart | 2 ++ lib/services/providers/recipe_list_provider.dart | 8 ++++++-- lib/services/providers/recipe_provider.dart | 4 ++-- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/pages/create_recipe_page.dart b/lib/pages/create_recipe_page.dart index 217b474..7f78ee9 100644 --- a/lib/pages/create_recipe_page.dart +++ b/lib/pages/create_recipe_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:rezepte/services/providers/db/dbhelper.dart'; import 'package:rezepte/widgets/ingredients_bottomsheet.dart'; import 'package:rezepte/widgets/will_pop_scope.dart'; import '../models/difficulty.dart'; @@ -34,10 +35,17 @@ class _CreateRecipeState extends State { @override Widget build(BuildContext context) { - recipe = Provider.of(context).recipe; - recipeProvider = Provider.of(context, listen: false); + recipeProvider = Provider.of(context, listen: true); recipeListProvider = Provider.of(context, listen: false); + + if (recipeProvider.recipe == null) { + recipe = Recipe(id: DbHelper.nextRecipeId, title: ''); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + recipeProvider.recipe = recipe; + }); + } + return CustomWillPopScope( context, ignore: recipe.isEmpty, diff --git a/lib/pages/recipe_detail_page.dart b/lib/pages/recipe_detail_page.dart index 7b2e45a..50e8e02 100644 --- a/lib/pages/recipe_detail_page.dart +++ b/lib/pages/recipe_detail_page.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:rezepte/services/providers/recipe_provider.dart'; +import '../models/recipe.dart'; + class RecipeDetail extends StatelessWidget { const RecipeDetail({super.key}); static const routeName = '/recipeDetail'; @@ -10,6 +12,9 @@ class RecipeDetail extends StatelessWidget { Widget build(BuildContext context) { final recipe = Provider.of(context, listen: false).recipe; + if (recipe == null) Navigator.of(context).pop(); + recipe as Recipe; + return Scaffold( appBar: AppBar(), body: Center( diff --git a/lib/services/providers/db/dbhelper.dart b/lib/services/providers/db/dbhelper.dart index 66f53a5..228d5b0 100644 --- a/lib/services/providers/db/dbhelper.dart +++ b/lib/services/providers/db/dbhelper.dart @@ -30,4 +30,6 @@ class DbHelper { static bool deleteRecipe(Recipe recipe) { return _isar.write((isar) => isar.recipes.delete(recipe.id)); } + + static Stream get recipesChangedStream => _isar.recipes.watchLazy(); } diff --git a/lib/services/providers/recipe_list_provider.dart b/lib/services/providers/recipe_list_provider.dart index 45b451e..6c7ef90 100644 --- a/lib/services/providers/recipe_list_provider.dart +++ b/lib/services/providers/recipe_list_provider.dart @@ -4,6 +4,11 @@ import 'package:rezepte/services/providers/db/dbhelper.dart'; import '../../models/recipe.dart'; class RecipeListProvider extends ChangeNotifier { + RecipeListProvider() { + DbHelper.recipesChangedStream.listen((event) { + notifyListeners(); + }); + } // final List _recipes = []; // set recipes(List recipes) { @@ -20,8 +25,7 @@ class RecipeListProvider extends ChangeNotifier { // if (!silent) notifyListeners(); // } - void addRecipe(Recipe recipe, {silent = false}) { + void addRecipe(Recipe recipe) { DbHelper.putRecipe(recipe); - if (!silent) notifyListeners(); } } diff --git a/lib/services/providers/recipe_provider.dart b/lib/services/providers/recipe_provider.dart index e396221..108dd24 100644 --- a/lib/services/providers/recipe_provider.dart +++ b/lib/services/providers/recipe_provider.dart @@ -5,9 +5,9 @@ import '../../models/recipe.dart'; class RecipeProvider extends ChangeNotifier { Recipe? _recipe; - Recipe get recipe => _recipe ??= Recipe(id: 0, title: ''); + Recipe? get recipe => _recipe; - set recipe(Recipe recipe) { + set recipe(Recipe? recipe) { _recipe = recipe; notifyListeners(); } From 8835c830819f40a71644f8120571c04a96f1fb1b Mon Sep 17 00:00:00 2001 From: SomnusVeritas Date: Mon, 13 Nov 2023 18:51:25 +0100 Subject: [PATCH 08/10] refactoring --- lib/example_data.dart | 22 ++++++++++++++----- lib/main.dart | 2 +- lib/models/ingredient.dart | 16 ++++++++++++++ .../create_recipe_page.dart | 10 ++++----- lib/pages/dashboard_page.dart | 2 +- lib/widgets/ingredients_bottomsheet.dart | 3 ++- 6 files changed, 42 insertions(+), 13 deletions(-) rename lib/pages/{ => create_recipe}/create_recipe_page.dart (96%) diff --git a/lib/example_data.dart b/lib/example_data.dart index 58958a9..2cd2af1 100644 --- a/lib/example_data.dart +++ b/lib/example_data.dart @@ -22,11 +22,23 @@ final List _fluid = constants.units.where((element) => element.type == UnitType.fluid).toList(); final List exampleIngredients = [ - Ingredient(title: 'Karotte', possibleUnits: _weightAndCount), - Ingredient(title: 'Kartoffel', possibleUnits: _weightAndCount), - Ingredient(title: 'Kaffeebohnen', possibleUnits: _weight), - Ingredient(title: 'Milch', possibleUnits: _fluid), - Ingredient(title: 'Limettenblätter', possibleUnits: _count), + Ingredient( + title: 'Karotte', + possibleUnits: _weightAndCount, + type: IngredientType.vegetable), + Ingredient( + title: 'Kartoffel', + possibleUnits: _weightAndCount, + type: IngredientType.vegetable), + Ingredient( + title: 'Kaffeebohnen', + possibleUnits: _weight, + type: IngredientType.other), + Ingredient(title: 'Milch', possibleUnits: _fluid, type: IngredientType.dairy), + Ingredient( + title: 'Limettenblätter', + possibleUnits: _count, + type: IngredientType.other), ]; final List exampleRecipes = [ diff --git a/lib/main.dart b/lib/main.dart index d625ea2..3cfd574 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:rezepte/pages/create_recipe_page.dart'; +import 'package:rezepte/pages/create_recipe/create_recipe_page.dart'; import 'package:rezepte/pages/dashboard_page.dart'; import 'package:rezepte/services/providers/recipe_list_provider.dart'; import 'package:rezepte/services/providers/recipe_provider.dart'; diff --git a/lib/models/ingredient.dart b/lib/models/ingredient.dart index 9efaae8..23a3007 100644 --- a/lib/models/ingredient.dart +++ b/lib/models/ingredient.dart @@ -9,21 +9,25 @@ class Ingredient { final String title; List possibleUnits; List preferredBrands; + IngredientType type; Ingredient({ required this.title, + required this.type, this.possibleUnits = const [], this.preferredBrands = const [], }); factory Ingredient.fromJson(Map json) => Ingredient( title: json['title'] as String, + type: json['ingredient_type'] as IngredientType, possibleUnits: _unitsFromJson(json['possibleUnits']), preferredBrands: json['preferredBrands'] as List, ); Map toJson() => { 'title': title, + 'ingredient_type': type, 'possibleUnits': possibleUnits.map((e) => e.toJson()).toList(), 'preferredBrands': preferredBrands, }; @@ -42,3 +46,15 @@ class Ingredient { static List _unitsFromJson(List> jsonList) => jsonList.map((e) => Unit.fromJson(e)).toList(); } + +enum IngredientType { + vegetable, + meat, + fish, + grain, + fruit, + dairy, + fatsAndOil, + spice, + other, +} diff --git a/lib/pages/create_recipe_page.dart b/lib/pages/create_recipe/create_recipe_page.dart similarity index 96% rename from lib/pages/create_recipe_page.dart rename to lib/pages/create_recipe/create_recipe_page.dart index 7f78ee9..9063e39 100644 --- a/lib/pages/create_recipe_page.dart +++ b/lib/pages/create_recipe/create_recipe_page.dart @@ -3,11 +3,11 @@ import 'package:provider/provider.dart'; import 'package:rezepte/services/providers/db/dbhelper.dart'; import 'package:rezepte/widgets/ingredients_bottomsheet.dart'; import 'package:rezepte/widgets/will_pop_scope.dart'; -import '../models/difficulty.dart'; -import '../models/ingredient_list_entry.dart'; -import '../models/recipe.dart'; -import '../services/providers/recipe_list_provider.dart'; -import '../services/providers/recipe_provider.dart'; +import '../../models/difficulty.dart'; +import '../../models/ingredient_list_entry.dart'; +import '../../models/recipe.dart'; +import '../../services/providers/recipe_list_provider.dart'; +import '../../services/providers/recipe_provider.dart'; class CreateRecipe extends StatefulWidget { const CreateRecipe({super.key}); diff --git a/lib/pages/dashboard_page.dart b/lib/pages/dashboard_page.dart index 5348354..febfe0c 100644 --- a/lib/pages/dashboard_page.dart +++ b/lib/pages/dashboard_page.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:rezepte/pages/create_recipe_page.dart'; +import 'package:rezepte/pages/create_recipe/create_recipe_page.dart'; import 'package:rezepte/widgets/recipe_list.dart'; class Dashboard extends StatelessWidget { diff --git a/lib/widgets/ingredients_bottomsheet.dart b/lib/widgets/ingredients_bottomsheet.dart index 674139b..f35430c 100644 --- a/lib/widgets/ingredients_bottomsheet.dart +++ b/lib/widgets/ingredients_bottomsheet.dart @@ -169,7 +169,8 @@ class _IngredientsBottomsheetState extends State { } bool _submit() { - final ingredient = Ingredient(title: _ingredientController.text); + final ingredient = Ingredient( + title: _ingredientController.text, type: IngredientType.other); final unit = selectedUnit; final amount = int.tryParse(_amountController.text); if (ingredient.title.isEmpty || unit == null || amount == null) { From e4fe16ac063265556e5cad53fe535bab3f315bbe Mon Sep 17 00:00:00 2001 From: SomnusVeritas Date: Mon, 13 Nov 2023 19:45:23 +0100 Subject: [PATCH 09/10] reimplemented how create recipe page works --- lib/main.dart | 2 +- .../create_recipe/create_recipe_page.dart | 189 ------------------ lib/pages/create_recipe_page.dart | 87 ++++++++ lib/pages/dashboard_page.dart | 2 +- lib/services/providers/recipe_provider.dart | 53 ----- .../create_recipe_page/add_info_widget.dart | 70 +++++++ .../add_ingredients_widget.dart | 124 ++++++++++++ .../create_recipe_page/add_steps_widget.dart | 10 + pubspec.yaml | 2 +- 9 files changed, 294 insertions(+), 245 deletions(-) delete mode 100644 lib/pages/create_recipe/create_recipe_page.dart create mode 100644 lib/pages/create_recipe_page.dart create mode 100644 lib/widgets/create_recipe_page/add_info_widget.dart create mode 100644 lib/widgets/create_recipe_page/add_ingredients_widget.dart create mode 100644 lib/widgets/create_recipe_page/add_steps_widget.dart diff --git a/lib/main.dart b/lib/main.dart index 3cfd574..d625ea2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:rezepte/pages/create_recipe/create_recipe_page.dart'; +import 'package:rezepte/pages/create_recipe_page.dart'; import 'package:rezepte/pages/dashboard_page.dart'; import 'package:rezepte/services/providers/recipe_list_provider.dart'; import 'package:rezepte/services/providers/recipe_provider.dart'; diff --git a/lib/pages/create_recipe/create_recipe_page.dart b/lib/pages/create_recipe/create_recipe_page.dart deleted file mode 100644 index 9063e39..0000000 --- a/lib/pages/create_recipe/create_recipe_page.dart +++ /dev/null @@ -1,189 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:rezepte/services/providers/db/dbhelper.dart'; -import 'package:rezepte/widgets/ingredients_bottomsheet.dart'; -import 'package:rezepte/widgets/will_pop_scope.dart'; -import '../../models/difficulty.dart'; -import '../../models/ingredient_list_entry.dart'; -import '../../models/recipe.dart'; -import '../../services/providers/recipe_list_provider.dart'; -import '../../services/providers/recipe_provider.dart'; - -class CreateRecipe extends StatefulWidget { - const CreateRecipe({super.key}); - static const routeName = '/createRecipe'; - - @override - State createState() => _CreateRecipeState(); -} - -class _CreateRecipeState extends State { - late RecipeListProvider recipeListProvider; - late RecipeProvider recipeProvider; - late Recipe recipe; - - @override - void initState() { - super.initState(); - } - - @override - void dispose() { - recipeProvider.disposeRecipe(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - recipeProvider = Provider.of(context, listen: true); - recipeListProvider = - Provider.of(context, listen: false); - - if (recipeProvider.recipe == null) { - recipe = Recipe(id: DbHelper.nextRecipeId, title: ''); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - recipeProvider.recipe = recipe; - }); - } - - return CustomWillPopScope( - context, - ignore: recipe.isEmpty, - child: Scaffold( - appBar: AppBar( - title: const Text('Create Recipe'), - ), - floatingActionButton: recipe.isNotEmpty - ? FloatingActionButton( - onPressed: _onRecipeSubmitted, - child: const Icon(Icons.save), - ) - : null, - body: Form( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Column( - children: [ - TextFormField( - onTapOutside: (event) => FocusScope.of(context).unfocus(), - onChanged: (value) => recipe.title = value, - decoration: const InputDecoration( - label: Text('Title'), - ), - style: TextStyle( - color: Theme.of(context).colorScheme.onBackground), - ), - TextFormField( - onTapOutside: (event) => FocusScope.of(context).unfocus(), - minLines: 1, - maxLines: 4, - onChanged: (value) => recipe.description = value, - decoration: const InputDecoration( - label: Text('Description'), - ), - style: TextStyle( - color: Theme.of(context).colorScheme.onBackground), - ), - DropdownMenu( - dropdownMenuEntries: DifficultyUtil.getDropdownList(), - onSelected: (value) => - recipe.difficulty = value ?? Difficulty.notSelected, - label: const Text('Difficulty'), - textStyle: TextStyle( - color: Theme.of(context).colorScheme.onBackground), - ), - ElevatedButton( - onPressed: _openIngredientBottomSheet, - child: const Text('Add Ingredient'), - ), - Expanded( - child: ListView.separated( - itemCount: recipe.ingredients.length, - itemBuilder: _ingredientListBuilder, - separatorBuilder: (context, index) => const Divider(), - ), - ) - ], - ), - ), - ), - ), - ); - } - - void _openIngredientBottomSheet() { - showModalBottomSheet( - context: context, - builder: (context) => IngredientsBottomsheet( - onSubmitted: _onIngredientSubmitted, - ), - ); - } - - void _onIngredientSubmitted(IngredientListEntry ingredient) => setState(() { - recipe.ingredients.add(ingredient); - }); - - void _onIngredientRemoveTapped(int index) { - final removedIngredient = recipe.ingredients.elementAt(index); - - recipe.removeIngredientAt(index); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: const Text('Ingredient Removed'), - action: SnackBarAction( - label: 'Undo', - onPressed: () { - recipe.addIngredient(removedIngredient); - }), - ), - ); - } - - Widget? _ingredientListBuilder(BuildContext context, int index) { - final ingredient = recipe.ingredients.elementAt(index); - - return ListTile( - contentPadding: EdgeInsets.zero, - title: Text(ingredient.ingredient.title), - subtitle: ingredient.optional ? const Text('optional') : null, - trailing: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - ingredient.amount.toString(), - style: Theme.of(context) - .textTheme - .bodyLarge! - .copyWith(color: Theme.of(context).colorScheme.onBackground), - ), - const Padding(padding: EdgeInsets.symmetric(horizontal: 2)), - Text( - ingredient.unit.name, - style: Theme.of(context) - .textTheme - .bodyLarge! - .copyWith(color: Theme.of(context).colorScheme.onBackground), - ), - const Padding(padding: EdgeInsets.symmetric(horizontal: 5)), - SizedBox( - width: 30, - height: 30, - child: IconButton( - padding: EdgeInsets.zero, - onPressed: () => _onIngredientRemoveTapped(index), - icon: const Icon(Icons.delete), - ), - ), - ], - ), - ); - } - - void _onRecipeSubmitted() { - // TODO implement onRecipeSubmitted - if (recipe.isEmpty) return; - recipeListProvider.addRecipe(recipe); - Navigator.of(context).pop(); - } -} diff --git a/lib/pages/create_recipe_page.dart b/lib/pages/create_recipe_page.dart new file mode 100644 index 0000000..ee2d0f5 --- /dev/null +++ b/lib/pages/create_recipe_page.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:rezepte/services/providers/db/dbhelper.dart'; +import 'package:rezepte/widgets/will_pop_scope.dart'; +import '../models/recipe.dart'; +import '../services/providers/recipe_list_provider.dart'; +import '../services/providers/recipe_provider.dart'; +import '../widgets/create_recipe_page/add_info_widget.dart'; +import '../widgets/create_recipe_page/add_ingredients_widget.dart'; +import '../widgets/create_recipe_page/add_steps_widget.dart'; + +class CreateRecipe extends StatefulWidget { + const CreateRecipe({super.key}); + static const routeName = '/createRecipe'; + + @override + State createState() => _CreateRecipeState(); +} + +class _CreateRecipeState extends State { + late RecipeListProvider recipeListProvider; + late RecipeProvider recipeProvider; + late Recipe recipe; + final List pages = [ + const AddRecipeInfoWidget(), + const AddIngredientsWidget(), + const AddCookingStepsWidget(), + ]; + int selectedTabIndex = 0; + + @override + void dispose() { + recipeProvider.disposeRecipe(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + recipeProvider = Provider.of(context, listen: true); + recipeListProvider = + Provider.of(context, listen: false); + + if (recipeProvider.recipe == null) { + recipe = Recipe(id: DbHelper.nextRecipeId, title: ''); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + recipeProvider.recipe = recipe; + }); + } + + return CustomWillPopScope( + context, + ignore: recipe.isEmpty, + child: Scaffold( + appBar: AppBar( + title: const Text('Create Recipe'), + ), + bottomNavigationBar: BottomNavigationBar( + currentIndex: selectedTabIndex, + showSelectedLabels: false, + items: const [ + BottomNavigationBarItem(icon: Icon(Icons.add_task), label: ''), + BottomNavigationBarItem(icon: Icon(Icons.add_task), label: ''), + BottomNavigationBarItem(icon: Icon(Icons.add_task), label: ''), + ], + onTap: (value) => setState(() => selectedTabIndex = value), + ), + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: pages.elementAt(selectedTabIndex), + ), + // floatingActionButton: recipe.isNotEmpty + // ? FloatingActionButton( + // onPressed: _onRecipeSubmitted, + // child: const Icon(Icons.save), + // ) + // : null, + ), + ); + } + + void _onRecipeSubmitted() { + // TODO implement onRecipeSubmitted + if (recipe.isEmpty) return; + recipeListProvider.addRecipe(recipe); + Navigator.of(context).pop(); + } +} diff --git a/lib/pages/dashboard_page.dart b/lib/pages/dashboard_page.dart index febfe0c..5348354 100644 --- a/lib/pages/dashboard_page.dart +++ b/lib/pages/dashboard_page.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:rezepte/pages/create_recipe/create_recipe_page.dart'; +import 'package:rezepte/pages/create_recipe_page.dart'; import 'package:rezepte/widgets/recipe_list.dart'; class Dashboard extends StatelessWidget { diff --git a/lib/services/providers/recipe_provider.dart b/lib/services/providers/recipe_provider.dart index 108dd24..6e41601 100644 --- a/lib/services/providers/recipe_provider.dart +++ b/lib/services/providers/recipe_provider.dart @@ -15,57 +15,4 @@ class RecipeProvider extends ChangeNotifier { void disposeRecipe() { _recipe = null; } - - // set description(String description) { - // _description = description; - // notifyListeners(); - // } - - // String get title => _title; - - // set title(String title) { - // _title = title; - // notifyListeners(); - // } - - // Difficulty? get difficulty => _difficulty; - - // set difficulty(Difficulty? difficulty) { - // _difficulty = difficulty; - // notifyListeners(); - // } - - // List get ingredients => _ingredients; - - // void addIngredient(IngredientListEntry ingredient) { - // _ingredients.add(ingredient); - // notifyListeners(); - // } - - // void clearIngredients({silent = false}) { - // ingredients.clear(); - // if (!silent) notifyListeners(); - // } - - // void removeIngredientAt(int index, {silent = false}) { - // ingredients.removeAt(index); - // if (!silent) notifyListeners(); - // } - - // void removeIngredient(IngredientListEntry ingredient, {silent = false}) { - // ingredients.removeWhere((element) => element == ingredient); - // if (!silent) notifyListeners(); - // } - - // List get steps => _steps; - - // void addStep(CookingStep step, {silent = false}) { - // steps.add(step); - // if (!silent) notifyListeners(); - // } - - // void removeStepAt(int index, {silent = false}) { - // steps.removeAt(index); - // if (!silent) notifyListeners(); - // } } diff --git a/lib/widgets/create_recipe_page/add_info_widget.dart b/lib/widgets/create_recipe_page/add_info_widget.dart new file mode 100644 index 0000000..bebca1f --- /dev/null +++ b/lib/widgets/create_recipe_page/add_info_widget.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import '../../models/difficulty.dart'; +import '../../models/recipe.dart'; +import '../../services/providers/recipe_provider.dart'; + +class AddRecipeInfoWidget extends StatefulWidget { + const AddRecipeInfoWidget({super.key}); + + @override + State createState() => _AddRecipeInfoWidgetState(); +} + +class _AddRecipeInfoWidgetState extends State { + late Recipe? recipe; + + @override + Widget build(BuildContext context) { + recipe = Provider.of(context, listen: true).recipe; + + if (recipe == null) { + return const Center( + child: CircularProgressIndicator(), + ); + } + + return Column( + children: [ + TextFormField( + onTapOutside: (event) => FocusScope.of(context).unfocus(), + onChanged: (value) => recipe!.title = value, + decoration: const InputDecoration( + label: Text('Title'), + ), + style: TextStyle(color: Theme.of(context).colorScheme.onBackground), + ), + TextFormField( + onTapOutside: (event) => FocusScope.of(context).unfocus(), + minLines: 1, + maxLines: 4, + onChanged: (value) => recipe!.description = value, + decoration: const InputDecoration( + label: Text('Description'), + ), + style: TextStyle(color: Theme.of(context).colorScheme.onBackground), + ), + DropdownMenu( + dropdownMenuEntries: DifficultyUtil.getDropdownList(), + onSelected: (value) => + recipe!.difficulty = value ?? Difficulty.notSelected, + label: const Text('Difficulty'), + textStyle: + TextStyle(color: Theme.of(context).colorScheme.onBackground), + ), + // ElevatedButton( + // onPressed: _openIngredientBottomSheet, + // child: const Text('Add Ingredient'), + // ), + // Expanded( + // child: ListView.separated( + // itemCount: recipe.ingredients.length, + // itemBuilder: _ingredientListBuilder, + // separatorBuilder: (context, index) => const Divider(), + // ), + // ) + ], + ); + } +} diff --git a/lib/widgets/create_recipe_page/add_ingredients_widget.dart b/lib/widgets/create_recipe_page/add_ingredients_widget.dart new file mode 100644 index 0000000..6c3830c --- /dev/null +++ b/lib/widgets/create_recipe_page/add_ingredients_widget.dart @@ -0,0 +1,124 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import '../../models/ingredient_list_entry.dart'; +import '../../models/recipe.dart'; +import '../../services/providers/recipe_provider.dart'; +import '../../widgets/ingredients_bottomsheet.dart'; + +class AddIngredientsWidget extends StatefulWidget { + const AddIngredientsWidget({super.key}); + + @override + State createState() => _AddIngredientsWidgetState(); +} + +class _AddIngredientsWidgetState extends State { + late RecipeProvider recipeProvider; + + void _onIngredientRemoveTapped(int index) { + final removedIngredient = + recipeProvider.recipe!.ingredients.elementAt(index); + + setState(() { + recipeProvider.recipe!.removeIngredientAt(index); + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Ingredient Removed'), + action: SnackBarAction( + label: 'Undo', + onPressed: () { + setState(() { + recipeProvider.recipe!.addIngredient(removedIngredient); + }); + }, + ), + ), + ); + } + + Widget? _ingredientListBuilder(BuildContext context, int index) { + final ingredient = recipeProvider.recipe!.ingredients.elementAt(index); + + return ListTile( + contentPadding: EdgeInsets.zero, + title: Text(ingredient.ingredient.title), + subtitle: ingredient.optional ? const Text('optional') : null, + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + ingredient.amount.toString(), + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(color: Theme.of(context).colorScheme.onBackground), + ), + const Padding(padding: EdgeInsets.symmetric(horizontal: 2)), + Text( + ingredient.unit.name, + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(color: Theme.of(context).colorScheme.onBackground), + ), + const Padding(padding: EdgeInsets.symmetric(horizontal: 5)), + SizedBox( + width: 30, + height: 30, + child: IconButton( + padding: EdgeInsets.zero, + onPressed: () => _onIngredientRemoveTapped(index), + icon: const Icon(Icons.delete), + ), + ), + ], + ), + ); + } + + void _openIngredientBottomSheet() { + showModalBottomSheet( + context: context, + builder: (context) => IngredientsBottomsheet( + onSubmitted: _onIngredientSubmitted, + ), + ); + } + + void _onIngredientSubmitted(IngredientListEntry ingredient) => setState(() { + recipeProvider.recipe!.ingredients.add(ingredient); + }); + + @override + Widget build(BuildContext context) { + recipeProvider = Provider.of(context, listen: true); + if (recipeProvider.recipe == null) { + return const Center( + child: CircularProgressIndicator(), + ); + } + + return Stack( + children: [ + ListView.separated( + padding: const EdgeInsets.only(bottom: 88), + itemCount: recipeProvider.recipe!.ingredients.length, + itemBuilder: _ingredientListBuilder, + separatorBuilder: (context, index) => const Divider(), + ), + Align( + alignment: Alignment.bottomRight, + child: Padding( + padding: const EdgeInsets.only(bottom: 16, right: 16), + child: FloatingActionButton( + onPressed: _openIngredientBottomSheet, + child: const Icon(Icons.add), + ), + ), + ), + ], + ); + } +} diff --git a/lib/widgets/create_recipe_page/add_steps_widget.dart b/lib/widgets/create_recipe_page/add_steps_widget.dart new file mode 100644 index 0000000..03ac1c2 --- /dev/null +++ b/lib/widgets/create_recipe_page/add_steps_widget.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class AddCookingStepsWidget extends StatelessWidget { + const AddCookingStepsWidget({super.key}); + + @override + Widget build(BuildContext context) { + return const Placeholder(); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 4deb5ab..146a75f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,7 +19,7 @@ dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^2.0.0 + flutter_lints: ^3.0.1 build_runner: ^2.4.6 flutter: From 6571e37161fad97cc4a709f20ced6c67b9f1b453 Mon Sep 17 00:00:00 2001 From: SomnusVeritas Date: Tue, 14 Nov 2023 13:10:42 +0100 Subject: [PATCH 10/10] bugfix in creatview and regenerated linux folde --- .gitignore | 1 - .metadata | 25 ++---- .../create_recipe_page/add_info_widget.dart | 19 ++-- linux/flutter/CMakeLists.txt | 88 +++++++++++++++++++ test/widget_test.dart | 30 +++++++ 5 files changed, 134 insertions(+), 29 deletions(-) create mode 100644 linux/flutter/CMakeLists.txt create mode 100644 test/widget_test.dart diff --git a/.gitignore b/.gitignore index def5b98..dc2c423 100644 --- a/.gitignore +++ b/.gitignore @@ -837,7 +837,6 @@ Temporary Items linux/flutter/generated_plugin_registrant.cc linux/flutter/generated_plugin_registrant.h linux/flutter/generated_plugins.cmake -linux/flutter/CMakeLists.txt ### ---------------------------- References ---------------------------- ### diff --git a/.metadata b/.metadata index 620e877..c331aa0 100644 --- a/.metadata +++ b/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: "ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a" + revision: "2f708eb8396e362e280fac22cf171c2cb467343c" channel: "stable" project_type: app @@ -13,26 +13,11 @@ project_type: app migration: platforms: - platform: root - create_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a - base_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a - - platform: android - create_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a - base_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a - - platform: ios - create_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a - base_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a + create_revision: 2f708eb8396e362e280fac22cf171c2cb467343c + base_revision: 2f708eb8396e362e280fac22cf171c2cb467343c - platform: linux - create_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a - base_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a - - platform: macos - create_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a - base_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a - - platform: web - create_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a - base_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a - - platform: windows - create_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a - base_revision: ff5b5b5fa6f35b717667719ddfdb1521d8bdd05a + create_revision: 2f708eb8396e362e280fac22cf171c2cb467343c + base_revision: 2f708eb8396e362e280fac22cf171c2cb467343c # User provided section diff --git a/lib/widgets/create_recipe_page/add_info_widget.dart b/lib/widgets/create_recipe_page/add_info_widget.dart index bebca1f..1e832e2 100644 --- a/lib/widgets/create_recipe_page/add_info_widget.dart +++ b/lib/widgets/create_recipe_page/add_info_widget.dart @@ -13,13 +13,13 @@ class AddRecipeInfoWidget extends StatefulWidget { } class _AddRecipeInfoWidgetState extends State { - late Recipe? recipe; + late RecipeProvider recipeProvider; @override Widget build(BuildContext context) { - recipe = Provider.of(context, listen: true).recipe; + recipeProvider = Provider.of(context, listen: true); - if (recipe == null) { + if (recipeProvider.recipe == null) { return const Center( child: CircularProgressIndicator(), ); @@ -28,34 +28,37 @@ class _AddRecipeInfoWidgetState extends State { return Column( children: [ TextFormField( + initialValue: recipeProvider.recipe!.title, onTapOutside: (event) => FocusScope.of(context).unfocus(), - onChanged: (value) => recipe!.title = value, + onChanged: (value) => recipeProvider.recipe!.title = value, decoration: const InputDecoration( label: Text('Title'), ), style: TextStyle(color: Theme.of(context).colorScheme.onBackground), ), TextFormField( + initialValue: recipeProvider.recipe!.description, onTapOutside: (event) => FocusScope.of(context).unfocus(), minLines: 1, maxLines: 4, - onChanged: (value) => recipe!.description = value, + onChanged: (value) => recipeProvider.recipe!.description = value, decoration: const InputDecoration( label: Text('Description'), ), style: TextStyle(color: Theme.of(context).colorScheme.onBackground), ), DropdownMenu( + initialSelection: recipeProvider.recipe!.difficulty, dropdownMenuEntries: DifficultyUtil.getDropdownList(), - onSelected: (value) => - recipe!.difficulty = value ?? Difficulty.notSelected, + onSelected: (value) => recipeProvider.recipe!.difficulty = + value ?? Difficulty.notSelected, label: const Text('Difficulty'), textStyle: TextStyle(color: Theme.of(context).colorScheme.onBackground), ), // ElevatedButton( // onPressed: _openIngredientBottomSheet, - // child: const Text('Add Ingredient'), + // child: const Text('Add Ingred ient'), // ), // Expanded( // child: ListView.separated( 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/test/widget_test.dart b/test/widget_test.dart new file mode 100644 index 0000000..865c184 --- /dev/null +++ b/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:rezepte/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +}