Merge pull request #97 from itsscb:ft/app

Ft/app
This commit is contained in:
itsscb 2023-11-07 00:24:39 +01:00 committed by GitHub
commit 9200fb63ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
267 changed files with 18017 additions and 7 deletions

View File

@ -96,10 +96,16 @@ proto:
./proto/*.proto
cd ..
proto_app:
cd frontend/app && \
rm -f lib/pb/*.dart && \
protoc --dart_out=grpc:lib/pb -I=../../bff/proto/ ../../bff/proto/*.proto && \
cd ../..
evans:
evans --host localhost --port 9090 --package pb -r repl
count_lines:
cloc --exclude-dir=.history,.git .
cloc --exclude-dir=.history,.git,.idea,.dart_tool,build,ios,android,linux,macos,web,windows .
.PHONY: reset_docker backend_build rebuild backend backend dev network postgres migratenew migrateup migratedown createdb dropdb sqlc sqlcinit test coverage server mock proto evans count_lines

View File

@ -54,14 +54,9 @@ func (server *Server) RefreshToken(ctx context.Context, req *pb.RefreshTokenRequ
return nil, status.Error(codes.PermissionDenied, "session expired")
}
id, err := server.tokenMaker.NewTokenID()
if err != nil {
slog.Error("refresh_token (token_id)", slog.Int64("invoked_by", int64(refreshPayload.AccountID)), slog.String("error", err.Error()))
return nil, status.Error(codes.Internal, "failed to create session token")
}
accessToken, accessPayload, err := server.tokenMaker.CreateToken(
refreshPayload.AccountID,
id,
session.ID,
server.config.AccessTokenDuration,
)
if err != nil {

861
frontend/app/.gitignore vendored Normal file
View File

@ -0,0 +1,861 @@
# Miscellaneous
*.class
#*.lock
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# 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/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
**/generated_plugin_registrant.dart
.packages
.pub-cache/
.pub/
build/
flutter_*.png
linked_*.ds
unlinked.ds
unlinked_spec.ds
# 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
### --------------------------- 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.
### ---------------------------- 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

45
frontend/app/.metadata Normal file
View File

@ -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: "6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
- platform: android
create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
- platform: ios
create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
- platform: linux
create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
- platform: macos
create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
- platform: web
create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
- platform: windows
create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e
# 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'

16
frontend/app/README.md Normal file
View File

@ -0,0 +1,16 @@
# app
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:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
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.

View File

@ -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

13
frontend/app/android/.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks

View File

@ -0,0 +1,67 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
android {
namespace "com.example.app"
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.app"
// 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
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
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.debug
}
}
}
flutter {
source '../..'
}
dependencies {}

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -0,0 +1,33 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="app"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>

View File

@ -0,0 +1,6 @@
package com.example.app
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -0,0 +1,31 @@
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

View File

@ -0,0 +1,3 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true

View File

@ -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-7.5-all.zip

View File

@ -0,0 +1,20 @@
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
include ":app"
apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle"

34
frontend/app/ios/.gitignore vendored Normal file
View File

@ -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

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
</dict>
</plist>

View File

@ -0,0 +1 @@
#include "Generated.xcconfig"

View File

@ -0,0 +1 @@
#include "Generated.xcconfig"

View File

@ -0,0 +1,614 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.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 */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
/* 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 = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
331C807B294A618700263BE5 /* RunnerTests.swift */,
);
path = RunnerTests;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
331C8080294A63A400263BE5 /* RunnerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
331C807D294A63A400263BE5 /* Sources */,
331C807E294A63A400263BE5 /* Frameworks */,
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 = 1430;
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 */,
);
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 = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
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;
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 = 11.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.app;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = AE0B7B92F70575B8D7E0D07E /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.app.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Debug;
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 89B67EB44CE7B6631473024E /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.app.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Release;
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 640959BDD8F10B91D80A66BE /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.app.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;
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;
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 = 11.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;
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;
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 = 11.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.app;
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.app;
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 */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "331C8080294A63A400263BE5"
BuildableName = "RunnerTests.xctest"
BlueprintName = "RunnerTests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@ -0,0 +1,13 @@
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

View File

@ -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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

View File

@ -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.

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>App</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>app</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

View File

@ -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.
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -0,0 +1,223 @@
import 'dart:async';
import 'package:fixnum/fixnum.dart';
import 'package:app/pb/google/protobuf/timestamp.pb.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class Session {
Session({
this.sessionId,
this.accessToken,
this.accessTokenExpiresAt,
this.refreshToken,
this.refreshTokenExpiresAt,
this.accountId,
});
String? sessionId;
String? accessToken;
String? refreshToken;
Timestamp? accessTokenExpiresAt;
Timestamp? refreshTokenExpiresAt;
Int64? accountId;
late Database _database;
Future<Database> get database async => _database;
static Future<Session> get session async {
final Database db = await openDatabase(
join(await getDatabasesPath(), 'df_database.db'),
onCreate: (db, version) {
return db.execute(
'CREATE TABLE sessions(accountId INTEGER PRIMARY KEY, sessionId TEXT, accessToken TEXT, accessTokenExpiresAt TEXT, refreshToken TEXT, refreshTokenExpiresAt TEXT)',
);
},
version: 1,
);
Session s = Session();
s._database = db;
final sessions = await s.getSessions();
if (sessions.isNotEmpty) {
final session = sessions[0];
session._database = db;
return session;
}
return s;
}
void _init() {
_initDatabase();
}
void reset() {
if (sessionId != null) {
removeSession(sessionId!);
}
sessionId = null;
accessToken = null;
refreshToken = null;
accessTokenExpiresAt = null;
refreshTokenExpiresAt = null;
}
Future<Database> _initDatabase() async {
// print('DB: INITIALIZING - start');
_database = await openDatabase(
join(await getDatabasesPath(), 'df_database.db'),
onCreate: (db, version) {
return db.execute(
'CREATE TABLE sessions(accountId INTEGER PRIMARY KEY, sessionId TEXT, accessToken TEXT, accessTokenExpiresAt TEXT, refreshToken TEXT, refreshTokenExpiresAt TEXT)',
);
},
version: 1,
);
// print('DB: INITIALIZING - end');
return _database;
}
Map<String, dynamic> toMap() {
return {
'accountId': accountId?.toInt(),
'sessionId': sessionId,
'accessToken': accessToken,
'accessTokenExpiresAt': accessTokenExpiresAt?.toDateTime().toString(),
'refreshToken': refreshToken,
'refreshTokenExpiresAt': refreshTokenExpiresAt?.toDateTime().toString(),
};
}
@override
String toString() {
return 'Session{accountId: $accountId, sessionId: $sessionId, accessToken: $accessToken, accessTokenExpiresAt: ${accessTokenExpiresAt.toString()}, refreshToken: $refreshToken, refreshTokenExpiresAt: ${refreshTokenExpiresAt.toString()}}';
}
static newSession(Session session) async {
final db = await openDatabase(
join(await getDatabasesPath(), 'df_database.db'),
onCreate: (db, version) {
return db.execute(
'CREATE TABLE sessions(accountId INTEGER PRIMARY KEY, sessionId TEXT, accessToken TEXT, accessTokenExpiresAt TEXT, refreshToken TEXT, refreshTokenExpiresAt TEXT)',
);
},
version: 1,
);
await db.insert(
'sessions',
session.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
static Future<Session> updateToken(Session s) async {
final db = await openDatabase(
join(await getDatabasesPath(), 'df_database.db'),
onCreate: (db, version) {
return db.execute(
'CREATE TABLE sessions(accountId INTEGER PRIMARY KEY, sessionId TEXT, accessToken TEXT, accessTokenExpiresAt TEXT, refreshToken TEXT, refreshTokenExpiresAt TEXT)',
);
},
version: 1,
);
await db.update(
'sessions',
s.toMap(),
);
return s; //await getSession(s.accountId!);
}
Future<void> insertSession(Session session) async {
// print('INSERTING SESSION: ${session.sessionId}');
final db = _database;
await db.insert(
'sessions',
session.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
// print('INSERT RESULT: $result');
}
Future<Session> updateSession(Session session) async {
sessionId = session.sessionId;
accessToken = session.accessToken;
accessTokenExpiresAt = session.accessTokenExpiresAt;
refreshToken = session.refreshToken;
refreshTokenExpiresAt = session.refreshTokenExpiresAt;
final db = _database;
await db.update('sessions', session.toMap());
return session;
}
Future<void> removeSession(String sessionId) async {
final db = _database;
await db.delete('sessions', where: 'sessionId = ?', whereArgs: [sessionId]);
this.sessionId = null;
refreshToken = null;
accessTokenExpiresAt = null;
refreshTokenExpiresAt = null;
accountId = null;
accessToken = null;
}
Future<List<Session>> getSessions() async {
final db = await database;
final List<Map<String, Object?>> maps = await db.query('sessions');
// print(maps);
final List<Session> sessions = List.generate(
maps.length,
(i) {
// print('GOT MAP: ${maps[i]}');
if (maps[i]['sessionId'] == null) {
return Session();
}
return Session(
sessionId: maps[i]['sessionId'] as String,
accessToken: maps[i]['accessToken'] as String,
accessTokenExpiresAt: Timestamp.fromDateTime(
DateTime.parse(maps[i]['accessTokenExpiresAt'] as String)),
refreshToken: maps[i]['refreshToken'] as String,
refreshTokenExpiresAt: Timestamp.fromDateTime(
DateTime.parse(maps[i]['refreshTokenExpiresAt'] as String)),
accountId: Int64(maps[i]['accountId'] as int),
);
},
);
return sessions;
}
static Future<Session> getSession(Int64 accountId) async {
final Database db = await openDatabase(
join(await getDatabasesPath(), 'df_database.db'),
onCreate: (db, version) {
return db.execute(
'CREATE TABLE sessions(accountId INTEGER PRIMARY KEY, sessionId TEXT, accessToken TEXT, accessTokenExpiresAt TEXT, refreshToken TEXT, refreshTokenExpiresAt TEXT)',
);
},
version: 1,
);
final List<Map<String, Object?>> maps = await db.query('sessions',
where: 'accountId = ?', whereArgs: [accountId], limit: 1);
final List<Session> sessions = List.generate(
maps.length,
(i) {
return Session(
sessionId: maps[i]['sessionId'] as String,
accessToken: maps[i]['accessToken'] as String,
accessTokenExpiresAt: maps[i]['accessTokenExpiresAt'] as Timestamp,
refreshToken: maps[i]['refreshToken'] as String,
refreshTokenExpiresAt: maps[i]['refreshTokenExpiresAt'] as Timestamp,
accountId: maps[i]['accountId'] as Int64,
);
},
);
return sessions[0];
}
}

View File

@ -0,0 +1,190 @@
import 'dart:developer';
import 'package:app/data/database.dart';
import 'package:app/pb/account.pb.dart';
import 'package:app/pb/rpc_create_account.pb.dart';
import 'package:app/pb/rpc_get_account.pb.dart';
import 'package:app/pb/rpc_get_account_info.pb.dart';
import 'package:app/pb/rpc_login.pb.dart';
import 'package:app/pb/rpc_refresh_token.pb.dart';
import 'package:app/pb/service_df.pbgrpc.dart';
import 'package:fixnum/fixnum.dart';
import 'package:grpc/grpc.dart';
class GClient {
GClient() {
_init();
}
String baseUrl = 'localhost';
int port = 9090;
Map<String, String> metadata = {'Authorization': ''};
late Session session;
Account? account;
static Future<GClient> get client async {
Session s = await Session.session;
GClient c = GClient();
c.session = s;
final sessions = await c.session.getSessions();
if (sessions.isNotEmpty) {
c.session = sessions[0];
}
print('ACCESS_TOKEN: ${c.session.accessToken}');
return c;
}
dfClient stub = dfClient(
ClientChannel('10.0.2.2',
port: 9090,
options: const ChannelOptions(
credentials: ChannelCredentials.insecure(),
)),
options: CallOptions(
timeout: const Duration(seconds: 5),
),
);
Future<void> main(List<String> args) async {}
void _init() async {
session = await Session.session;
final sessions = await session.getSessions();
if (sessions.isNotEmpty) {
session = sessions[0];
}
}
Future<CreateAccountResponse> createAccount(
{required String email,
required String password,
required Function({GrpcError? error}) onError}) async {
try {
final response = await stub.createAccount(CreateAccountRequest(
email: email,
password: password,
));
account = response.account;
return response;
} on GrpcError catch (err) {
onError(error: err);
print('GRPC ERROR: ${err.message}');
} catch (err) {
print('ERROR: $err');
}
return CreateAccountResponse();
}
Future<LoginResponse> login(
{required String email,
required String password,
required Function({GrpcError? error}) onError,
required Function onSuccess}) async {
LoginResponse response = LoginResponse();
try {
response = await stub.login(LoginRequest(
email: email,
password: password,
));
session.accessToken = response.accessToken;
session.accountId = response.accountId;
session.sessionId = response.sessionId;
session.refreshToken = response.refreshToken;
session.accessTokenExpiresAt = response.accessTokenExpiresAt;
session.refreshTokenExpiresAt = response.refreshTokenExpiresAt;
try {
session.insertSession(session);
} catch (err) {}
metadata['Authorization'] = 'Bearer ${response.accessToken}';
onSuccess();
return response;
} on GrpcError catch (err) {
print('caught error: ${err.message}');
metadata['Authorization'] = '';
onError(error: err);
} catch (err) {
print('caught error: $err');
metadata['Authorization'] = '';
onError();
}
return response;
}
bool get isLoggedIn =>
session.accessTokenExpiresAt != null &&
session.accessTokenExpiresAt!.toDateTime().isAfter(DateTime.now());
Future<void> resetSession() async {
session.reset();
account = Account();
session = await Session.session;
}
Future<bool> refreshToken() async {
try {
final response = await stub.refreshToken(
RefreshTokenRequest(
refreshToken: session.refreshToken,
),
);
session.accessToken = response.accessToken;
session.insertSession(session);
return true;
} on GrpcError catch (err) {
print('caught grpc error: $err');
}
return false;
}
Future<GetAccountResponse> getAccount(
{required Int64 accountId,
required Function({GrpcError? err}) onError}) async {
GetAccountResponse response = GetAccountResponse();
try {
response = await stub.getAccount(GetAccountRequest(
id: accountId,
));
account = response.account;
} on GrpcError catch (err) {
if (err.code == 16) {
log(err.toString());
onError(err: err);
} else {
log(err.toString());
onError();
}
} catch (err) {
log(err.toString());
onError();
}
return response;
}
Future<GetAccountInfoResponse> getAccountInfo(GetAccountInfoRequest request,
{required Function({String msg}) onError}) async {
GetAccountInfoResponse response = GetAccountInfoResponse();
try {
print('SENDING REQ: $request WITH $metadata');
response = await stub.getAccountInfo(
request,
options: CallOptions(
metadata: {'Authorization': 'Bearer ${session.accessToken}'},
),
);
return response;
} on GrpcError catch (err) {
print('caught grpc error: ${err.message} [${err.code}]');
if (err.code == 16) {
onError(msg: 'Sitzung ist abgelaufen.\nBitte loggen Sie sich neu ein.');
} else {
onError(msg: err.message != null ? err.message! : 'Interner Fehler');
}
} catch (err) {
print('caught error: $err');
onError(msg: err.toString());
}
return response;
}
}

View File

@ -0,0 +1,49 @@
import 'package:app/pages/home_page.dart';
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(
MaterialApp(
theme: ThemeData().copyWith(
colorScheme: const ColorScheme(
brightness: Brightness.dark,
primary: Colors.white,
onPrimary: Colors.black,
secondary: Colors.black,
onSecondary: Colors.white,
error: Color.fromARGB(170, 255, 0, 0),
onError: Color.fromARGB(170, 255, 0, 0),
background: Colors.transparent,
onBackground: Colors.white,
surface: Colors.black,
onSurface: Colors.white,
),
textTheme: const TextTheme().copyWith(
titleLarge: const TextStyle(
color: Colors.white,
),
titleMedium: const TextStyle(
color: Colors.white,
),
titleSmall: const TextStyle(
color: Colors.white,
),
),
inputDecorationTheme: const InputDecorationTheme(
labelStyle: TextStyle(
color: Colors.grey,
),
),
scaffoldBackgroundColor: Colors.transparent,
appBarTheme: const AppBarTheme().copyWith(
backgroundColor: Colors.black,
foregroundColor: Colors.white,
)),
home: HomePage(
loggedOut: false,
),
),
);
}

View File

@ -0,0 +1,17 @@
class ApiResponse<T> {
Status status;
T? data;
String? message;
ApiResponse.initial(this.message) : status = Status.INITIAL;
ApiResponse.loading(this.message) : status = Status.LOADING;
ApiResponse.completed(this.data) : status = Status.COMPLETED;
ApiResponse.error(this.message) : status = Status.ERROR;
@override
String toString() {
return "Status : $status \n Message: $message \n Data : $data";
}
}
enum Status { INITIAL, LOADING, COMPLETED, ERROR }

View File

@ -0,0 +1,32 @@
class AppException implements Exception {
final _message;
final _prefix;
AppException([this._message, this._prefix]);
String toString() {
return "$_prefix$_message";
}
}
class FetchDataException extends AppException {
FetchDataException([String? message])
: super(message, 'Fehler bei der Kommunikation: ');
}
class BadRequestException extends AppException {
BadRequestException([message]) : super(message, 'Ungültige Anfrage; ');
}
class UnauthorizedException extends AppException {
UnauthorizedException([message])
: super(message, 'Nicht authorisierte Anfrage; ');
}
class InvalidInputException extends AppException {
InvalidInputException([message]) : super(message, 'Ungültige Eingabe; ');
}
class InternalException extends AppException {
InternalException([message]) : super(message, 'Interner Fehler; ');
}

View File

@ -0,0 +1,345 @@
import 'dart:io';
import 'package:app/model/apis/app_exception.dart';
import 'package:app/pb/account.pb.dart';
import 'package:app/pb/account_info.pb.dart';
import 'package:app/pb/google/protobuf/timestamp.pb.dart';
import 'package:app/pb/person.pb.dart';
import 'package:app/data/database.dart';
import 'package:app/pb/rpc_create_account.pb.dart';
import 'package:app/pb/rpc_create_person.pb.dart';
import 'package:app/pb/rpc_get_account.pb.dart';
import 'package:app/pb/rpc_get_account_info.pb.dart';
import 'package:app/pb/rpc_get_person.pb.dart';
import 'package:app/pb/rpc_list_persons.pb.dart';
import 'package:app/pb/rpc_login.pb.dart';
import 'package:app/pb/rpc_refresh_token.pb.dart';
import 'package:app/pb/service_df.pbgrpc.dart';
import 'package:fixnum/fixnum.dart';
import 'package:grpc/grpc.dart';
class BackendService {
BackendService() {
_init();
}
final String baseUrl = '10.0.0.2';
final String port = '9090';
late Session _session;
final dfClient _client = dfClient(
ClientChannel('10.0.2.2',
port: 9090,
options: const ChannelOptions(
credentials: ChannelCredentials.insecure(),
)),
options: CallOptions(
timeout: const Duration(seconds: 5),
),
);
static get client => dfClient(
ClientChannel('10.0.2.2',
port: 9090,
options: const ChannelOptions(
credentials: ChannelCredentials.insecure(),
)),
options: CallOptions(
timeout: const Duration(seconds: 5),
),
);
void _init() {
Session.session.then((value) => _session = value);
}
Future<Session?> _isLoggedIn() async {
Session session = await Session.session;
if (session.accessToken == null ||
session.refreshToken == null ||
session.accountId == null) {
return null;
}
if (session.accessTokenExpiresAt == null) {
return null;
}
if (session.refreshTokenExpiresAt == null) {
return null;
}
if (session.refreshTokenExpiresAt!.toDateTime().isBefore(DateTime.now())) {
return null;
} else {
if (session.refreshToken != null &&
session.accessTokenExpiresAt!.toDateTime().isBefore(DateTime.now())) {
session = await refreshToken(session);
}
}
return session;
}
static Future<bool> get isLoggedIn async {
Session session = await Session.session;
if (session.accessToken == null ||
session.refreshToken == null ||
session.accountId == null) {
return false;
}
if (session.accessTokenExpiresAt == null) {
await logout();
return false;
}
if (session.refreshTokenExpiresAt == null) {
await logout();
return false;
}
if (session.refreshTokenExpiresAt!.toDateTime().isBefore(DateTime.now())) {
await logout();
return false;
}
if (session.accessTokenExpiresAt!.toDateTime().isBefore(DateTime.now())) {
Session s = await BackendService.refreshToken(session);
if (s == session) {
return false;
}
}
return true;
}
static Future<bool> createAccount(
{required String email, required String password}) async {
try {
await BackendService.client.createAccount(CreateAccountRequest(
email: email,
password: password,
));
return await login(email: email, password: password);
} on SocketException {
throw FetchDataException('Keine Internet Verbindung');
} on GrpcError catch (err) {
throw FetchDataException(err.message);
} catch (err) {
throw InternalException(err.toString());
}
}
Future<Account> getAccount() async {
Session? session = await _isLoggedIn();
if (session == null) {
throw UnauthorizedException('Sitzung ist abgelaufen');
}
try {
final GetAccountResponse response = await _client.getAccount(
GetAccountRequest(id: session.accountId),
options: CallOptions(
metadata: {'Authorization': 'Bearer ${session.accessToken}'}));
return response.account;
} on SocketException {
throw FetchDataException('Keine Internet Verbindung');
} on GrpcError catch (err) {
if (err.code == 16) {
throw UnauthorizedException(err.message);
}
throw FetchDataException(err.message);
} catch (err) {
throw InternalException(err.toString());
}
}
Future<AccountInfo> getAccountInfo() async {
Session session = await Session.session;
if (session.accessTokenExpiresAt == null) {
throw UnauthorizedException('Keine Siztung gefunden');
}
if (session.accessTokenExpiresAt!.toDateTime().isBefore(DateTime.now())) {
session = await refreshToken(session);
if (session.accessTokenExpiresAt!.toDateTime().isBefore(DateTime.now())) {
throw UnauthorizedException('Sitzung ist abgelaufen');
}
}
try {
final GetAccountInfoResponse response = await _client
.getAccountInfo(GetAccountInfoRequest(accountId: _session.accountId));
return response.accountInfo;
} on SocketException {
throw FetchDataException('Keine Internet Verbindung');
} on GrpcError catch (err) {
if (err.code == 16) {
await refreshToken(session);
return getAccountInfo();
}
throw FetchDataException(err.message);
} catch (err) {
throw InternalException(err.toString());
}
}
Future<Person> getPerson(Int64 personId) async {
Session session = await Session.session;
if (session.accessTokenExpiresAt == null) {
throw UnauthorizedException('Keine Siztung gefunden');
}
if (session.accessTokenExpiresAt!.toDateTime().isBefore(DateTime.now())) {
session = await refreshToken(session);
if (session.accessTokenExpiresAt == null) {
throw UnauthorizedException('Sitzung ist abgelaufen');
}
}
try {
final GetPersonResponse response =
await _client.getPerson(GetPersonRequest(id: personId));
return response.person;
} on SocketException {
throw FetchDataException('Keine Internet Verbindung');
} on GrpcError catch (err) {
throw FetchDataException(err.message);
} catch (err) {
throw InternalException(err.toString());
}
}
Future<Person> createPerson(
{required String firstname,
required String lastname,
required String street,
required String zip,
required String city,
required String country,
required DateTime birthday}) async {
Session session = await Session.session;
if (session.accessTokenExpiresAt == null) {
throw UnauthorizedException('Keine Siztung gefunden');
}
if (session.accessTokenExpiresAt!.toDateTime().isBefore(DateTime.now())) {
session = await refreshToken(session);
if (session.accessTokenExpiresAt == null) {
throw UnauthorizedException('Sitzung ist abgelaufen');
}
}
try {
final CreatePersonResponse response = await _client.createPerson(
CreatePersonRequest(
accountId: session.accountId,
lastname: lastname,
firstname: firstname,
street: street,
zip: zip,
country: country,
birthday: Timestamp.fromDateTime(birthday),
),
options: CallOptions(
metadata: {'Authorization': 'Bearer ${session.accessToken}'}));
return response.person;
} on SocketException {
throw FetchDataException('Keine Internet Verbindung');
} on GrpcError catch (err) {
throw FetchDataException(err.message);
} catch (err) {
throw InternalException(err.toString());
}
}
Future<List<Person>> listPersons() async {
Session session = await Session.session;
if (session.accessTokenExpiresAt == null) {
throw UnauthorizedException('Keine Siztung gefunden');
}
if (session.accessTokenExpiresAt!.toDateTime().isBefore(DateTime.now())) {
session = await refreshToken(session);
if (session.accessTokenExpiresAt == null) {
throw UnauthorizedException('Sitzung ist abgelaufen');
}
}
try {
final ListPersonsResponse response = await _client.listPersons(
ListPersonsRequest(
accountId: session.accountId,
),
options: CallOptions(
metadata: {'Authorization': 'Bearer ${session.accessToken}'}));
return response.persons;
} on SocketException {
throw FetchDataException('Keine Internet Verbindung');
} on GrpcError catch (err) {
throw FetchDataException(err.message);
} catch (err) {
throw InternalException(err.toString());
}
}
// Future<List<Person>> listPersons() async {
// if (_session.accessToken == null) {
// refreshToken();
// }
// try {
// ListPersonsResponse response =
// await _client.listPersons(ListPersonsRequest(accountId: _session.accountId));
// return response.persons;
// } on SocketException {
// throw FetchDataException('Keine Internet Verbindung');
// } on GrpcError catch (err) {
// throw FetchDataException(err.message);
// } catch (err) {
// throw InternalException(err.toString());
// }
// }
static Future<bool> login(
{required String email, required String password}) async {
try {
final LoginResponse response = await BackendService.client.login(
LoginRequest(
email: email,
password: password,
),
);
Session s = Session(
accessToken: response.accessToken,
sessionId: response.sessionId,
accessTokenExpiresAt: response.accessTokenExpiresAt,
refreshToken: response.refreshToken,
refreshTokenExpiresAt: response.refreshTokenExpiresAt,
accountId: response.accountId,
);
await Session.newSession(s);
return response.accessToken != '';
} on SocketException {
throw FetchDataException('Keine Internet Verbindung');
} on GrpcError catch (err) {
throw FetchDataException(err.message);
} catch (err) {
throw InternalException(err.toString());
}
}
static Future<Session> refreshToken(Session session) async {
try {
final RefreshTokenResponse response = await BackendService.client
.refreshToken(
RefreshTokenRequest(refreshToken: session.refreshToken));
session.accessToken = response.accessToken;
session.accessTokenExpiresAt = response.accessTokenExpiresAt;
session = await Session.updateToken(session);
return session;
} on SocketException {
throw FetchDataException('Keine Internet Verbindung');
} on GrpcError catch (err) {
throw FetchDataException(err.message);
} catch (err) {
throw InternalException(err.toString());
}
}
static Future<void> logout() async {
Session session = await Session.session;
session.reset();
}
}

View File

@ -0,0 +1,32 @@
import 'package:app/model/apis/api_response.dart';
import 'package:app/model/services/backend_service.dart';
import 'package:app/model/view_model/base_vm.dart';
import 'package:app/pb/account.pb.dart';
class AccountViewModel extends BaseViewModel {
AccountViewModel() {
_init();
}
ApiResponse _apiResponse = ApiResponse.initial('Keine Daten');
final BackendService _service = BackendService();
Account? _account;
ApiResponse get response {
return _apiResponse;
}
Account? get account {
return _account;
}
void _init() async {
super.init();
// try {
// _apiResponse = ApiResponse.completed(await _service.getAccount());
// } catch (e) {
// _apiResponse = ApiResponse.error(e.toString());
// }
// notifyListeners();
}
}

View File

@ -0,0 +1,254 @@
import 'package:app/model/apis/api_response.dart';
import 'package:app/model/services/backend_service.dart';
import 'package:app/pages/home_page.dart';
import 'package:app/util/colors.dart';
import 'package:flutter/material.dart';
class BaseViewModel with ChangeNotifier {
BaseViewModel() {
init();
}
ApiResponse _apiResponse = ApiResponse.initial('Keine Daten');
final BackendService _service = BackendService();
ApiResponse get response {
return _apiResponse;
}
void init() async {
// if (await BackendService.isLoggedIn) {
try {
_apiResponse = ApiResponse.completed(await _service.getAccount());
} catch (e) {
_apiResponse = ApiResponse.error(e.toString());
}
notifyListeners();
// }
}
Future<bool> isLoggedIn(BuildContext context) async {
final messenger = ScaffoldMessenger.of(context);
final navigator = Navigator.of(context);
bool loggedIn = false;
try {
loggedIn = await BackendService.isLoggedIn;
} catch (err) {
if (err.toString().contains('session is blocked')) {
_apiResponse = ApiResponse.error('Sitzung ist abgelaufen');
navigator.pushAndRemoveUntil(
MaterialPageRoute(
builder: (builder) => HomePage(
loggedOut: true,
)),
(route) => false);
messenger.showSnackBar(SnackBar(
backgroundColor: CustomColors.error,
content: const Text(
'Sitzung ist abgelaufen',
style: TextStyle(color: Colors.white),
),
// action: SnackBarAction(
// label: 'Details',
// onPressed: () {
// if (context.mounted) {
// showDialog(
// context: context,
// builder: (context) => AlertDialog(
// backgroundColor: Colors.black,
// icon: Icon(
// Icons.error,
// color: CustomColors.error,
// ),
// content: Text(
// err.toString(),
// textAlign: TextAlign.center,
// ),
// ));
// }
// },
// ),
));
}
}
return loggedIn;
}
Future<void> getAccount(BuildContext context) async {
_apiResponse = ApiResponse.loading('Lade Daten');
notifyListeners();
final messenger = ScaffoldMessenger.of(context);
try {
_apiResponse = ApiResponse.completed(await _service.getAccount());
} catch (e) {
if (e.toString().contains('session is blocked')) {
_apiResponse = ApiResponse.error('Sitzung ist abgelaufen');
messenger.showSnackBar(SnackBar(
backgroundColor: CustomColors.error,
content: const Text(
'Sitzung ist abgelaufen',
style: TextStyle(color: Colors.white),
),
action: SnackBarAction(
label: 'Details',
onPressed: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
backgroundColor: Colors.black,
icon: Icon(
Icons.error,
color: CustomColors.error,
),
content: Text(
e.toString(),
textAlign: TextAlign.center,
),
));
},
),
));
}
messenger.showSnackBar(SnackBar(
backgroundColor: CustomColors.error,
content: const Text(
'Sitzung ist abgelaufen',
style: TextStyle(color: Colors.white),
),
action: SnackBarAction(
label: 'Details',
onPressed: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
backgroundColor: Colors.black,
icon: Icon(
Icons.error,
color: CustomColors.error,
),
content: Text(
e.toString(),
textAlign: TextAlign.center,
),
));
},
),
));
_apiResponse = ApiResponse.error(e.toString());
}
notifyListeners();
}
Future<void> logout() async {
_apiResponse = ApiResponse.loading('Logge aus');
notifyListeners();
try {
await BackendService.logout();
_apiResponse = ApiResponse.completed(true);
} catch (e) {
_apiResponse = ApiResponse.error(e.toString());
}
print(_apiResponse.message);
notifyListeners();
}
Future<bool> login(BuildContext context,
{required String email, required String password}) async {
bool resp = false;
_apiResponse = ApiResponse.loading('Logge ein');
notifyListeners();
final messenger = ScaffoldMessenger.of(context);
try {
resp = await BackendService.login(email: email, password: password);
_apiResponse = ApiResponse.completed(resp);
messenger.showSnackBar(SnackBar(
backgroundColor: CustomColors.success,
content: const Text(
'Erfolgreich eingeloggt',
style: TextStyle(color: Colors.white),
),
));
} catch (e) {
messenger.showSnackBar(SnackBar(
backgroundColor: CustomColors.error,
content: const Text(
'Login fehlgeschlagen',
style: TextStyle(color: Colors.white),
),
action: SnackBarAction(
label: 'Details',
onPressed: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
backgroundColor: Colors.black,
icon: Icon(
Icons.error,
color: CustomColors.error,
),
content: Text(
e.toString(),
textAlign: TextAlign.center,
),
));
},
),
));
_apiResponse = ApiResponse.error(e.toString());
}
print(_apiResponse.message);
notifyListeners();
return resp;
}
Future<bool> createAccount(BuildContext context,
{required String email, required String password}) async {
bool resp = false;
final messenger = ScaffoldMessenger.of(context);
_apiResponse = ApiResponse.loading('Logge ein');
notifyListeners();
try {
resp =
await BackendService.createAccount(email: email, password: password);
messenger.showSnackBar(SnackBar(
backgroundColor: CustomColors.success,
content: const Text(
'Account angelegt',
style: TextStyle(color: Colors.white),
),
));
_apiResponse = ApiResponse.completed(resp);
} catch (e) {
messenger.showSnackBar(SnackBar(
backgroundColor: CustomColors.error,
content: const Text(
'Account anlegen fehlgeschlagen',
style: TextStyle(color: Colors.white),
),
action: SnackBarAction(
label: 'Details',
onPressed: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
backgroundColor: Colors.black,
icon: Icon(
Icons.error,
color: CustomColors.error,
),
content: Text(
e.toString(),
textAlign: TextAlign.center,
),
));
},
),
));
_apiResponse = ApiResponse.error(e.toString());
}
print(_apiResponse.message);
notifyListeners();
return resp;
}
}

View File

@ -0,0 +1,57 @@
import 'package:app/model/apis/api_response.dart';
import 'package:app/model/services/backend_service.dart';
import 'package:app/pb/person.pb.dart';
import 'package:flutter/material.dart';
class PersonsViewModel with ChangeNotifier {
PersonsViewModel() {
listPersons();
}
ApiResponse _apiResponse = ApiResponse.initial('Keine Daten');
final BackendService _service = BackendService();
ApiResponse get response {
return _apiResponse;
}
Future<List<Person>> listPersons() async {
List<Person> persons = [];
_apiResponse = ApiResponse.loading('Lade Daten');
try {
persons = await _service.listPersons();
_apiResponse = ApiResponse.completed(persons);
} catch (e) {
_apiResponse = ApiResponse.error(e.toString());
}
notifyListeners();
return persons;
}
Future<Person> createPerson(BuildContext context,
{required String firstname,
required String lastname,
required String street,
required String zip,
required String city,
required String country,
required DateTime birthday}) async {
Person person = Person();
_apiResponse = ApiResponse.loading('Erstelle Person');
try {
person = await _service.createPerson(
firstname: firstname,
lastname: lastname,
street: street,
zip: zip,
city: city,
country: country,
birthday: birthday);
_apiResponse = ApiResponse.completed(person);
} catch (err) {
_apiResponse = ApiResponse.error(err.toString());
}
notifyListeners();
return person;
}
}

View File

@ -0,0 +1,218 @@
import 'package:app/model/services/backend_service.dart';
import 'package:app/model/view_model/account_vm.dart';
import 'package:app/pages/login_overlay.dart';
import 'package:app/pages/persons_page.dart';
import 'package:app/widgets/background.dart';
import 'package:app/widgets/bottom_navigation.dart';
import 'package:app/widgets/bottom_navigation_item.dart';
import 'package:app/widgets/drawer.dart';
import 'package:app/widgets/side_drawer_item.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class HomePage extends StatefulWidget {
HomePage({super.key, required this.loggedOut});
bool loggedOut;
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
_init();
}
AccountViewModel vm = AccountViewModel();
void _init() async {
// _setLoading(true);
// _setLoading(widget.loggedOut);
// _loading = widget.loggedOut;
// _loggedin = await BackendService.isLoggedIn;
// if (!_loggedin) {
// await BackendService.logout();
// final navigator = Navigator.of(context);
// navigator.pushAndRemoveUntil(
// MaterialPageRoute(
// builder: (builder) => HomePage(
// loggedOut: true,
// )),
// (route) => false);
// }
_setLoading(false);
}
_isLoggedIn(BuildContext context) async {
bool logged = await vm.isLoggedIn(context);
_loggedin = logged;
}
void _setLoading(bool loading) {
setState(() {
_loading = loading;
});
}
bool _loading = true;
bool _loggedin = false;
@override
Widget build(BuildContext context) {
return Background(
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
// flexibleSpace: Image.asset(
// 'lib/assets/logo_300x200.png',
// // height: 400,
// ),
),
drawer: SideDrawer(
children: [
const Spacer(
flex: 3,
),
SideDrawerItem(
onPressed: () {},
icon: Icons.question_answer,
color: Colors.white,
label: 'About',
),
SideDrawerItem(
onPressed: () {},
icon: Icons.privacy_tip,
color: Colors.white,
label: 'Datenschutz',
),
SideDrawerItem(
onPressed: () {},
icon: Icons.apartment,
color: Colors.white,
label: 'Impressum',
),
const Spacer(
flex: 1,
),
if (_loggedin)
SideDrawerItem(
onPressed: () async {
setState(() {
_loading = true;
});
await BackendService.logout();
// ignore: use_build_context_synchronously
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (builder) => HomePage(
loggedOut: true,
)),
(route) => false);
setState(() {
_loggedin = false;
_loading = false;
});
},
icon: Icons.logout,
color: Colors.white,
label: 'Logout',
),
],
),
bottomNavigationBar: BottomNavigation(
children: [
if (!_loggedin) ...[
BottomNavigationItem(
onPressed: () async {
final bool res = await showLogin(context, registration: true);
setState(() {
_loggedin = res;
});
},
icon: Icons.person_add_alt,
color: Colors.white,
label: 'Registrieren',
),
BottomNavigationItem(
onPressed: () async {
await showLogin(context);
setState(() {
vm.isLoggedIn(context);
});
},
icon: Icons.login,
color: Colors.white,
label: 'Login',
),
] else
BottomNavigationItem(
onPressed: () async {
final navigator = Navigator.of(context);
if (await vm.isLoggedIn(context)) {
navigator.push(MaterialPageRoute(
builder: (builder) => const PersonsPage()));
} else {
navigator.pushAndRemoveUntil(
MaterialPageRoute(
builder: (builder) => const PersonsPage()),
(route) => false);
}
},
icon: Icons.person_search,
color: Colors.white,
label: 'Personen',
),
BottomNavigationItem(
onPressed: () {},
icon: Icons.dashboard,
color: Colors.white,
label: 'Dashboard',
),
...[]
],
),
body: Padding(
padding: const EdgeInsets.fromLTRB(16, 45, 16, 16),
child: Center(
child: ChangeNotifierProvider<AccountViewModel>(
create: (context) => AccountViewModel(),
child:
Consumer<AccountViewModel>(builder: (context, value, child) {
// _checkResponse(value.response);
if (!widget.loggedOut) {
_isLoggedIn(context);
}
return _loading
? const CircularProgressIndicator(
color: Colors.grey,
)
: Column(
children: [
Image.asset(
'lib/assets/logo_300x200.png',
),
const SizedBox(
height: 40,
),
Text(
'Digitale Spuren auf Knopfdruck entfernen'
.toUpperCase(),
textAlign: TextAlign.center,
style: const TextStyle(
fontFamily: 'sans-serif',
fontSize: 24,
height: 1.6,
fontWeight: FontWeight.normal,
letterSpacing: 6,
),
),
],
);
})),
),
),
));
}
}

View File

@ -0,0 +1,239 @@
import 'package:app/model/view_model/base_vm.dart';
import 'package:app/widgets/background.dart';
import 'package:app/widgets/bottom_navigation.dart';
import 'package:app/widgets/bottom_navigation_item.dart';
import 'package:app/widgets/side_drawer.dart';
import 'package:app/widgets/side_drawer_item.dart';
import 'package:flutter/material.dart';
import 'package:app/util/validation.dart';
import 'package:provider/provider.dart';
Future<bool> showLogin(BuildContext context,
{bool registration = false}) async {
final formKey = GlobalKey<FormState>();
final mailController = TextEditingController();
final passwordController = TextEditingController();
BaseViewModel vm = BaseViewModel();
bool submitted = false;
bool loggedin = false;
void login(BuildContext context) {
if (formKey.currentState!.validate()) {
submitted = true;
FocusScope.of(context).unfocus();
vm
.login(context,
email: mailController.text, password: passwordController.text)
.then(
(r) {
if (r) {
loggedin = r;
Navigator.pop(context, true);
}
},
);
passwordController.clear();
submitted = false;
}
}
void register(BuildContext context) {
if (formKey.currentState!.validate()) {
submitted = true;
vm
.createAccount(
context,
email: mailController.text,
password: passwordController.text,
)
.then(
(r) {
if (r) {
loggedin = r;
Navigator.pop(context, true);
}
},
);
}
}
await showModalBottomSheet(
useSafeArea: true,
isScrollControlled: true,
backgroundColor: Colors.black,
context: context,
builder: (builder) {
return Background(
child: Scaffold(
drawer: SideDrawer(
children: [
const Spacer(
flex: 3,
),
SideDrawerItem(
onPressed: () {},
icon: Icons.question_answer,
color: Colors.white,
label: 'About',
),
SideDrawerItem(
onPressed: () {},
icon: Icons.privacy_tip,
color: Colors.white,
label: 'Datenschutz',
),
SideDrawerItem(
onPressed: () {},
icon: Icons.apartment,
color: Colors.white,
label: 'Impressum',
),
const Spacer(
flex: 1,
),
],
),
bottomNavigationBar: BottomNavigation(
children: [
BottomNavigationItem(
onPressed: () {
Navigator.pop(context, false);
},
icon: Icons.arrow_back,
color: Colors.white,
label: 'Zurück',
),
BottomNavigationItem(
onPressed: () {
Navigator.pop(context, false);
},
icon: Icons.home,
color: Colors.white,
label: 'Home',
),
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
height: 50,
),
const Image(
width: 180,
image: AssetImage(
'lib/assets/logo_300x200.png',
),
),
const SizedBox(
height: 30,
),
Text(
registration ? 'Registrieren' : 'Login',
style: const TextStyle(
fontFamily: 'sans-serif',
fontSize: 24,
height: 1.6,
fontWeight: FontWeight.normal,
letterSpacing: 6,
),
),
ChangeNotifierProvider<BaseViewModel>(
create: (context) => BaseViewModel(),
child: Consumer<BaseViewModel>(
builder: (context, value, child) => Form(
key: formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(
height: 40,
),
TextFormField(
// autofocus: true,
// inputFormatters: [
// FilteringTextInputFormatter.allow(
// emailRegExp,
// ),
// ],
controller: mailController,
decoration: const InputDecoration(
fillColor: Color.fromARGB(30, 255, 255, 255),
filled: true,
hintStyle: TextStyle(
color: Colors.white38,
),
hintText: 'E-Mail Adresse',
),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || !value.isValidEmail) {
return 'Bitte eine gültige E-Mail Adresse eingeben';
}
return null;
},
),
TextFormField(
style: const TextStyle(
color: Colors.white,
),
// inputFormatters: [
// FilteringTextInputFormatter.allow(
// passwordRegExp,
// ),
// ],
controller: passwordController,
decoration: const InputDecoration(
fillColor: Color.fromARGB(30, 255, 255, 255),
filled: true,
hintStyle: TextStyle(
color: Colors.white38,
),
hintText: 'Passwort',
),
keyboardType: TextInputType.visiblePassword,
obscureText: true,
validator: (value) {
if (value == null || !value.isValidPassword) {
return 'Bitte geben Sie Ihr Passwort ein';
}
return null;
},
),
const SizedBox(
height: 15,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: !submitted
? !registration
? () {
login(context);
}
: () {
register(context);
}
: null,
child: const Icon(Icons.login),
),
],
)
],
),
),
),
),
const Spacer(),
],
),
),
),
);
});
return loggedin;
}

View File

@ -0,0 +1,184 @@
import 'package:app/model/apis/api_response.dart';
import 'package:app/model/services/backend_service.dart';
import 'package:app/model/view_model/persons_vm.dart';
import 'package:app/pages/home_page.dart';
import 'package:app/pb/person.pb.dart';
import 'package:app/widgets/background.dart';
import 'package:app/widgets/bottom_navigation.dart';
import 'package:app/widgets/bottom_navigation_item.dart';
import 'package:app/widgets/side_drawer.dart';
import 'package:app/widgets/side_drawer_item.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class PersonsPage extends StatefulWidget {
const PersonsPage({super.key});
@override
State<PersonsPage> createState() => _PersonsPageState();
}
class _PersonsPageState extends State<PersonsPage> {
@override
void initState() {
super.initState();
_init();
}
void _init() async {
_setLoading(true);
_loggedin = await BackendService.isLoggedIn;
_setLoading(false);
}
void _setLoading(bool loading) {
setState(() {
_loading = loading;
});
}
void _checkResponse(ApiResponse response) {
if (response.status == Status.ERROR &&
response.message!.contains('unauthenticated')) {
BackendService.logout();
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (builder) => HomePage(
loggedOut: true,
)),
(route) => false);
}
}
bool _loading = true;
bool _loggedin = false;
List<Person> persons = [];
PersonsViewModel vm = PersonsViewModel();
void listPersons(BuildContext context) async {
persons = await vm.listPersons();
}
List<Widget> _personsList(List<Person> persons) {
final List<Widget> list = [];
for (var p in persons) {
list.add(Card(
color: Colors.black,
child: Text(
'${p.firstname} ${p.lastname}',
style: const TextStyle(color: Colors.white),
),
));
}
return list;
}
@override
Widget build(BuildContext context) {
return Background(
child: Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
appBar: AppBar(
automaticallyImplyLeading: false,
),
drawer: SideDrawer(
children: [
const Spacer(
flex: 3,
),
SideDrawerItem(
onPressed: () {},
icon: Icons.question_answer,
color: Colors.white,
label: 'About',
),
SideDrawerItem(
onPressed: () {},
icon: Icons.privacy_tip,
color: Colors.white,
label: 'Datenschutz',
),
SideDrawerItem(
onPressed: () {},
icon: Icons.apartment,
color: Colors.white,
label: 'Impressum',
),
const Spacer(
flex: 1,
),
if (_loggedin)
SideDrawerItem(
onPressed: () async {
setState(() {
_loading = true;
});
await BackendService.logout();
// ignore: use_build_context_synchronously
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (builder) => HomePage(
loggedOut: true,
)),
(route) => false);
setState(() {
_loggedin = false;
_loading = false;
});
},
icon: Icons.logout,
color: Colors.white,
label: 'Logout',
),
],
),
bottomNavigationBar: BottomNavigation(
children: [
BottomNavigationItem(
onPressed: () {},
icon: Icons.dashboard,
color: Colors.white,
label: 'Dashboard',
),
BottomNavigationItem(
onPressed: () {
Navigator.of(context).pop();
},
icon: Icons.home,
color: Colors.white,
label: 'Home',
),
],
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Center(
child: ChangeNotifierProvider<PersonsViewModel>(
create: (context) => PersonsViewModel(),
child: Consumer<PersonsViewModel>(
builder: (context, value, child) {
_checkResponse(value.response);
listPersons(context);
return _loading
? const CircularProgressIndicator(
color: Colors.grey,
)
: value.response.status == Status.COMPLETED
? value.response.data.length > 0
? ListView(children: _personsList(persons))
: const Text('Noch keine Personen angelegt')
: const Text('Lade Daten...');
},
),
),
),
),
),
);
}
}

View File

@ -0,0 +1,302 @@
import 'package:app/gapi/client.dart';
import 'package:app/pages_old/start_page.dart';
import 'package:app/pb/account_info.pb.dart';
import 'package:app/pb/rpc_get_account_info.pb.dart';
import 'package:app/widgets/background.dart';
import 'package:app/widgets/bottom_bar.dart';
import 'package:app/widgets/loading_widget.dart';
import 'package:app/widgets/side_drawer.dart';
import 'package:flutter/material.dart';
class DashboardPage extends StatefulWidget {
const DashboardPage({
super.key,
// required this.client,
});
// final GClient client;
@override
State<DashboardPage> createState() => _DashboardPageState();
}
class _DashboardPageState extends State<DashboardPage> {
bool _loading = false;
late AccountInfo accountInfo;
void _setLoading(bool loading) {
setState(() {
_loading = loading;
});
}
@override
void initState() {
super.initState();
_setLoading(true);
// widget.client.getAccountInfo(
// GetAccountInfoRequest(
// accountId: widget.client.session.accountId,
// ),
// onError: ({String? msg}) {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: const Text('AccountInfo konnte nicht geladen werden'),
// action: msg != null
// ? SnackBarAction(
// label: 'Details',
// textColor: Colors.grey,
// onPressed: () {
// showDialog(
// context: context,
// builder: (context) {
// return AlertDialog(
// content: Text(
// msg,
// textAlign: TextAlign.center,
// style: const TextStyle(color: Colors.black),
// ),
// icon: const Icon(
// Icons.warning,
// color: Colors.red,
// ),
// );
// },
// );
// })
// : null,
// ),
// );
// },
// ).then((value) {
// accountInfo = value.accountInfo;
// _setLoading(false);
// });
}
@override
Widget build(BuildContext context) {
return Background(
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
flexibleSpace: Image.asset(
'lib/assets/logo_300x200.png',
height: 80,
),
),
drawer: Builder(builder: (context) {
return SideDrawer(
children: [
const Spacer(),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'About',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.question_answer,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'Datenschutz',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.privacy_tip,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'Impressum',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.apartment,
color: Colors.white,
),
],
),
),
// if (widget.client.session.accessToken != null)
// TextButton(
// onPressed: () {
// widget.client.session.accessToken = null;
// widget.client.session
// .removeSession(widget.client.session.sessionId!);
// Navigator.of(context).pushAndRemoveUntil(
// MaterialPageRoute(
// builder: (context) =>
// StartPage(client: widget.client),
// ),
// (route) => false);
// },
// child: const Row(
// children: [
// Text(
// 'Log out',
// style: TextStyle(fontSize: 20),
// ),
// Spacer(),
// Icon(
// Icons.logout,
// color: Colors.white,
// ),
// ],
// ),
// ),
const SizedBox(
height: 250,
)
],
);
}),
// bottomNavigationBar: Builder(
// builder: (context) {
// return BottomBar(
// children: widget.client.session.accessToken != null
// ? [
// BottomNavigationBarItem(
// backgroundColor: Colors.white,
// label: 'Personen',
// icon: Column(
// children: [
// IconButton(
// onPressed: () =>
// Scaffold.of(context).openDrawer(),
// icon: const Icon(
// Icons.group,
// color: Colors.white,
// ),
// ),
// const Text(
// 'Personen',
// style: TextStyle(
// color: Colors.white,
// fontSize: 16,
// ),
// )
// ],
// ),
// ),
// BottomNavigationBarItem(
// backgroundColor: Colors.white,
// label: 'Home',
// icon: Column(
// children: [
// IconButton(
// onPressed: () {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) => StartPage(
// client: widget.client,
// ),
// ),
// );
// },
// icon: const Icon(
// Icons.home,
// color: Colors.white,
// ),
// ),
// const Text(
// 'Home',
// style: TextStyle(
// color: Colors.white,
// fontSize: 16,
// ),
// )
// ],
// ),
// ),
// BottomNavigationBarItem(
// backgroundColor: Colors.white,
// label: 'Menu',
// icon: IconButton(
// onPressed: () {
// Scaffold.of(context).openDrawer();
// },
// icon: const Icon(
// Icons.menu,
// color: Colors.white,
// ),
// ),
// )
// ]
// : [
// BottomNavigationBarItem(
// label: 'back',
// backgroundColor: Colors.white,
// icon: IconButton(
// onPressed: () {},
// icon: const Icon(
// Icons.arrow_back,
// color: Colors.white,
// ),
// ),
// ),
// BottomNavigationBarItem(
// backgroundColor: Colors.white,
// label: 'Menu',
// icon: IconButton(
// onPressed: () => Scaffold.of(context).openDrawer(),
// icon: const Icon(
// Icons.menu,
// color: Colors.white,
// ),
// ),
// ),
// ],
// );
// },
// ),
body: !_loading
? Background(
child: Center(
child: Column(
children: [
const SizedBox(
height: 48,
),
Text(
'Willkommen ${accountInfo.firstname} ${accountInfo.lastname}!',
style: const TextStyle(
fontSize: 24,
),
),
],
),
),
)
: const LoadingWidget(),
),
);
}
}

View File

@ -0,0 +1,290 @@
import 'package:app/gapi/client.dart';
import 'package:app/model/services/backend_service.dart';
import 'package:app/pages_old/start_page.dart';
import 'package:app/widgets/background.dart';
import 'package:app/widgets/bottom_bar.dart';
import 'package:app/widgets/loading_widget.dart';
import 'package:app/widgets/side_drawer.dart';
import 'package:flutter/material.dart';
import 'package:grpc/grpc.dart';
// GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
class LoginPage extends StatefulWidget {
const LoginPage({
super.key,
// required this.client,
// required this.onChangePage,
});
// final GClient client;
// void Function(Pages page) onChangePage;
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
bool _loading = false;
final List<BottomNavigationBarItem> bottombarButtons = [];
// List<BottomNavigationBarItem> _selectedBottomBarButtons = bottomBarButtons;
@override
void initState() {
super.initState();
_addBottomBarButtons();
}
void _addBottomBarButtons() {
bottombarButtons.addAll([
const BottomNavigationBarItem(
label: 'back',
backgroundColor: Colors.white,
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Menu',
icon: IconButton(
onPressed: () => Scaffold.of(context).openDrawer(),
icon: const Icon(
Icons.menu,
color: Colors.white,
),
),
),
]);
}
void _setLoading(bool loading) {
setState(() {
_loading = loading;
});
}
// final GClient client = GClient();
final _formKey = GlobalKey<FormState>();
final mailController = TextEditingController();
final passwordController = TextEditingController();
@override
Widget build(BuildContext context) {
return Background(
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
// flexibleSpace: Image.asset(
// 'lib/assets/logo_300x200.png',
// height: 80,
// ),
),
bottomNavigationBar: BottomBar(
children: [
BottomNavigationBarItem(
label: 'back',
backgroundColor: Colors.white,
icon: IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: const Icon(
Icons.arrow_back,
color: Colors.white,
),
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Menu',
icon: IconButton(
onPressed: () => Scaffold.of(context).openDrawer(),
icon: const Icon(
Icons.menu,
color: Colors.white,
),
),
),
],
),
drawer: SideDrawer(children: [
const Spacer(),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'About',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.question_answer,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'Datenschutz',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.privacy_tip,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'Impressum',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.apartment,
color: Colors.white,
),
],
),
),
const SizedBox(
height: 250,
)
]),
body: !_loading
? Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 100, 16, 16),
child: SingleChildScrollView(
child: Column(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Image(
width: 180,
image: AssetImage(
'lib/assets/logo_300x200.png',
),
),
const SizedBox(
height: 30,
),
const Text(
'Login',
style: TextStyle(
fontFamily: 'sans-serif',
fontSize: 24,
height: 1.6,
fontWeight: FontWeight.normal,
letterSpacing: 6,
),
),
const SizedBox(
height: 20,
),
TextFormField(
// style: TextStyle(
// color: Theme.of(context).colorScheme.primary,
// ),
controller: mailController,
decoration: const InputDecoration(
fillColor: Color.fromARGB(30, 255, 255, 255),
filled: true,
hintStyle: TextStyle(
color: Colors.white38,
),
hintText: 'E-Mail Adresse',
),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Bitte eine gültige E-Mail Adresse eingeben';
}
return null;
},
),
TextFormField(
style: const TextStyle(
color: Colors.white,
),
controller: passwordController,
decoration: const InputDecoration(
fillColor: Color.fromARGB(30, 255, 255, 255),
filled: true,
hintStyle: TextStyle(
color: Colors.white38,
),
hintText: 'Passwort',
),
keyboardType: TextInputType.visiblePassword,
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Bitte geben Sie Ihr Passwort ein';
}
return null;
},
),
const SizedBox(
height: 15,
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
// final navigator = Navigator.of(context);
_setLoading(true);
BackendService.login(
email: mailController.text,
password: passwordController.text,
).then(
(r) {
if (r) {
Navigator.pop(context);
Navigator.pop(context);
// Navigator.pushAndRemoveUntil(
// context,
// MaterialPageRoute(
// builder: (ctx) => const StartPage(
// // client: widget.client,
// ),
// ),
// (ctx) => false,
// );
// widget.onChangePage(
// Pages.dashboard,
// );
}
// _setLoading(false);
},
);
}
},
child: const Icon(Icons.login))
],
),
),
),
)
: const LoadingWidget(),
),
);
}
}

View File

@ -0,0 +1,224 @@
import 'package:app/gapi/client.dart';
import 'package:app/pages_old/start_page.dart';
import 'package:app/widgets/background.dart';
import 'package:app/widgets/bottom_bar.dart';
import 'package:app/widgets/loading_widget.dart';
import 'package:app/widgets/side_drawer.dart';
import 'package:flutter/material.dart';
import 'package:grpc/grpc.dart';
class RegisterPage extends StatefulWidget {
const RegisterPage({
super.key,
// required this.client,
});
// final GClient client;
@override
State<RegisterPage> createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
bool _loading = false;
final _formKey = GlobalKey<FormState>();
final mailController = TextEditingController();
final passwordController = TextEditingController();
void _setLoading(bool loading) {
setState(() {
_loading = loading;
});
}
@override
Widget build(BuildContext context) {
return Background(
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
flexibleSpace: Image.asset(
'lib/assets/logo_300x200.png',
height: 80,
),
),
drawer: Builder(builder: (context) {
return SideDrawer(
children: [
const Spacer(),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'About',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.question_answer,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'Datenschutz',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.privacy_tip,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'Impressum',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.apartment,
color: Colors.white,
),
],
),
),
const SizedBox(
height: 250,
)
],
);
}),
bottomNavigationBar: BottomBar(
children: [
BottomNavigationBarItem(
label: 'back',
backgroundColor: Colors.white,
icon: IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: const Icon(
Icons.arrow_back,
color: Colors.white,
),
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Menu',
icon: IconButton(
onPressed: () => Scaffold.of(context).openDrawer(),
icon: const Icon(
Icons.menu,
color: Colors.white,
),
),
),
],
),
body: !_loading
? Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 100, 16, 16),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Image(
width: 180,
image: AssetImage(
'lib/assets/logo_300x200.png',
),
),
const SizedBox(
height: 30,
),
const Text(
'Registrieren',
style: TextStyle(
fontFamily: 'sans-serif',
fontSize: 24,
height: 1.6,
fontWeight: FontWeight.normal,
letterSpacing: 6,
),
),
const SizedBox(
height: 20,
),
TextFormField(
controller: mailController,
decoration: const InputDecoration(
fillColor: Color.fromARGB(30, 255, 255, 255),
filled: true,
hintStyle: TextStyle(
color: Colors.white38,
),
hintText: 'E-Mail Adresse',
),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Bitte eine gültige E-Mail Adresse eingeben';
}
return null;
},
),
TextFormField(
style: const TextStyle(
color: Colors.white,
),
controller: passwordController,
decoration: const InputDecoration(
fillColor: Color.fromARGB(30, 255, 255, 255),
filled: true,
hintStyle: TextStyle(
color: Colors.white38,
),
hintText: 'Passwort',
),
keyboardType: TextInputType.visiblePassword,
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Bitte geben Sie Ihr Passwort ein';
}
return null;
},
),
const SizedBox(
height: 15,
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
// _setLoading(true);
}
},
child: const Icon(Icons.login))
],
),
),
),
)
: const LoadingWidget()),
);
}
}

View File

@ -0,0 +1,373 @@
import 'package:app/gapi/client.dart';
import 'package:app/model/apis/api_response.dart';
import 'package:app/model/view_model/account_vm.dart';
import 'package:app/pages_old/dashboard_page.dart';
import 'package:app/pages_old/login_page.dart';
import 'package:app/pages_old/register_page.dart';
import 'package:app/pb/account.pb.dart';
import 'package:app/widgets/background.dart';
import 'package:app/widgets/bottom_bar.dart';
import 'package:app/widgets/side_drawer.dart';
import 'package:flutter/material.dart';
import 'dart:core';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class StartPage extends StatefulWidget {
const StartPage({
super.key,
// required this.client,
});
// GClient client;
@override
State<StartPage> createState() => _StartPageState();
}
class _StartPageState extends State<StartPage> {
final List<BottomNavigationBarItem> bottombarButtons = [];
// void _updateClient(GClient c) {
// setState(() {
// widget.client = c;
// });
// }
@override
void initState() {
super.initState();
}
SnackBar _snackBar(BuildContext context, String message, String label,
void Function() action) {
ScaffoldMessenger.of(context).removeCurrentSnackBar();
// ScaffoldMessenger.of(context).clearSnackBars();
return SnackBar(
content: Text(
message,
style: const TextStyle(color: Colors.black),
),
backgroundColor: Colors.white,
action: SnackBarAction(
label: label,
onPressed: action,
),
);
}
@override
Widget build(BuildContext context) {
return Background(
child: ChangeNotifierProvider<AccountViewModel>(
create: (context) => AccountViewModel(),
child: Consumer<AccountViewModel>(builder: (context, value, child) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
),
drawer: Builder(builder: (context) {
return SideDrawer(children: [
const Spacer(),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'About',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.question_answer,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'Datenschutz',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.privacy_tip,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Row(
children: [
Text(
'Impressum',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.apartment,
color: Colors.white,
),
],
),
),
TextButton(
onPressed: () {
value.logout();
// ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
_snackBar(
context,
value.response.message != null
? value.response.message!
: value.response.status.toString(),
value.response.status.toString(),
() {
print('asdf');
},
),
);
},
child: const Row(
children: [
Text(
'Log out',
style: TextStyle(fontSize: 20),
),
Spacer(),
Icon(
Icons.logout,
color: Colors.white,
),
],
),
),
const SizedBox(
height: 250,
)
]);
}),
bottomNavigationBar: Builder(builder: (context) {
return BottomBar(
// onTap: (value) => _bottomBarAction(value),
children: value.response.data != null
? [
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Personen',
icon: Column(
children: [
IconButton(
onPressed: () =>
Scaffold.of(context).openDrawer(),
icon: const Icon(
Icons.group,
color: Colors.white,
),
),
const Text(
'Personen',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
)
],
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Dashboard',
icon: Column(
children: [
IconButton(
onPressed: () {},
icon: const Icon(
Icons.dashboard,
color: Colors.white,
),
),
const Text(
'Dashboard',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
)
],
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Menu',
icon: IconButton(
onPressed: () {
Scaffold.of(context).openDrawer();
},
icon: const Icon(
Icons.menu,
color: Colors.white,
),
),
)
]
: [
BottomNavigationBarItem(
label: 'register',
backgroundColor: Colors.white,
icon: Column(
children: [
IconButton(
onPressed: () {},
icon: const Icon(
Icons.login,
color: Colors.white,
),
),
const Text(
'Registrieren',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
)
],
),
),
BottomNavigationBarItem(
label: 'login',
backgroundColor: Colors.white,
icon: Column(
children: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (builder) =>
const LoginPage()));
},
icon: const Icon(
Icons.login,
color: Colors.white,
),
),
const Text(
'Login',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
)
],
),
),
BottomNavigationBarItem(
backgroundColor: Colors.white,
label: 'Menu',
icon: IconButton(
onPressed: () => Scaffold.of(context).openDrawer(),
icon: const Icon(
Icons.menu,
color: Colors.white,
),
),
),
],
);
}),
body: Column(
children: [
if (value.response.status == Status.COMPLETED &&
value.response.data != null &&
!(value.response.data as Account).emailVerified)
Card(
color: Colors.orange,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
const Text(
'E-Mail ist noch nicht verifiziert.',
style: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'sans-serif',
fontSize: 14),
),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.restore,
color: Colors.white,
),
),
],
),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Image(
image: AssetImage(
'lib/assets/logo_300x200.png',
),
),
const SizedBox(
height: 40,
),
Text(
'Digitale Spuren auf Knopfdruck entfernen'
.toUpperCase(),
textAlign: TextAlign.center,
style: const TextStyle(
fontFamily: 'sans-serif',
fontSize: 24,
height: 1.6,
fontWeight: FontWeight.normal,
letterSpacing: 6,
),
),
TextButton(
onPressed: () {
// ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
_snackBar(
context,
value.response.message != null
? value.response.message!
: value.response.status.toString(),
value.response.status.toString(),
() {
print('asdf');
},
),
);
},
child: const Text('asdf'))
],
),
),
],
),
);
}),
),
);
}
}

View File

@ -0,0 +1,159 @@
//
// Generated code. Do not modify.
// source: account.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:core' as $core;
import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:protobuf/protobuf.dart' as $pb;
import 'google/protobuf/timestamp.pb.dart' as $27;
class Account extends $pb.GeneratedMessage {
factory Account({
$fixnum.Int64? id,
$core.String? email,
$core.String? secretKey,
$27.Timestamp? emailVerifiedTime,
$core.bool? emailVerified,
$27.Timestamp? privacyAcceptedDate,
$core.int? permissionLevel,
}) {
final $result = create();
if (id != null) {
$result.id = id;
}
if (email != null) {
$result.email = email;
}
if (secretKey != null) {
$result.secretKey = secretKey;
}
if (emailVerifiedTime != null) {
$result.emailVerifiedTime = emailVerifiedTime;
}
if (emailVerified != null) {
$result.emailVerified = emailVerified;
}
if (privacyAcceptedDate != null) {
$result.privacyAcceptedDate = privacyAcceptedDate;
}
if (permissionLevel != null) {
$result.permissionLevel = permissionLevel;
}
return $result;
}
Account._() : super();
factory Account.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Account.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Account', package: const $pb.PackageName(_omitMessageNames ? '' : 'pb'), createEmptyInstance: create)
..a<$fixnum.Int64>(1, _omitFieldNames ? '' : 'id', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO)
..aOS(2, _omitFieldNames ? '' : 'email')
..aOS(3, _omitFieldNames ? '' : 'secretKey')
..aOM<$27.Timestamp>(9, _omitFieldNames ? '' : 'emailVerifiedTime', subBuilder: $27.Timestamp.create)
..aOB(10, _omitFieldNames ? '' : 'emailVerified')
..aOM<$27.Timestamp>(12, _omitFieldNames ? '' : 'privacyAcceptedDate', subBuilder: $27.Timestamp.create)
..a<$core.int>(13, _omitFieldNames ? '' : 'permissionLevel', $pb.PbFieldType.O3)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
Account clone() => Account()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
Account copyWith(void Function(Account) updates) => super.copyWith((message) => updates(message as Account)) as Account;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Account create() => Account._();
Account createEmptyInstance() => create();
static $pb.PbList<Account> createRepeated() => $pb.PbList<Account>();
@$core.pragma('dart2js:noInline')
static Account getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Account>(create);
static Account? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get id => $_getI64(0);
@$pb.TagNumber(1)
set id($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasId() => $_has(0);
@$pb.TagNumber(1)
void clearId() => clearField(1);
@$pb.TagNumber(2)
$core.String get email => $_getSZ(1);
@$pb.TagNumber(2)
set email($core.String v) { $_setString(1, v); }
@$pb.TagNumber(2)
$core.bool hasEmail() => $_has(1);
@$pb.TagNumber(2)
void clearEmail() => clearField(2);
@$pb.TagNumber(3)
$core.String get secretKey => $_getSZ(2);
@$pb.TagNumber(3)
set secretKey($core.String v) { $_setString(2, v); }
@$pb.TagNumber(3)
$core.bool hasSecretKey() => $_has(2);
@$pb.TagNumber(3)
void clearSecretKey() => clearField(3);
@$pb.TagNumber(9)
$27.Timestamp get emailVerifiedTime => $_getN(3);
@$pb.TagNumber(9)
set emailVerifiedTime($27.Timestamp v) { setField(9, v); }
@$pb.TagNumber(9)
$core.bool hasEmailVerifiedTime() => $_has(3);
@$pb.TagNumber(9)
void clearEmailVerifiedTime() => clearField(9);
@$pb.TagNumber(9)
$27.Timestamp ensureEmailVerifiedTime() => $_ensure(3);
@$pb.TagNumber(10)
$core.bool get emailVerified => $_getBF(4);
@$pb.TagNumber(10)
set emailVerified($core.bool v) { $_setBool(4, v); }
@$pb.TagNumber(10)
$core.bool hasEmailVerified() => $_has(4);
@$pb.TagNumber(10)
void clearEmailVerified() => clearField(10);
@$pb.TagNumber(12)
$27.Timestamp get privacyAcceptedDate => $_getN(5);
@$pb.TagNumber(12)
set privacyAcceptedDate($27.Timestamp v) { setField(12, v); }
@$pb.TagNumber(12)
$core.bool hasPrivacyAcceptedDate() => $_has(5);
@$pb.TagNumber(12)
void clearPrivacyAcceptedDate() => clearField(12);
@$pb.TagNumber(12)
$27.Timestamp ensurePrivacyAcceptedDate() => $_ensure(5);
@$pb.TagNumber(13)
$core.int get permissionLevel => $_getIZ(6);
@$pb.TagNumber(13)
set permissionLevel($core.int v) { $_setSignedInt32(6, v); }
@$pb.TagNumber(13)
$core.bool hasPermissionLevel() => $_has(6);
@$pb.TagNumber(13)
void clearPermissionLevel() => clearField(13);
}
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');

View File

@ -0,0 +1,11 @@
//
// Generated code. Do not modify.
// source: account.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import

View File

@ -0,0 +1,52 @@
//
// Generated code. Do not modify.
// source: account.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use accountDescriptor instead')
const Account$json = {
'1': 'Account',
'2': [
{'1': 'id', '3': 1, '4': 1, '5': 4, '10': 'id'},
{'1': 'email', '3': 2, '4': 1, '5': 9, '10': 'email'},
{'1': 'secret_key', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'secretKey', '17': true},
{'1': 'email_verified_time', '3': 9, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '8': {}, '10': 'emailVerifiedTime'},
{'1': 'email_verified', '3': 10, '4': 1, '5': 8, '10': 'emailVerified'},
{'1': 'privacy_accepted_date', '3': 12, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '8': {}, '10': 'privacyAcceptedDate'},
{'1': 'permission_level', '3': 13, '4': 1, '5': 5, '8': {}, '10': 'permissionLevel'},
],
'7': {},
'8': [
{'1': '_secret_key'},
],
};
/// Descriptor for `Account`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List accountDescriptor = $convert.base64Decode(
'CgdBY2NvdW50Eg4KAmlkGAEgASgEUgJpZBIUCgVlbWFpbBgCIAEoCVIFZW1haWwSIgoKc2Vjcm'
'V0X2tleRgDIAEoCUgAUglzZWNyZXRLZXmIAQESZwoTZW1haWxfdmVyaWZpZWRfdGltZRgJIAEo'
'CzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCG5JBGEoWIjIwMjMtMTAtMDVUMDA6MDA6MD'
'BaIlIRZW1haWxWZXJpZmllZFRpbWUSJQoOZW1haWxfdmVyaWZpZWQYCiABKAhSDWVtYWlsVmVy'
'aWZpZWQSawoVcHJpdmFjeV9hY2NlcHRlZF9kYXRlGAwgASgLMhouZ29vZ2xlLnByb3RvYnVmLl'
'RpbWVzdGFtcEIbkkEYShYiMjAyMy0xMC0wNVQwMDowMDowMFoiUhNwcml2YWN5QWNjZXB0ZWRE'
'YXRlEk4KEHBlcm1pc3Npb25fbGV2ZWwYDSABKAVCI5JBIDIeRGVmYXVsdCBpcyAwIChub24tcH'
'JpdmlsZWRnZWQpUg9wZXJtaXNzaW9uTGV2ZWw6vQOSQbkDCgkqB0FjY291bnQyqwN7ImlkIjog'
'IjEiLCJlbWFpbCI6ICJqb2huLmRvZUBleGFtcGxlLmNvbSIsICJmaXJzdG5hbWUiOiAiSm9obi'
'IsICJsYXN0bmFtZSI6ICJEb2UiLCAicGhvbmUiOiAiIiwgInN0cmVldCI6ICJEZWF0aCBTdGFy'
'IDIiLCAiemlwIjogIjA4MTUiLCAiY2l0eSI6ICJOZXcgWW9yayIsICJjb3VudHJ5IjogIlVTQS'
'IsICJiaXJ0aGRheSI6ICIxOTkwLTEwLTA1VDAwOjAwOjAwWiIsICJwcml2YWN5X2FjY2VwdGVk'
'IjogZmFsc2UsICJwcml2YWN5X2FjY2VwdGVkX2RhdGUiOiAiMDAwMS0wMS0wMVQwMDowMDowMF'
'oiLCAiY3JlYXRvciI6ICJqb2huLmRvZUBleGFtcGxlLmNvbSIsICJjcmVhdGVkIjogIjIwMjMt'
'MTAtMDVUMDI6MzA6NTNaIiwgImNoYW5nZXIiOiAiam9obi5kb2VAZXhhbXBsZS5jb20iLCAiY2'
'hhbmdlZCI6ICIyMDIzLTEwLTA1VDAyOjMwOjUzWiJ9Qg0KC19zZWNyZXRfa2V5');

View File

@ -0,0 +1,289 @@
//
// Generated code. Do not modify.
// source: account_info.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:core' as $core;
import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:protobuf/protobuf.dart' as $pb;
import 'google/protobuf/timestamp.pb.dart' as $27;
class AccountInfo extends $pb.GeneratedMessage {
factory AccountInfo({
$fixnum.Int64? accountId,
$core.String? firstname,
$core.String? lastname,
$core.String? street,
$core.String? city,
$core.String? zip,
$core.String? country,
$27.Timestamp? birthday,
$core.String? phone,
$core.bool? privacyAccepted,
$27.Timestamp? privacyAcceptedDate,
$core.int? permissionLevel,
$core.String? creator,
$27.Timestamp? created,
$core.String? changer,
$27.Timestamp? changed,
}) {
final $result = create();
if (accountId != null) {
$result.accountId = accountId;
}
if (firstname != null) {
$result.firstname = firstname;
}
if (lastname != null) {
$result.lastname = lastname;
}
if (street != null) {
$result.street = street;
}
if (city != null) {
$result.city = city;
}
if (zip != null) {
$result.zip = zip;
}
if (country != null) {
$result.country = country;
}
if (birthday != null) {
$result.birthday = birthday;
}
if (phone != null) {
$result.phone = phone;
}
if (privacyAccepted != null) {
$result.privacyAccepted = privacyAccepted;
}
if (privacyAcceptedDate != null) {
$result.privacyAcceptedDate = privacyAcceptedDate;
}
if (permissionLevel != null) {
$result.permissionLevel = permissionLevel;
}
if (creator != null) {
$result.creator = creator;
}
if (created != null) {
$result.created = created;
}
if (changer != null) {
$result.changer = changer;
}
if (changed != null) {
$result.changed = changed;
}
return $result;
}
AccountInfo._() : super();
factory AccountInfo.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory AccountInfo.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'AccountInfo', package: const $pb.PackageName(_omitMessageNames ? '' : 'pb'), createEmptyInstance: create)
..a<$fixnum.Int64>(1, _omitFieldNames ? '' : 'accountId', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO)
..aOS(3, _omitFieldNames ? '' : 'firstname')
..aOS(4, _omitFieldNames ? '' : 'lastname')
..aOS(5, _omitFieldNames ? '' : 'street')
..aOS(6, _omitFieldNames ? '' : 'city')
..aOS(7, _omitFieldNames ? '' : 'zip')
..aOS(8, _omitFieldNames ? '' : 'country')
..aOM<$27.Timestamp>(9, _omitFieldNames ? '' : 'birthday', subBuilder: $27.Timestamp.create)
..aOS(10, _omitFieldNames ? '' : 'phone')
..aOB(11, _omitFieldNames ? '' : 'privacyAccepted')
..aOM<$27.Timestamp>(12, _omitFieldNames ? '' : 'privacyAcceptedDate', subBuilder: $27.Timestamp.create)
..a<$core.int>(13, _omitFieldNames ? '' : 'permissionLevel', $pb.PbFieldType.O3)
..aOS(14, _omitFieldNames ? '' : 'creator')
..aOM<$27.Timestamp>(15, _omitFieldNames ? '' : 'created', subBuilder: $27.Timestamp.create)
..aOS(16, _omitFieldNames ? '' : 'changer')
..aOM<$27.Timestamp>(17, _omitFieldNames ? '' : 'changed', subBuilder: $27.Timestamp.create)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
AccountInfo clone() => AccountInfo()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
AccountInfo copyWith(void Function(AccountInfo) updates) => super.copyWith((message) => updates(message as AccountInfo)) as AccountInfo;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static AccountInfo create() => AccountInfo._();
AccountInfo createEmptyInstance() => create();
static $pb.PbList<AccountInfo> createRepeated() => $pb.PbList<AccountInfo>();
@$core.pragma('dart2js:noInline')
static AccountInfo getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<AccountInfo>(create);
static AccountInfo? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get accountId => $_getI64(0);
@$pb.TagNumber(1)
set accountId($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasAccountId() => $_has(0);
@$pb.TagNumber(1)
void clearAccountId() => clearField(1);
@$pb.TagNumber(3)
$core.String get firstname => $_getSZ(1);
@$pb.TagNumber(3)
set firstname($core.String v) { $_setString(1, v); }
@$pb.TagNumber(3)
$core.bool hasFirstname() => $_has(1);
@$pb.TagNumber(3)
void clearFirstname() => clearField(3);
@$pb.TagNumber(4)
$core.String get lastname => $_getSZ(2);
@$pb.TagNumber(4)
set lastname($core.String v) { $_setString(2, v); }
@$pb.TagNumber(4)
$core.bool hasLastname() => $_has(2);
@$pb.TagNumber(4)
void clearLastname() => clearField(4);
@$pb.TagNumber(5)
$core.String get street => $_getSZ(3);
@$pb.TagNumber(5)
set street($core.String v) { $_setString(3, v); }
@$pb.TagNumber(5)
$core.bool hasStreet() => $_has(3);
@$pb.TagNumber(5)
void clearStreet() => clearField(5);
@$pb.TagNumber(6)
$core.String get city => $_getSZ(4);
@$pb.TagNumber(6)
set city($core.String v) { $_setString(4, v); }
@$pb.TagNumber(6)
$core.bool hasCity() => $_has(4);
@$pb.TagNumber(6)
void clearCity() => clearField(6);
@$pb.TagNumber(7)
$core.String get zip => $_getSZ(5);
@$pb.TagNumber(7)
set zip($core.String v) { $_setString(5, v); }
@$pb.TagNumber(7)
$core.bool hasZip() => $_has(5);
@$pb.TagNumber(7)
void clearZip() => clearField(7);
@$pb.TagNumber(8)
$core.String get country => $_getSZ(6);
@$pb.TagNumber(8)
set country($core.String v) { $_setString(6, v); }
@$pb.TagNumber(8)
$core.bool hasCountry() => $_has(6);
@$pb.TagNumber(8)
void clearCountry() => clearField(8);
@$pb.TagNumber(9)
$27.Timestamp get birthday => $_getN(7);
@$pb.TagNumber(9)
set birthday($27.Timestamp v) { setField(9, v); }
@$pb.TagNumber(9)
$core.bool hasBirthday() => $_has(7);
@$pb.TagNumber(9)
void clearBirthday() => clearField(9);
@$pb.TagNumber(9)
$27.Timestamp ensureBirthday() => $_ensure(7);
@$pb.TagNumber(10)
$core.String get phone => $_getSZ(8);
@$pb.TagNumber(10)
set phone($core.String v) { $_setString(8, v); }
@$pb.TagNumber(10)
$core.bool hasPhone() => $_has(8);
@$pb.TagNumber(10)
void clearPhone() => clearField(10);
@$pb.TagNumber(11)
$core.bool get privacyAccepted => $_getBF(9);
@$pb.TagNumber(11)
set privacyAccepted($core.bool v) { $_setBool(9, v); }
@$pb.TagNumber(11)
$core.bool hasPrivacyAccepted() => $_has(9);
@$pb.TagNumber(11)
void clearPrivacyAccepted() => clearField(11);
@$pb.TagNumber(12)
$27.Timestamp get privacyAcceptedDate => $_getN(10);
@$pb.TagNumber(12)
set privacyAcceptedDate($27.Timestamp v) { setField(12, v); }
@$pb.TagNumber(12)
$core.bool hasPrivacyAcceptedDate() => $_has(10);
@$pb.TagNumber(12)
void clearPrivacyAcceptedDate() => clearField(12);
@$pb.TagNumber(12)
$27.Timestamp ensurePrivacyAcceptedDate() => $_ensure(10);
@$pb.TagNumber(13)
$core.int get permissionLevel => $_getIZ(11);
@$pb.TagNumber(13)
set permissionLevel($core.int v) { $_setSignedInt32(11, v); }
@$pb.TagNumber(13)
$core.bool hasPermissionLevel() => $_has(11);
@$pb.TagNumber(13)
void clearPermissionLevel() => clearField(13);
@$pb.TagNumber(14)
$core.String get creator => $_getSZ(12);
@$pb.TagNumber(14)
set creator($core.String v) { $_setString(12, v); }
@$pb.TagNumber(14)
$core.bool hasCreator() => $_has(12);
@$pb.TagNumber(14)
void clearCreator() => clearField(14);
@$pb.TagNumber(15)
$27.Timestamp get created => $_getN(13);
@$pb.TagNumber(15)
set created($27.Timestamp v) { setField(15, v); }
@$pb.TagNumber(15)
$core.bool hasCreated() => $_has(13);
@$pb.TagNumber(15)
void clearCreated() => clearField(15);
@$pb.TagNumber(15)
$27.Timestamp ensureCreated() => $_ensure(13);
@$pb.TagNumber(16)
$core.String get changer => $_getSZ(14);
@$pb.TagNumber(16)
set changer($core.String v) { $_setString(14, v); }
@$pb.TagNumber(16)
$core.bool hasChanger() => $_has(14);
@$pb.TagNumber(16)
void clearChanger() => clearField(16);
@$pb.TagNumber(17)
$27.Timestamp get changed => $_getN(15);
@$pb.TagNumber(17)
set changed($27.Timestamp v) { setField(17, v); }
@$pb.TagNumber(17)
$core.bool hasChanged() => $_has(15);
@$pb.TagNumber(17)
void clearChanged() => clearField(17);
@$pb.TagNumber(17)
$27.Timestamp ensureChanged() => $_ensure(15);
}
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');

View File

@ -0,0 +1,11 @@
//
// Generated code. Do not modify.
// source: account_info.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import

View File

@ -0,0 +1,64 @@
//
// Generated code. Do not modify.
// source: account_info.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use accountInfoDescriptor instead')
const AccountInfo$json = {
'1': 'AccountInfo',
'2': [
{'1': 'account_id', '3': 1, '4': 1, '5': 4, '10': 'accountId'},
{'1': 'firstname', '3': 3, '4': 1, '5': 9, '10': 'firstname'},
{'1': 'lastname', '3': 4, '4': 1, '5': 9, '10': 'lastname'},
{'1': 'street', '3': 5, '4': 1, '5': 9, '10': 'street'},
{'1': 'city', '3': 6, '4': 1, '5': 9, '10': 'city'},
{'1': 'zip', '3': 7, '4': 1, '5': 9, '10': 'zip'},
{'1': 'country', '3': 8, '4': 1, '5': 9, '10': 'country'},
{'1': 'birthday', '3': 9, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '8': {}, '10': 'birthday'},
{'1': 'phone', '3': 10, '4': 1, '5': 9, '10': 'phone'},
{'1': 'privacy_accepted', '3': 11, '4': 1, '5': 8, '10': 'privacyAccepted'},
{'1': 'privacy_accepted_date', '3': 12, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '8': {}, '10': 'privacyAcceptedDate'},
{'1': 'permission_level', '3': 13, '4': 1, '5': 5, '8': {}, '10': 'permissionLevel'},
{'1': 'creator', '3': 14, '4': 1, '5': 9, '10': 'creator'},
{'1': 'created', '3': 15, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '8': {}, '10': 'created'},
{'1': 'changer', '3': 16, '4': 1, '5': 9, '10': 'changer'},
{'1': 'changed', '3': 17, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '8': {}, '10': 'changed'},
],
'7': {},
};
/// Descriptor for `AccountInfo`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List accountInfoDescriptor = $convert.base64Decode(
'CgtBY2NvdW50SW5mbxIdCgphY2NvdW50X2lkGAEgASgEUglhY2NvdW50SWQSHAoJZmlyc3RuYW'
'1lGAMgASgJUglmaXJzdG5hbWUSGgoIbGFzdG5hbWUYBCABKAlSCGxhc3RuYW1lEhYKBnN0cmVl'
'dBgFIAEoCVIGc3RyZWV0EhIKBGNpdHkYBiABKAlSBGNpdHkSEAoDemlwGAcgASgJUgN6aXASGA'
'oHY291bnRyeRgIIAEoCVIHY291bnRyeRJTCghiaXJ0aGRheRgJIAEoCzIaLmdvb2dsZS5wcm90'
'b2J1Zi5UaW1lc3RhbXBCG5JBGEoWIjE5OTAtMTAtMDVUMDA6MDA6MDBaIlIIYmlydGhkYXkSFA'
'oFcGhvbmUYCiABKAlSBXBob25lEikKEHByaXZhY3lfYWNjZXB0ZWQYCyABKAhSD3ByaXZhY3lB'
'Y2NlcHRlZBJrChVwcml2YWN5X2FjY2VwdGVkX2RhdGUYDCABKAsyGi5nb29nbGUucHJvdG9idW'
'YuVGltZXN0YW1wQhuSQRhKFiIyMDIzLTEwLTA1VDAwOjAwOjAwWiJSE3ByaXZhY3lBY2NlcHRl'
'ZERhdGUSTgoQcGVybWlzc2lvbl9sZXZlbBgNIAEoBUIjkkEgMh5EZWZhdWx0IGlzIDAgKG5vbi'
'1wcml2aWxlZGdlZClSD3Blcm1pc3Npb25MZXZlbBIYCgdjcmVhdG9yGA4gASgJUgdjcmVhdG9y'
'ElEKB2NyZWF0ZWQYDyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQhuSQRhKFiIyMD'
'IzLTEwLTA1VDAwOjAwOjAwWiJSB2NyZWF0ZWQSGAoHY2hhbmdlchgQIAEoCVIHY2hhbmdlchJR'
'CgdjaGFuZ2VkGBEgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEIbkkEYShYiMjAyMy'
'0xMC0wNVQwMDowMDowMFoiUgdjaGFuZ2VkOqkDkkGlAwoNKgtBY2NvdW50SW5mbzKTA3siYWNj'
'b3VudF9pZCI6ICIxIiwgImZpcnN0bmFtZSI6ICJKb2huIiwgImxhc3RuYW1lIjogIkRvZSIsIC'
'JwaG9uZSI6ICIiLCAic3RyZWV0IjogIkRlYXRoIFN0YXIgMiIsICJ6aXAiOiAiMDgxNSIsICJj'
'aXR5IjogIk5ldyBZb3JrIiwgImNvdW50cnkiOiAiVVNBIiwgImJpcnRoZGF5IjogIjE5OTAtMT'
'AtMDVUMDA6MDA6MDBaIiwgInByaXZhY3lfYWNjZXB0ZWQiOiBmYWxzZSwgInByaXZhY3lfYWNj'
'ZXB0ZWRfZGF0ZSI6ICIwMDAxLTAxLTAxVDAwOjAwOjAwWiIsICJjcmVhdG9yIjogImpvaG4uZG'
'9lQGV4YW1wbGUuY29tIiwgImNyZWF0ZWQiOiAiMjAyMy0xMC0wNVQwMjozMDo1M1oiLCAiY2hh'
'bmdlciI6ICJqb2huLmRvZUBleGFtcGxlLmNvbSIsICJjaGFuZ2VkIjogIjIwMjMtMTAtMDVUMD'
'I6MzA6NTNaIn0=');

View File

@ -0,0 +1,259 @@
//
// Generated code. Do not modify.
// source: document.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:core' as $core;
import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:protobuf/protobuf.dart' as $pb;
import 'google/protobuf/timestamp.pb.dart' as $27;
class Document extends $pb.GeneratedMessage {
factory Document({
$fixnum.Int64? personId,
$fixnum.Int64? mailId,
$core.String? name,
$core.String? type,
$core.String? path,
$core.String? url,
$core.bool? valid,
$core.String? validatedBy,
$27.Timestamp? validDate,
$core.String? creator,
$27.Timestamp? created,
$core.String? changer,
$27.Timestamp? changed,
$fixnum.Int64? id,
}) {
final $result = create();
if (personId != null) {
$result.personId = personId;
}
if (mailId != null) {
$result.mailId = mailId;
}
if (name != null) {
$result.name = name;
}
if (type != null) {
$result.type = type;
}
if (path != null) {
$result.path = path;
}
if (url != null) {
$result.url = url;
}
if (valid != null) {
$result.valid = valid;
}
if (validatedBy != null) {
$result.validatedBy = validatedBy;
}
if (validDate != null) {
$result.validDate = validDate;
}
if (creator != null) {
$result.creator = creator;
}
if (created != null) {
$result.created = created;
}
if (changer != null) {
$result.changer = changer;
}
if (changed != null) {
$result.changed = changed;
}
if (id != null) {
$result.id = id;
}
return $result;
}
Document._() : super();
factory Document.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Document.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Document', package: const $pb.PackageName(_omitMessageNames ? '' : 'pb'), createEmptyInstance: create)
..a<$fixnum.Int64>(1, _omitFieldNames ? '' : 'personId', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO)
..a<$fixnum.Int64>(2, _omitFieldNames ? '' : 'mailId', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO)
..aOS(3, _omitFieldNames ? '' : 'name')
..aOS(4, _omitFieldNames ? '' : 'type')
..aOS(5, _omitFieldNames ? '' : 'path')
..aOS(6, _omitFieldNames ? '' : 'url')
..aOB(7, _omitFieldNames ? '' : 'valid')
..aOS(8, _omitFieldNames ? '' : 'validatedBy')
..aOM<$27.Timestamp>(9, _omitFieldNames ? '' : 'validDate', subBuilder: $27.Timestamp.create)
..aOS(10, _omitFieldNames ? '' : 'creator')
..aOM<$27.Timestamp>(11, _omitFieldNames ? '' : 'created', subBuilder: $27.Timestamp.create)
..aOS(12, _omitFieldNames ? '' : 'changer')
..aOM<$27.Timestamp>(13, _omitFieldNames ? '' : 'changed', subBuilder: $27.Timestamp.create)
..a<$fixnum.Int64>(14, _omitFieldNames ? '' : 'id', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
Document clone() => Document()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
Document copyWith(void Function(Document) updates) => super.copyWith((message) => updates(message as Document)) as Document;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Document create() => Document._();
Document createEmptyInstance() => create();
static $pb.PbList<Document> createRepeated() => $pb.PbList<Document>();
@$core.pragma('dart2js:noInline')
static Document getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Document>(create);
static Document? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get personId => $_getI64(0);
@$pb.TagNumber(1)
set personId($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasPersonId() => $_has(0);
@$pb.TagNumber(1)
void clearPersonId() => clearField(1);
@$pb.TagNumber(2)
$fixnum.Int64 get mailId => $_getI64(1);
@$pb.TagNumber(2)
set mailId($fixnum.Int64 v) { $_setInt64(1, v); }
@$pb.TagNumber(2)
$core.bool hasMailId() => $_has(1);
@$pb.TagNumber(2)
void clearMailId() => clearField(2);
@$pb.TagNumber(3)
$core.String get name => $_getSZ(2);
@$pb.TagNumber(3)
set name($core.String v) { $_setString(2, v); }
@$pb.TagNumber(3)
$core.bool hasName() => $_has(2);
@$pb.TagNumber(3)
void clearName() => clearField(3);
@$pb.TagNumber(4)
$core.String get type => $_getSZ(3);
@$pb.TagNumber(4)
set type($core.String v) { $_setString(3, v); }
@$pb.TagNumber(4)
$core.bool hasType() => $_has(3);
@$pb.TagNumber(4)
void clearType() => clearField(4);
@$pb.TagNumber(5)
$core.String get path => $_getSZ(4);
@$pb.TagNumber(5)
set path($core.String v) { $_setString(4, v); }
@$pb.TagNumber(5)
$core.bool hasPath() => $_has(4);
@$pb.TagNumber(5)
void clearPath() => clearField(5);
@$pb.TagNumber(6)
$core.String get url => $_getSZ(5);
@$pb.TagNumber(6)
set url($core.String v) { $_setString(5, v); }
@$pb.TagNumber(6)
$core.bool hasUrl() => $_has(5);
@$pb.TagNumber(6)
void clearUrl() => clearField(6);
@$pb.TagNumber(7)
$core.bool get valid => $_getBF(6);
@$pb.TagNumber(7)
set valid($core.bool v) { $_setBool(6, v); }
@$pb.TagNumber(7)
$core.bool hasValid() => $_has(6);
@$pb.TagNumber(7)
void clearValid() => clearField(7);
@$pb.TagNumber(8)
$core.String get validatedBy => $_getSZ(7);
@$pb.TagNumber(8)
set validatedBy($core.String v) { $_setString(7, v); }
@$pb.TagNumber(8)
$core.bool hasValidatedBy() => $_has(7);
@$pb.TagNumber(8)
void clearValidatedBy() => clearField(8);
@$pb.TagNumber(9)
$27.Timestamp get validDate => $_getN(8);
@$pb.TagNumber(9)
set validDate($27.Timestamp v) { setField(9, v); }
@$pb.TagNumber(9)
$core.bool hasValidDate() => $_has(8);
@$pb.TagNumber(9)
void clearValidDate() => clearField(9);
@$pb.TagNumber(9)
$27.Timestamp ensureValidDate() => $_ensure(8);
@$pb.TagNumber(10)
$core.String get creator => $_getSZ(9);
@$pb.TagNumber(10)
set creator($core.String v) { $_setString(9, v); }
@$pb.TagNumber(10)
$core.bool hasCreator() => $_has(9);
@$pb.TagNumber(10)
void clearCreator() => clearField(10);
@$pb.TagNumber(11)
$27.Timestamp get created => $_getN(10);
@$pb.TagNumber(11)
set created($27.Timestamp v) { setField(11, v); }
@$pb.TagNumber(11)
$core.bool hasCreated() => $_has(10);
@$pb.TagNumber(11)
void clearCreated() => clearField(11);
@$pb.TagNumber(11)
$27.Timestamp ensureCreated() => $_ensure(10);
@$pb.TagNumber(12)
$core.String get changer => $_getSZ(11);
@$pb.TagNumber(12)
set changer($core.String v) { $_setString(11, v); }
@$pb.TagNumber(12)
$core.bool hasChanger() => $_has(11);
@$pb.TagNumber(12)
void clearChanger() => clearField(12);
@$pb.TagNumber(13)
$27.Timestamp get changed => $_getN(12);
@$pb.TagNumber(13)
set changed($27.Timestamp v) { setField(13, v); }
@$pb.TagNumber(13)
$core.bool hasChanged() => $_has(12);
@$pb.TagNumber(13)
void clearChanged() => clearField(13);
@$pb.TagNumber(13)
$27.Timestamp ensureChanged() => $_ensure(12);
@$pb.TagNumber(14)
$fixnum.Int64 get id => $_getI64(13);
@$pb.TagNumber(14)
set id($fixnum.Int64 v) { $_setInt64(13, v); }
@$pb.TagNumber(14)
$core.bool hasId() => $_has(13);
@$pb.TagNumber(14)
void clearId() => clearField(14);
}
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');

View File

@ -0,0 +1,11 @@
//
// Generated code. Do not modify.
// source: document.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import

View File

@ -0,0 +1,55 @@
//
// Generated code. Do not modify.
// source: document.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use documentDescriptor instead')
const Document$json = {
'1': 'Document',
'2': [
{'1': 'person_id', '3': 1, '4': 1, '5': 4, '9': 0, '10': 'personId', '17': true},
{'1': 'mail_id', '3': 2, '4': 1, '5': 4, '9': 1, '10': 'mailId', '17': true},
{'1': 'name', '3': 3, '4': 1, '5': 9, '10': 'name'},
{'1': 'type', '3': 4, '4': 1, '5': 9, '10': 'type'},
{'1': 'path', '3': 5, '4': 1, '5': 9, '10': 'path'},
{'1': 'url', '3': 6, '4': 1, '5': 9, '10': 'url'},
{'1': 'valid', '3': 7, '4': 1, '5': 8, '10': 'valid'},
{'1': 'validated_by', '3': 8, '4': 1, '5': 9, '10': 'validatedBy'},
{'1': 'valid_date', '3': 9, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '8': {}, '10': 'validDate'},
{'1': 'creator', '3': 10, '4': 1, '5': 9, '10': 'creator'},
{'1': 'created', '3': 11, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '8': {}, '10': 'created'},
{'1': 'changer', '3': 12, '4': 1, '5': 9, '10': 'changer'},
{'1': 'changed', '3': 13, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '8': {}, '10': 'changed'},
{'1': 'id', '3': 14, '4': 1, '5': 4, '10': 'id'},
],
'7': {},
'8': [
{'1': '_person_id'},
{'1': '_mail_id'},
],
};
/// Descriptor for `Document`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List documentDescriptor = $convert.base64Decode(
'CghEb2N1bWVudBIgCglwZXJzb25faWQYASABKARIAFIIcGVyc29uSWSIAQESHAoHbWFpbF9pZB'
'gCIAEoBEgBUgZtYWlsSWSIAQESEgoEbmFtZRgDIAEoCVIEbmFtZRISCgR0eXBlGAQgASgJUgR0'
'eXBlEhIKBHBhdGgYBSABKAlSBHBhdGgSEAoDdXJsGAYgASgJUgN1cmwSFAoFdmFsaWQYByABKA'
'hSBXZhbGlkEiEKDHZhbGlkYXRlZF9ieRgIIAEoCVILdmFsaWRhdGVkQnkSVgoKdmFsaWRfZGF0'
'ZRgJIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCG5JBGEoWIjIwMjMtMTAtMDVUMD'
'A6MDA6MDBaIlIJdmFsaWREYXRlEhgKB2NyZWF0b3IYCiABKAlSB2NyZWF0b3ISUQoHY3JlYXRl'
'ZBgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCG5JBGEoWIjIwMjMtMTAtMDVUMD'
'A6MDA6MDBaIlIHY3JlYXRlZBIYCgdjaGFuZ2VyGAwgASgJUgdjaGFuZ2VyElEKB2NoYW5nZWQY'
'DSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQhuSQRhKFiIyMDIzLTEwLTA1VDAwOj'
'AwOjAwWiJSB2NoYW5nZWQSDgoCaWQYDiABKARSAmlkOg+SQQwKCioIRG9jdW1lbnRCDAoKX3Bl'
'cnNvbl9pZEIKCghfbWFpbF9pZA==');

View File

@ -0,0 +1,188 @@
//
// Generated code. Do not modify.
// source: timestamp.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:core' as $core;
import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:protobuf/protobuf.dart' as $pb;
import 'package:protobuf/src/protobuf/mixins/well_known.dart' as $mixin;
/// A Timestamp represents a point in time independent of any time zone or local
/// calendar, encoded as a count of seconds and fractions of seconds at
/// nanosecond resolution. The count is relative to an epoch at UTC midnight on
/// January 1, 1970, in the proleptic Gregorian calendar which extends the
/// Gregorian calendar backwards to year one.
///
/// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
/// second table is needed for interpretation, using a [24-hour linear
/// smear](https://developers.google.com/time/smear).
///
/// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
/// restricting to that range, we ensure that we can convert to and from [RFC
/// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
///
/// # Examples
///
/// Example 1: Compute Timestamp from POSIX `time()`.
///
/// Timestamp timestamp;
/// timestamp.set_seconds(time(NULL));
/// timestamp.set_nanos(0);
///
/// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
///
/// struct timeval tv;
/// gettimeofday(&tv, NULL);
///
/// Timestamp timestamp;
/// timestamp.set_seconds(tv.tv_sec);
/// timestamp.set_nanos(tv.tv_usec * 1000);
///
/// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
///
/// FILETIME ft;
/// GetSystemTimeAsFileTime(&ft);
/// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
///
/// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
/// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
/// Timestamp timestamp;
/// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
/// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
///
/// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
///
/// long millis = System.currentTimeMillis();
///
/// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
/// .setNanos((int) ((millis % 1000) * 1000000)).build();
///
/// Example 5: Compute Timestamp from Java `Instant.now()`.
///
/// Instant now = Instant.now();
///
/// Timestamp timestamp =
/// Timestamp.newBuilder().setSeconds(now.getEpochSecond())
/// .setNanos(now.getNano()).build();
///
/// Example 6: Compute Timestamp from current time in Python.
///
/// timestamp = Timestamp()
/// timestamp.GetCurrentTime()
///
/// # JSON Mapping
///
/// In JSON format, the Timestamp type is encoded as a string in the
/// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
/// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
/// where {year} is always expressed using four digits while {month}, {day},
/// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
/// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
/// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
/// is required. A proto3 JSON serializer should always use UTC (as indicated by
/// "Z") when printing the Timestamp type and a proto3 JSON parser should be
/// able to accept both UTC and other timezones (as indicated by an offset).
///
/// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
/// 01:30 UTC on January 15, 2017.
///
/// In JavaScript, one can convert a Date object to this format using the
/// standard
/// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
/// method. In Python, a standard `datetime.datetime` object can be converted
/// to this format using
/// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
/// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
/// the Joda Time's [`ISODateTimeFormat.dateTime()`](
/// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime()
/// ) to obtain a formatter capable of generating timestamps in this format.
class Timestamp extends $pb.GeneratedMessage with $mixin.TimestampMixin {
factory Timestamp({
$fixnum.Int64? seconds,
$core.int? nanos,
}) {
final $result = create();
if (seconds != null) {
$result.seconds = seconds;
}
if (nanos != null) {
$result.nanos = nanos;
}
return $result;
}
Timestamp._() : super();
factory Timestamp.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Timestamp.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Timestamp', package: const $pb.PackageName(_omitMessageNames ? '' : 'google.protobuf'), createEmptyInstance: create, toProto3Json: $mixin.TimestampMixin.toProto3JsonHelper, fromProto3Json: $mixin.TimestampMixin.fromProto3JsonHelper)
..aInt64(1, _omitFieldNames ? '' : 'seconds')
..a<$core.int>(2, _omitFieldNames ? '' : 'nanos', $pb.PbFieldType.O3)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
Timestamp clone() => Timestamp()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
Timestamp copyWith(void Function(Timestamp) updates) => super.copyWith((message) => updates(message as Timestamp)) as Timestamp;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Timestamp create() => Timestamp._();
Timestamp createEmptyInstance() => create();
static $pb.PbList<Timestamp> createRepeated() => $pb.PbList<Timestamp>();
@$core.pragma('dart2js:noInline')
static Timestamp getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Timestamp>(create);
static Timestamp? _defaultInstance;
/// Represents seconds of UTC time since Unix epoch
/// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
/// 9999-12-31T23:59:59Z inclusive.
@$pb.TagNumber(1)
$fixnum.Int64 get seconds => $_getI64(0);
@$pb.TagNumber(1)
set seconds($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasSeconds() => $_has(0);
@$pb.TagNumber(1)
void clearSeconds() => clearField(1);
/// Non-negative fractions of a second at nanosecond resolution. Negative
/// second values with fractions must still have non-negative nanos values
/// that count forward in time. Must be from 0 to 999,999,999
/// inclusive.
@$pb.TagNumber(2)
$core.int get nanos => $_getIZ(1);
@$pb.TagNumber(2)
set nanos($core.int v) { $_setSignedInt32(1, v); }
@$pb.TagNumber(2)
$core.bool hasNanos() => $_has(1);
@$pb.TagNumber(2)
void clearNanos() => clearField(2);
/// Creates a new instance from [dateTime].
///
/// Time zone information will not be preserved.
static Timestamp fromDateTime($core.DateTime dateTime) {
final result = create();
$mixin.TimestampMixin.setFromDateTime(result, dateTime);
return result;
}
}
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');

View File

@ -0,0 +1,11 @@
//
// Generated code. Do not modify.
// source: timestamp.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import

View File

@ -0,0 +1,29 @@
//
// Generated code. Do not modify.
// source: timestamp.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use timestampDescriptor instead')
const Timestamp$json = {
'1': 'Timestamp',
'2': [
{'1': 'seconds', '3': 1, '4': 1, '5': 3, '10': 'seconds'},
{'1': 'nanos', '3': 2, '4': 1, '5': 5, '10': 'nanos'},
],
};
/// Descriptor for `Timestamp`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List timestampDescriptor = $convert.base64Decode(
'CglUaW1lc3RhbXASGAoHc2Vjb25kcxgBIAEoA1IHc2Vjb25kcxIUCgVuYW5vcxgCIAEoBVIFbm'
'Fub3M=');

View File

@ -0,0 +1,144 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package google.protobuf;
option cc_enable_arenas = true;
option go_package = "google.golang.org/protobuf/types/known/timestamppb";
option java_package = "com.google.protobuf";
option java_outer_classname = "TimestampProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
// A Timestamp represents a point in time independent of any time zone or local
// calendar, encoded as a count of seconds and fractions of seconds at
// nanosecond resolution. The count is relative to an epoch at UTC midnight on
// January 1, 1970, in the proleptic Gregorian calendar which extends the
// Gregorian calendar backwards to year one.
//
// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
// second table is needed for interpretation, using a [24-hour linear
// smear](https://developers.google.com/time/smear).
//
// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
// restricting to that range, we ensure that we can convert to and from [RFC
// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
//
// # Examples
//
// Example 1: Compute Timestamp from POSIX `time()`.
//
// Timestamp timestamp;
// timestamp.set_seconds(time(NULL));
// timestamp.set_nanos(0);
//
// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
//
// struct timeval tv;
// gettimeofday(&tv, NULL);
//
// Timestamp timestamp;
// timestamp.set_seconds(tv.tv_sec);
// timestamp.set_nanos(tv.tv_usec * 1000);
//
// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
//
// FILETIME ft;
// GetSystemTimeAsFileTime(&ft);
// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
//
// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
// Timestamp timestamp;
// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
//
// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
//
// long millis = System.currentTimeMillis();
//
// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
// .setNanos((int) ((millis % 1000) * 1000000)).build();
//
// Example 5: Compute Timestamp from Java `Instant.now()`.
//
// Instant now = Instant.now();
//
// Timestamp timestamp =
// Timestamp.newBuilder().setSeconds(now.getEpochSecond())
// .setNanos(now.getNano()).build();
//
// Example 6: Compute Timestamp from current time in Python.
//
// timestamp = Timestamp()
// timestamp.GetCurrentTime()
//
// # JSON Mapping
//
// In JSON format, the Timestamp type is encoded as a string in the
// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
// where {year} is always expressed using four digits while {month}, {day},
// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
// is required. A proto3 JSON serializer should always use UTC (as indicated by
// "Z") when printing the Timestamp type and a proto3 JSON parser should be
// able to accept both UTC and other timezones (as indicated by an offset).
//
// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
// 01:30 UTC on January 15, 2017.
//
// In JavaScript, one can convert a Date object to this format using the
// standard
// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
// method. In Python, a standard `datetime.datetime` object can be converted
// to this format using
// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
// the Joda Time's [`ISODateTimeFormat.dateTime()`](
// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime()
// ) to obtain a formatter capable of generating timestamps in this format.
//
message Timestamp {
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
int64 seconds = 1;
// Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999
// inclusive.
int32 nanos = 2;
}

View File

@ -0,0 +1,257 @@
//
// Generated code. Do not modify.
// source: payment.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:core' as $core;
import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:protobuf/protobuf.dart' as $pb;
import 'google/protobuf/timestamp.pb.dart' as $27;
class Payment extends $pb.GeneratedMessage {
factory Payment({
$fixnum.Int64? id,
$fixnum.Int64? accountId,
$core.String? paymentCategory,
$core.String? bankname,
$core.String? iBAN,
$core.String? bIC,
$core.String? paypalAccount,
$core.String? paypalId,
$core.String? paymentSystem,
$core.String? type,
$core.String? creator,
$27.Timestamp? created,
$core.String? changer,
$27.Timestamp? changed,
}) {
final $result = create();
if (id != null) {
$result.id = id;
}
if (accountId != null) {
$result.accountId = accountId;
}
if (paymentCategory != null) {
$result.paymentCategory = paymentCategory;
}
if (bankname != null) {
$result.bankname = bankname;
}
if (iBAN != null) {
$result.iBAN = iBAN;
}
if (bIC != null) {
$result.bIC = bIC;
}
if (paypalAccount != null) {
$result.paypalAccount = paypalAccount;
}
if (paypalId != null) {
$result.paypalId = paypalId;
}
if (paymentSystem != null) {
$result.paymentSystem = paymentSystem;
}
if (type != null) {
$result.type = type;
}
if (creator != null) {
$result.creator = creator;
}
if (created != null) {
$result.created = created;
}
if (changer != null) {
$result.changer = changer;
}
if (changed != null) {
$result.changed = changed;
}
return $result;
}
Payment._() : super();
factory Payment.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Payment.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Payment', package: const $pb.PackageName(_omitMessageNames ? '' : 'pb'), createEmptyInstance: create)
..a<$fixnum.Int64>(1, _omitFieldNames ? '' : 'id', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO)
..a<$fixnum.Int64>(2, _omitFieldNames ? '' : 'accountId', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO)
..aOS(3, _omitFieldNames ? '' : 'paymentCategory')
..aOS(4, _omitFieldNames ? '' : 'bankname')
..aOS(5, _omitFieldNames ? '' : 'IBAN', protoName: 'IBAN')
..aOS(6, _omitFieldNames ? '' : 'BIC', protoName: 'BIC')
..aOS(7, _omitFieldNames ? '' : 'paypalAccount')
..aOS(8, _omitFieldNames ? '' : 'paypalId')
..aOS(9, _omitFieldNames ? '' : 'paymentSystem')
..aOS(10, _omitFieldNames ? '' : 'type')
..aOS(11, _omitFieldNames ? '' : 'creator')
..aOM<$27.Timestamp>(12, _omitFieldNames ? '' : 'created', subBuilder: $27.Timestamp.create)
..aOS(13, _omitFieldNames ? '' : 'changer')
..aOM<$27.Timestamp>(14, _omitFieldNames ? '' : 'changed', subBuilder: $27.Timestamp.create)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
Payment clone() => Payment()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
Payment copyWith(void Function(Payment) updates) => super.copyWith((message) => updates(message as Payment)) as Payment;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Payment create() => Payment._();
Payment createEmptyInstance() => create();
static $pb.PbList<Payment> createRepeated() => $pb.PbList<Payment>();
@$core.pragma('dart2js:noInline')
static Payment getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Payment>(create);
static Payment? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get id => $_getI64(0);
@$pb.TagNumber(1)
set id($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasId() => $_has(0);
@$pb.TagNumber(1)
void clearId() => clearField(1);
@$pb.TagNumber(2)
$fixnum.Int64 get accountId => $_getI64(1);
@$pb.TagNumber(2)
set accountId($fixnum.Int64 v) { $_setInt64(1, v); }
@$pb.TagNumber(2)
$core.bool hasAccountId() => $_has(1);
@$pb.TagNumber(2)
void clearAccountId() => clearField(2);
@$pb.TagNumber(3)
$core.String get paymentCategory => $_getSZ(2);
@$pb.TagNumber(3)
set paymentCategory($core.String v) { $_setString(2, v); }
@$pb.TagNumber(3)
$core.bool hasPaymentCategory() => $_has(2);
@$pb.TagNumber(3)
void clearPaymentCategory() => clearField(3);
@$pb.TagNumber(4)
$core.String get bankname => $_getSZ(3);
@$pb.TagNumber(4)
set bankname($core.String v) { $_setString(3, v); }
@$pb.TagNumber(4)
$core.bool hasBankname() => $_has(3);
@$pb.TagNumber(4)
void clearBankname() => clearField(4);
@$pb.TagNumber(5)
$core.String get iBAN => $_getSZ(4);
@$pb.TagNumber(5)
set iBAN($core.String v) { $_setString(4, v); }
@$pb.TagNumber(5)
$core.bool hasIBAN() => $_has(4);
@$pb.TagNumber(5)
void clearIBAN() => clearField(5);
@$pb.TagNumber(6)
$core.String get bIC => $_getSZ(5);
@$pb.TagNumber(6)
set bIC($core.String v) { $_setString(5, v); }
@$pb.TagNumber(6)
$core.bool hasBIC() => $_has(5);
@$pb.TagNumber(6)
void clearBIC() => clearField(6);
@$pb.TagNumber(7)
$core.String get paypalAccount => $_getSZ(6);
@$pb.TagNumber(7)
set paypalAccount($core.String v) { $_setString(6, v); }
@$pb.TagNumber(7)
$core.bool hasPaypalAccount() => $_has(6);
@$pb.TagNumber(7)
void clearPaypalAccount() => clearField(7);
@$pb.TagNumber(8)
$core.String get paypalId => $_getSZ(7);
@$pb.TagNumber(8)
set paypalId($core.String v) { $_setString(7, v); }
@$pb.TagNumber(8)
$core.bool hasPaypalId() => $_has(7);
@$pb.TagNumber(8)
void clearPaypalId() => clearField(8);
@$pb.TagNumber(9)
$core.String get paymentSystem => $_getSZ(8);
@$pb.TagNumber(9)
set paymentSystem($core.String v) { $_setString(8, v); }
@$pb.TagNumber(9)
$core.bool hasPaymentSystem() => $_has(8);
@$pb.TagNumber(9)
void clearPaymentSystem() => clearField(9);
@$pb.TagNumber(10)
$core.String get type => $_getSZ(9);
@$pb.TagNumber(10)
set type($core.String v) { $_setString(9, v); }
@$pb.TagNumber(10)
$core.bool hasType() => $_has(9);
@$pb.TagNumber(10)
void clearType() => clearField(10);
@$pb.TagNumber(11)
$core.String get creator => $_getSZ(10);
@$pb.TagNumber(11)
set creator($core.String v) { $_setString(10, v); }
@$pb.TagNumber(11)
$core.bool hasCreator() => $_has(10);
@$pb.TagNumber(11)
void clearCreator() => clearField(11);
@$pb.TagNumber(12)
$27.Timestamp get created => $_getN(11);
@$pb.TagNumber(12)
set created($27.Timestamp v) { setField(12, v); }
@$pb.TagNumber(12)
$core.bool hasCreated() => $_has(11);
@$pb.TagNumber(12)
void clearCreated() => clearField(12);
@$pb.TagNumber(12)
$27.Timestamp ensureCreated() => $_ensure(11);
@$pb.TagNumber(13)
$core.String get changer => $_getSZ(12);
@$pb.TagNumber(13)
set changer($core.String v) { $_setString(12, v); }
@$pb.TagNumber(13)
$core.bool hasChanger() => $_has(12);
@$pb.TagNumber(13)
void clearChanger() => clearField(13);
@$pb.TagNumber(14)
$27.Timestamp get changed => $_getN(13);
@$pb.TagNumber(14)
set changed($27.Timestamp v) { setField(14, v); }
@$pb.TagNumber(14)
$core.bool hasChanged() => $_has(13);
@$pb.TagNumber(14)
void clearChanged() => clearField(14);
@$pb.TagNumber(14)
$27.Timestamp ensureChanged() => $_ensure(13);
}
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');

View File

@ -0,0 +1,11 @@
//
// Generated code. Do not modify.
// source: payment.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import

View File

@ -0,0 +1,66 @@
//
// Generated code. Do not modify.
// source: payment.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use paymentDescriptor instead')
const Payment$json = {
'1': 'Payment',
'2': [
{'1': 'id', '3': 1, '4': 1, '5': 4, '10': 'id'},
{'1': 'account_id', '3': 2, '4': 1, '5': 4, '10': 'accountId'},
{'1': 'payment_category', '3': 3, '4': 1, '5': 9, '10': 'paymentCategory'},
{'1': 'bankname', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'bankname', '17': true},
{'1': 'IBAN', '3': 5, '4': 1, '5': 9, '9': 1, '10': 'IBAN', '17': true},
{'1': 'BIC', '3': 6, '4': 1, '5': 9, '9': 2, '10': 'BIC', '17': true},
{'1': 'paypal_account', '3': 7, '4': 1, '5': 9, '9': 3, '10': 'paypalAccount', '17': true},
{'1': 'paypal_id', '3': 8, '4': 1, '5': 9, '9': 4, '10': 'paypalId', '17': true},
{'1': 'payment_system', '3': 9, '4': 1, '5': 9, '9': 5, '10': 'paymentSystem', '17': true},
{'1': 'type', '3': 10, '4': 1, '5': 9, '10': 'type'},
{'1': 'creator', '3': 11, '4': 1, '5': 9, '10': 'creator'},
{'1': 'created', '3': 12, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '8': {}, '10': 'created'},
{'1': 'changer', '3': 13, '4': 1, '5': 9, '10': 'changer'},
{'1': 'changed', '3': 14, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '8': {}, '10': 'changed'},
],
'7': {},
'8': [
{'1': '_bankname'},
{'1': '_IBAN'},
{'1': '_BIC'},
{'1': '_paypal_account'},
{'1': '_paypal_id'},
{'1': '_payment_system'},
],
};
/// Descriptor for `Payment`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List paymentDescriptor = $convert.base64Decode(
'CgdQYXltZW50Eg4KAmlkGAEgASgEUgJpZBIdCgphY2NvdW50X2lkGAIgASgEUglhY2NvdW50SW'
'QSKQoQcGF5bWVudF9jYXRlZ29yeRgDIAEoCVIPcGF5bWVudENhdGVnb3J5Eh8KCGJhbmtuYW1l'
'GAQgASgJSABSCGJhbmtuYW1liAEBEhcKBElCQU4YBSABKAlIAVIESUJBTogBARIVCgNCSUMYBi'
'ABKAlIAlIDQklDiAEBEioKDnBheXBhbF9hY2NvdW50GAcgASgJSANSDXBheXBhbEFjY291bnSI'
'AQESIAoJcGF5cGFsX2lkGAggASgJSARSCHBheXBhbElkiAEBEioKDnBheW1lbnRfc3lzdGVtGA'
'kgASgJSAVSDXBheW1lbnRTeXN0ZW2IAQESEgoEdHlwZRgKIAEoCVIEdHlwZRIYCgdjcmVhdG9y'
'GAsgASgJUgdjcmVhdG9yElEKB2NyZWF0ZWQYDCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZX'
'N0YW1wQhuSQRhKFiIyMDIzLTEwLTA1VDAwOjAwOjAwWiJSB2NyZWF0ZWQSGAoHY2hhbmdlchgN'
'IAEoCVIHY2hhbmdlchJRCgdjaGFuZ2VkGA4gASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdG'
'FtcEIbkkEYShYiMjAyMy0xMC0wNVQwMDowMDowMFoiUgdjaGFuZ2VkOu4CkkHqAgoJKgdQYXlt'
'ZW50MtwCeyJpZCI6ICIxIiwiYWNjb3VudF9pZCI6ICIxIiwgInBheW1lbnRfY2F0ZWdvcnkiOi'
'AiVEJEOiBwYXlwYWwiLCAicGF5cGFsX2FjY291bnQiOiAiam9obi5kb2VAZXhhbXBsZS5jb20i'
'LCAicGF5cGFsX2lkIjogInRoaXMtaXMtYS1wYXlwYWwtaWQiLCAicGF5bWVudF9zeXN0ZW0iOi'
'AiVEJEOiBwYXlwYWwgc3lzdGVtIiwgInR5cGUiOiAiVEJEOiBzb21lIHR5cGUiLCAiY3JlYXRv'
'ciI6ICJqb2huLmRvZUBleGFtcGxlLmNvbSIsICJjcmVhdGVkIjogIjIwMjMtMTAtMDVUMDI6Mz'
'A6NTNaIiwgImNoYW5nZXIiOiAiam9obi5kb2VAZXhhbXBsZS5jb20iLCAiY2hhbmdlZCI6ICIy'
'MDIzLTEwLTA1VDAyOjMwOjUzWiJ9QgsKCV9iYW5rbmFtZUIHCgVfSUJBTkIGCgRfQklDQhEKD1'
'9wYXlwYWxfYWNjb3VudEIMCgpfcGF5cGFsX2lkQhEKD19wYXltZW50X3N5c3RlbQ==');

Some files were not shown because too many files have changed in this diff Show More