Compare commits
42 Commits
88021cdade
...
dao
Author | SHA1 | Date | |
---|---|---|---|
604b099010 | |||
c6030f8ac5 | |||
ffd696053a | |||
fb0b73ecaf | |||
1234a300e1 | |||
3153bf13f9 | |||
68443b3427 | |||
5d27744ead | |||
67d7a374d4 | |||
54d47245ae | |||
7f2cf0b49f | |||
8fe60e7ae3 | |||
b2e2eb67b0 | |||
0dc7c3ced0 | |||
13fe7e2ef4 | |||
d6e62024d7 | |||
4094f7edba | |||
586d2355c9 | |||
4e5eeec937 | |||
0c0f596fbb | |||
f781001d3b | |||
19f835d8f2 | |||
56b25a6963 | |||
5bae1aa416 | |||
29479e8aba | |||
9ffa0d178c | |||
932e9cd6a4 | |||
d42696df61 | |||
1564d6cd83 | |||
4fd36246ae | |||
e8e1737875 | |||
baa0f603cf | |||
d7bd755c57 | |||
8890346b59 | |||
a2812b40a0 | |||
1c8f03c97b | |||
b273979ac0 | |||
780e270c15 | |||
e3a09458d8 | |||
6b319a8d96 | |||
0fe3d65bb8 | |||
ec6381f04d |
145
.gitignore
vendored
145
.gitignore
vendored
@ -9,6 +9,7 @@
|
|||||||
.history
|
.history
|
||||||
.svn/
|
.svn/
|
||||||
migrate_working_dir/
|
migrate_working_dir/
|
||||||
|
bkp
|
||||||
|
|
||||||
# IntelliJ related
|
# IntelliJ related
|
||||||
*.iml
|
*.iml
|
||||||
@ -31,6 +32,8 @@ migrate_working_dir/
|
|||||||
.pub-cache/
|
.pub-cache/
|
||||||
.pub/
|
.pub/
|
||||||
/build/
|
/build/
|
||||||
|
pubspec.lock
|
||||||
|
devtools_options.yaml
|
||||||
|
|
||||||
# Symbolication related
|
# Symbolication related
|
||||||
app.*.symbols
|
app.*.symbols
|
||||||
@ -42,3 +45,145 @@ app.*.map.json
|
|||||||
/android/app/debug
|
/android/app/debug
|
||||||
/android/app/profile
|
/android/app/profile
|
||||||
/android/app/release
|
/android/app/release
|
||||||
|
|
||||||
|
|
||||||
|
# Do not remove or rename entries in this file, only add new ones
|
||||||
|
# See https://github.com/flutter/flutter/issues/128635 for more context.
|
||||||
|
|
||||||
|
# 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/api_docs.zip
|
||||||
|
/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-preload-cache/
|
||||||
|
.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
|
||||||
|
**/Flutter/ephemeral/
|
||||||
|
**/Pods/
|
||||||
|
**/macos/Flutter/GeneratedPluginRegistrant.swift
|
||||||
|
**/macos/Flutter/ephemeral
|
||||||
|
**/xcuserdata/
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
**/windows/flutter/ephemeral/
|
||||||
|
**/windows/flutter/generated_plugin_registrant.cc
|
||||||
|
**/windows/flutter/generated_plugin_registrant.h
|
||||||
|
**/windows/flutter/generated_plugins.cmake
|
||||||
|
|
||||||
|
# Linux
|
||||||
|
**/linux/flutter/ephemeral/
|
||||||
|
**/linux/flutter/generated_plugin_registrant.cc
|
||||||
|
**/linux/flutter/generated_plugin_registrant.h
|
||||||
|
**/linux/flutter/generated_plugins.cmake
|
||||||
|
|
||||||
|
# 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
|
||||||
|
!.vscode/settings.json
|
34
.metadata
34
.metadata
@ -1,11 +1,11 @@
|
|||||||
# This file tracks properties of this Flutter project.
|
# This file tracks properties of this Flutter project.
|
||||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
#
|
#
|
||||||
# This file should be version controlled.
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
version:
|
version:
|
||||||
revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
revision: "dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668"
|
||||||
channel: stable
|
channel: "stable"
|
||||||
|
|
||||||
project_type: app
|
project_type: app
|
||||||
|
|
||||||
@ -13,26 +13,26 @@ project_type: app
|
|||||||
migration:
|
migration:
|
||||||
platforms:
|
platforms:
|
||||||
- platform: root
|
- platform: root
|
||||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
- platform: android
|
- platform: android
|
||||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
- platform: ios
|
- platform: ios
|
||||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
- platform: linux
|
- platform: linux
|
||||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
- platform: macos
|
- platform: macos
|
||||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
- platform: web
|
- platform: web
|
||||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
- platform: windows
|
- platform: windows
|
||||||
create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
|
base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
|
||||||
|
|
||||||
# User provided section
|
# User provided section
|
||||||
|
|
||||||
|
74
.vscode/dart.code-snippets
vendored
74
.vscode/dart.code-snippets
vendored
@ -1,74 +0,0 @@
|
|||||||
{
|
|
||||||
// Place your snippets for dart here. Each snippet is defined under a snippet name and has a prefix, body and
|
|
||||||
// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
|
|
||||||
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
|
|
||||||
// same ids are connected.
|
|
||||||
// Example:
|
|
||||||
// "Print to console": {
|
|
||||||
// "prefix": "log",
|
|
||||||
// "body": [
|
|
||||||
// "console.log('$1');",
|
|
||||||
// "$2"
|
|
||||||
// ],
|
|
||||||
// "description": "Log output to console"
|
|
||||||
// }
|
|
||||||
"Stateless Widget": {
|
|
||||||
"prefix": "stateless",
|
|
||||||
"body": [
|
|
||||||
"import 'package:flutter/material.dart';",
|
|
||||||
"\n",
|
|
||||||
"class ${1:MyClass} extends StatelessWidget {",
|
|
||||||
"@override",
|
|
||||||
"Widget build(BuildContext context) {",
|
|
||||||
"return Container($0);}}"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Stateful Widget": {
|
|
||||||
"prefix": "stateful",
|
|
||||||
"body": [
|
|
||||||
"import 'package:flutter/material.dart';",
|
|
||||||
"\n",
|
|
||||||
"class ${1:MyClass} extends StatefulWidget {",
|
|
||||||
"const ${1:MyClass}({Key key, $2}) : super(key: key);",
|
|
||||||
"\n",
|
|
||||||
"@override",
|
|
||||||
"_${1:MyClass}State createState() => _${1:MyClass}State();",
|
|
||||||
"}",
|
|
||||||
"\n",
|
|
||||||
"class _${1:MyClass}State extends State<${1:MyClass}> {",
|
|
||||||
"\n",
|
|
||||||
"@override",
|
|
||||||
"void initState() {",
|
|
||||||
"super.initState();",
|
|
||||||
"}",
|
|
||||||
"\n",
|
|
||||||
"@override",
|
|
||||||
"void dispose() {",
|
|
||||||
"super.dispose();",
|
|
||||||
"}",
|
|
||||||
"\n",
|
|
||||||
"@override",
|
|
||||||
"Widget build(BuildContext context) {",
|
|
||||||
"return Container($0);}}"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Widget Test": {
|
|
||||||
"prefix": "widgettest",
|
|
||||||
"body": [
|
|
||||||
"import 'package:flutter_test/flutter_test.dart';",
|
|
||||||
"import 'package:flutter/material.dart';",
|
|
||||||
"//import 'package:piota/${1:widgetfile}.dart';",
|
|
||||||
"\n",
|
|
||||||
"import 'ui_test_util.dart';",
|
|
||||||
"\n",
|
|
||||||
"void main() {",
|
|
||||||
"group('${2:groupname}', () {",
|
|
||||||
"final testableWidget = testWidget(${3:Container()},Size(375, 667));",
|
|
||||||
"testWidgets('${3:Container()} test', (WidgetTester tester) async {",
|
|
||||||
"final finder = find.byKey(Key('${5:keyname}'));",
|
|
||||||
"await tester.pumpWidget(testableWidget);",
|
|
||||||
"expect(finder, findsOneWidget);",
|
|
||||||
"});});}"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
# SendTrain
|
# SendTrain v0.2.2
|
||||||
|
|
||||||
Mobile app for community driven climbing training and support.
|
Mobile app for community driven climbing training and support.
|
||||||
|
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
# packages, and plugins designed to encourage good coding practices.
|
# packages, and plugins designed to encourage good coding practices.
|
||||||
include: package:flutter_lints/flutter.yaml
|
include: package:flutter_lints/flutter.yaml
|
||||||
|
|
||||||
|
analyzer:
|
||||||
|
exclude:
|
||||||
|
- "**/*.g.dart"
|
||||||
|
|
||||||
linter:
|
linter:
|
||||||
# The lint rules applied to this project can be customized in the
|
# The lint rules applied to this project can be customized in the
|
||||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||||
|
2
android/.gitignore
vendored
2
android/.gitignore
vendored
@ -7,7 +7,7 @@ gradle-wrapper.jar
|
|||||||
GeneratedPluginRegistrant.java
|
GeneratedPluginRegistrant.java
|
||||||
|
|
||||||
# Remember to never publicly share your keystore.
|
# Remember to never publicly share your keystore.
|
||||||
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
|
# See https://flutter.dev/to/reference-keystore
|
||||||
key.properties
|
key.properties
|
||||||
**/*.keystore
|
**/*.keystore
|
||||||
**/*.jks
|
**/*.jks
|
||||||
|
@ -1,71 +1,44 @@
|
|||||||
def localProperties = new Properties()
|
plugins {
|
||||||
def localPropertiesFile = rootProject.file('local.properties')
|
id "com.android.application"
|
||||||
if (localPropertiesFile.exists()) {
|
id "kotlin-android"
|
||||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||||
localProperties.load(reader)
|
id "dev.flutter.flutter-gradle-plugin"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
|
||||||
if (flutterRoot == null) {
|
|
||||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
|
||||||
}
|
|
||||||
|
|
||||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
|
||||||
if (flutterVersionCode == null) {
|
|
||||||
flutterVersionCode = '1'
|
|
||||||
}
|
|
||||||
|
|
||||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
|
||||||
if (flutterVersionName == null) {
|
|
||||||
flutterVersionName = '1.0'
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
|
||||||
apply plugin: 'kotlin-android'
|
|
||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion flutter.compileSdkVersion
|
namespace = "com.example.sendtrain"
|
||||||
ndkVersion flutter.ndkVersion
|
compileSdk = flutter.compileSdkVersion
|
||||||
|
ndkVersion = flutter.ndkVersion
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '1.8'
|
jvmTarget = JavaVersion.VERSION_1_8
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
main.java.srcDirs += 'src/main/kotlin'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
applicationId "com.sendtrain.sendtrain"
|
applicationId = "com.example.sendtrain"
|
||||||
// You can update the following values to match your application needs.
|
// 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.
|
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||||
minSdkVersion flutter.minSdkVersion
|
minSdk = flutter.minSdkVersion
|
||||||
targetSdkVersion flutter.targetSdkVersion
|
targetSdk = flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode = flutter.versionCode
|
||||||
versionName flutterVersionName
|
versionName = flutter.versionName
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
// TODO: Add your own signing config for the release build.
|
// TODO: Add your own signing config for the release build.
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||||
signingConfig signingConfigs.debug
|
signingConfig = signingConfigs.debug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flutter {
|
flutter {
|
||||||
source '../..'
|
source = "../.."
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="com.sendtrain.sendtrain">
|
|
||||||
<!-- The INTERNET permission is required for development. Specifically,
|
<!-- The INTERNET permission is required for development. Specifically,
|
||||||
the Flutter tool needs it to communicate with the running application
|
the Flutter tool needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="com.sendtrain.sendtrain">
|
<application
|
||||||
<application
|
android:label="sendtrain"
|
||||||
android:label="SendTrain"
|
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
|
android:taskAffinity=""
|
||||||
android:theme="@style/LaunchTheme"
|
android:theme="@style/LaunchTheme"
|
||||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
@ -31,4 +31,15 @@
|
|||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
</application>
|
</application>
|
||||||
|
<!-- Required to query activities that can process text, see:
|
||||||
|
https://developer.android.com/training/package-visibility and
|
||||||
|
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
||||||
|
|
||||||
|
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
|
||||||
|
<queries>
|
||||||
|
<intent>
|
||||||
|
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
||||||
|
<data android:mimeType="text/plain"/>
|
||||||
|
</intent>
|
||||||
|
</queries>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.example.sendtrain
|
||||||
|
|
||||||
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
||||||
|
class MainActivity: FlutterActivity()
|
@ -1,6 +0,0 @@
|
|||||||
package com.sendtrain.sendtrain
|
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
|
||||||
|
|
||||||
class MainActivity: FlutterActivity() {
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="com.sendtrain.sendtrain">
|
|
||||||
<!-- The INTERNET permission is required for development. Specifically,
|
<!-- The INTERNET permission is required for development. Specifically,
|
||||||
the Flutter tool needs it to communicate with the running application
|
the Flutter tool needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
|
@ -1,16 +1,3 @@
|
|||||||
buildscript {
|
|
||||||
ext.kotlin_version = '1.7.10'
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:7.2.0'
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
@ -18,12 +5,12 @@ allprojects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rootProject.buildDir = '../build'
|
rootProject.buildDir = "../build"
|
||||||
subprojects {
|
subprojects {
|
||||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||||
}
|
}
|
||||||
subprojects {
|
subprojects {
|
||||||
project.evaluationDependsOn(':app')
|
project.evaluationDependsOn(":app")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register("clean", Delete) {
|
tasks.register("clean", Delete) {
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
org.gradle.jvmargs=-Xmx1536M
|
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
|
||||||
|
@ -1,11 +1,25 @@
|
|||||||
include ':app'
|
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
|
||||||
|
}()
|
||||||
|
|
||||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||||
def properties = new Properties()
|
|
||||||
|
|
||||||
assert localPropertiesFile.exists()
|
repositories {
|
||||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
plugins {
|
||||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
id "com.android.application" version "8.1.0" apply false
|
||||||
|
id "org.jetbrains.kotlin.android" version "2.1.0" apply false
|
||||||
|
}
|
||||||
|
|
||||||
|
include ":app"
|
||||||
|
9
build.yaml
Normal file
9
build.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
targets:
|
||||||
|
$default:
|
||||||
|
builders:
|
||||||
|
drift_dev:
|
||||||
|
options:
|
||||||
|
schema_dir: lib/database/drift_schemas/
|
||||||
|
databases:
|
||||||
|
# Required: A name for the database and it's path
|
||||||
|
sendtrain: lib/database/database.dart
|
@ -1,33 +0,0 @@
|
|||||||
PODS:
|
|
||||||
- Flutter (1.0.0)
|
|
||||||
- flutter_inappwebview (0.0.1):
|
|
||||||
- Flutter
|
|
||||||
- flutter_inappwebview/Core (= 0.0.1)
|
|
||||||
- OrderedSet (~> 5.0)
|
|
||||||
- flutter_inappwebview/Core (0.0.1):
|
|
||||||
- Flutter
|
|
||||||
- OrderedSet (~> 5.0)
|
|
||||||
- OrderedSet (5.0.0)
|
|
||||||
|
|
||||||
DEPENDENCIES:
|
|
||||||
- Flutter (from `Flutter`)
|
|
||||||
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
|
|
||||||
|
|
||||||
SPEC REPOS:
|
|
||||||
trunk:
|
|
||||||
- OrderedSet
|
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
|
||||||
Flutter:
|
|
||||||
:path: Flutter
|
|
||||||
flutter_inappwebview:
|
|
||||||
:path: ".symlinks/plugins/flutter_inappwebview/ios"
|
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
|
||||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
|
||||||
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
|
|
||||||
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
|
|
||||||
|
|
||||||
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
|
|
||||||
|
|
||||||
COCOAPODS: 1.12.0
|
|
12
ios/RunnerTests/RunnerTests.swift
Normal file
12
ios/RunnerTests/RunnerTests.swift
Normal 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.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,15 +1,89 @@
|
|||||||
|
import 'package:sendtrain/classes/media.dart';
|
||||||
|
|
||||||
class ActivityAction {
|
class ActivityAction {
|
||||||
int id;
|
int id;
|
||||||
String title;
|
String title;
|
||||||
String description;
|
String description;
|
||||||
Set activityActionSet;
|
Set activityActionSet;
|
||||||
|
List<Media>? media;
|
||||||
|
|
||||||
ActivityAction({
|
ActivityAction({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.description,
|
required this.description,
|
||||||
required this.activityActionSet,
|
required this.activityActionSet,
|
||||||
|
this.media,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
List<List<Map<String, dynamic>>> items() {
|
||||||
|
List<List<Map<String, dynamic>>> sets = [];
|
||||||
|
Reps reps = activityActionSet.reps;
|
||||||
|
int totalActions = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < activityActionSet.total; i++) {
|
||||||
|
List<Map<String, dynamic>> actions = [];
|
||||||
|
int? weight = _setWeight(i);
|
||||||
|
|
||||||
|
actions.add({
|
||||||
|
'actionID': totalActions++,
|
||||||
|
'name': title,
|
||||||
|
'type': reps.type,
|
||||||
|
'amount': reps.amounts[i],
|
||||||
|
'weight': weight,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (activityActionSet.type == 'alternating') {
|
||||||
|
if (reps.rest != null) {
|
||||||
|
actions.add({
|
||||||
|
'actionID': totalActions++,
|
||||||
|
'name': 'Rest',
|
||||||
|
'type': 'seconds',
|
||||||
|
'amount': reps.rest! ~/ 1000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.add({
|
||||||
|
'actionID': totalActions++,
|
||||||
|
'name': title,
|
||||||
|
'type': reps.type,
|
||||||
|
'amount': reps.amounts[i],
|
||||||
|
'weights': weight,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.add({
|
||||||
|
'actionID': totalActions++,
|
||||||
|
'name': 'Rest',
|
||||||
|
'type': 'seconds',
|
||||||
|
'amount': activityActionSet.rest ~/ 1000,
|
||||||
|
});
|
||||||
|
|
||||||
|
sets.add(actions);
|
||||||
|
|
||||||
|
// sets.add([{
|
||||||
|
// 'actionID': totalActions++,
|
||||||
|
// 'name': 'Rest',
|
||||||
|
// 'type': 'seconds',
|
||||||
|
// 'amount': activityActionSet.rest ~/ 1000,
|
||||||
|
// }]);
|
||||||
|
|
||||||
|
// for (int j = 0; i < activityActionSet.reps.amounts; j++) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sets;
|
||||||
|
}
|
||||||
|
|
||||||
|
int? _setWeight(setNum) {
|
||||||
|
Reps reps = activityActionSet.reps;
|
||||||
|
|
||||||
|
if (reps.weights.length == activityActionSet.total) {
|
||||||
|
return reps.weights[setNum];
|
||||||
|
} else if (reps.weights.length == 1) {
|
||||||
|
return reps.weights[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Set {
|
class Set {
|
||||||
@ -30,14 +104,14 @@ class Reps {
|
|||||||
String type;
|
String type;
|
||||||
List<int> tempo;
|
List<int> tempo;
|
||||||
List<int> amounts;
|
List<int> amounts;
|
||||||
List<int> weights;
|
List<int> weights = [];
|
||||||
int rest;
|
int? rest;
|
||||||
|
|
||||||
Reps({
|
Reps({
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.tempo,
|
required this.tempo,
|
||||||
required this.amounts,
|
required this.amounts,
|
||||||
required this.weights,
|
required this.weights,
|
||||||
required this.rest,
|
this.rest,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
35
lib/daos/actions_dao.dart
Normal file
35
lib/daos/actions_dao.dart
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
|
||||||
|
part 'actions_dao.g.dart';
|
||||||
|
|
||||||
|
@DriftAccessor(tables: [Actions])
|
||||||
|
class ActionsDao extends DatabaseAccessor<AppDatabase> with _$ActionsDaoMixin {
|
||||||
|
ActionsDao(super.db);
|
||||||
|
|
||||||
|
Future<List<Action>> all() async {
|
||||||
|
return await select(actions).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Action> find(int id) async {
|
||||||
|
return await (select(actions)..where((action) => action.id.equals(id) )).getSingle();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<Action>> fromActivity(Activity activity) async {
|
||||||
|
final result = select(db.activityActions).join(
|
||||||
|
[
|
||||||
|
innerJoin(
|
||||||
|
db.actions,
|
||||||
|
db.actions.id.equalsExp(db.activityActions.actionId),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
..where(db.activityActions.activityId.equals(activity.id));
|
||||||
|
|
||||||
|
final actions = (await result.get())
|
||||||
|
.map((e) => e.readTable(db.actions))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
}
|
8
lib/daos/actions_dao.g.dart
Normal file
8
lib/daos/actions_dao.g.dart
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'actions_dao.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
mixin _$ActionsDaoMixin on DatabaseAccessor<AppDatabase> {
|
||||||
|
$ActionsTable get actions => attachedDatabase.actions;
|
||||||
|
}
|
35
lib/daos/activities_dao.dart
Normal file
35
lib/daos/activities_dao.dart
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
|
||||||
|
part 'activities_dao.g.dart';
|
||||||
|
|
||||||
|
@DriftAccessor(tables: [Activities])
|
||||||
|
class ActivitiesDao extends DatabaseAccessor<AppDatabase> with _$ActivitiesDaoMixin {
|
||||||
|
ActivitiesDao(super.db);
|
||||||
|
|
||||||
|
Future<List<Activity>> all() async {
|
||||||
|
return await select(activities).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Activity> find(int id) async {
|
||||||
|
return await (select(activities)..where((activity) => activity.id.equals(id) )).getSingle();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<Activity>> sessionActivities(int id) async {
|
||||||
|
final result = select(db.sessionActivities).join(
|
||||||
|
[
|
||||||
|
innerJoin(
|
||||||
|
db.activities,
|
||||||
|
db.activities.id
|
||||||
|
.equalsExp(db.sessionActivities.activityId),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)..where(db.sessionActivities.sessionId.equals(id));
|
||||||
|
|
||||||
|
final activities = (await result.get())
|
||||||
|
.map((e) => e.readTable(db.activities))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
return activities;
|
||||||
|
}
|
||||||
|
}
|
8
lib/daos/activities_dao.g.dart
Normal file
8
lib/daos/activities_dao.g.dart
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'activities_dao.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
mixin _$ActivitiesDaoMixin on DatabaseAccessor<AppDatabase> {
|
||||||
|
$ActivitiesTable get activities => attachedDatabase.activities;
|
||||||
|
}
|
30
lib/daos/activity_actions_dao.dart
Normal file
30
lib/daos/activity_actions_dao.dart
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
|
||||||
|
part 'activity_actions_dao.g.dart';
|
||||||
|
|
||||||
|
@DriftAccessor(tables: [ActivityActions])
|
||||||
|
class ActivityActionsDao extends DatabaseAccessor<AppDatabase> with _$ActivityActionsDaoMixin {
|
||||||
|
ActivityActionsDao(super.db);
|
||||||
|
|
||||||
|
Future<List<ActivityAction>> all() => select(activityActions).get();
|
||||||
|
Stream<List<ActivityAction>> watch() => select(activityActions).watch();
|
||||||
|
Future insert(ActivityAction activityAction) => into(activityActions).insert(activityAction);
|
||||||
|
Future replace(ActivityAction activityAction) => update(activityActions).replace(activityAction);
|
||||||
|
Future remove(ActivityAction activityAction) => delete(activityActions).delete(activityAction);
|
||||||
|
|
||||||
|
// Future<List<ActivityAction>> all() async {
|
||||||
|
// return await select(activityActions).get();
|
||||||
|
// }
|
||||||
|
|
||||||
|
Future<ActivityAction> find(int id) async {
|
||||||
|
return await (select(activityActions)..where((activityAction) => activityAction.id.equals(id) )).getSingle();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<ActivityAction>> fromActivityId(int id) async {
|
||||||
|
final result = db.managers.activityActions
|
||||||
|
.filter((activityAction) => activityAction.activityId.id(id));
|
||||||
|
|
||||||
|
return result.get();
|
||||||
|
}
|
||||||
|
}
|
10
lib/daos/activity_actions_dao.g.dart
Normal file
10
lib/daos/activity_actions_dao.g.dart
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'activity_actions_dao.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
mixin _$ActivityActionsDaoMixin on DatabaseAccessor<AppDatabase> {
|
||||||
|
$ActivitiesTable get activities => attachedDatabase.activities;
|
||||||
|
$ActionsTable get actions => attachedDatabase.actions;
|
||||||
|
$ActivityActionsTable get activityActions => attachedDatabase.activityActions;
|
||||||
|
}
|
57
lib/daos/media_items_dao.dart
Normal file
57
lib/daos/media_items_dao.dart
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
|
||||||
|
part 'media_items_dao.g.dart';
|
||||||
|
|
||||||
|
@DriftAccessor(tables: [MediaItems])
|
||||||
|
class MediaItemsDao extends DatabaseAccessor<AppDatabase> with _$MediaItemsDaoMixin {
|
||||||
|
MediaItemsDao(super.db);
|
||||||
|
|
||||||
|
Future<List<MediaItem>> all() async {
|
||||||
|
return await select(mediaItems).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<MediaItem> find(int id) async {
|
||||||
|
return await (select(mediaItems)..where((mediaItem) => mediaItem.id.equals(id) )).getSingle();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<MediaItem>> fromActivity(Activity activity) async {
|
||||||
|
final result = select(db.objectMediaItems).join(
|
||||||
|
[
|
||||||
|
innerJoin(
|
||||||
|
db.mediaItems,
|
||||||
|
db.mediaItems.id.equalsExp(db.objectMediaItems.mediaId),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
..where(
|
||||||
|
db.objectMediaItems.objectType.equals(ObjectType.activities.name))
|
||||||
|
..where(db.objectMediaItems.objectId.equals(activity.id));
|
||||||
|
|
||||||
|
final mediaItems = (await result.get())
|
||||||
|
.map((e) => e.readTable(db.mediaItems))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
return mediaItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<MediaItem>> fromSession(Session session) async {
|
||||||
|
final result = select(db.objectMediaItems).join(
|
||||||
|
[
|
||||||
|
innerJoin(
|
||||||
|
db.mediaItems,
|
||||||
|
db.mediaItems.id.equalsExp(db.objectMediaItems.mediaId),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
..where(
|
||||||
|
db.objectMediaItems.objectType.equals(ObjectType.sessions.name))
|
||||||
|
..where(db.objectMediaItems.objectId.equals(session.id));
|
||||||
|
|
||||||
|
final mediaItems = (await result.get())
|
||||||
|
.map((e) => e.readTable(db.mediaItems))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
return mediaItems;
|
||||||
|
}
|
||||||
|
}
|
8
lib/daos/media_items_dao.g.dart
Normal file
8
lib/daos/media_items_dao.g.dart
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'media_items_dao.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
mixin _$MediaItemsDaoMixin on DatabaseAccessor<AppDatabase> {
|
||||||
|
$MediaItemsTable get mediaItems => attachedDatabase.mediaItems;
|
||||||
|
}
|
24
lib/daos/session_activities_dao.dart
Normal file
24
lib/daos/session_activities_dao.dart
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
|
||||||
|
part 'session_activities_dao.g.dart';
|
||||||
|
|
||||||
|
@DriftAccessor(tables: [SessionActivities])
|
||||||
|
class SessionActivitiesDao extends DatabaseAccessor<AppDatabase> with _$SessionActivitiesDaoMixin {
|
||||||
|
SessionActivitiesDao(super.db);
|
||||||
|
|
||||||
|
Future<List<SessionActivity>> all() async {
|
||||||
|
return await select(sessionActivities).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<SessionActivity> find(int id) async {
|
||||||
|
return await (select(sessionActivities)..where((sessionActivity) => sessionActivity.id.equals(id) )).getSingle();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<SessionActivity>> fromSessionId(int id) async {
|
||||||
|
final result = db.managers.sessionActivities
|
||||||
|
.filter((sessionActivity) => sessionActivity.sessionId.id(id));
|
||||||
|
|
||||||
|
return result.get();
|
||||||
|
}
|
||||||
|
}
|
11
lib/daos/session_activities_dao.g.dart
Normal file
11
lib/daos/session_activities_dao.g.dart
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'session_activities_dao.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
mixin _$SessionActivitiesDaoMixin on DatabaseAccessor<AppDatabase> {
|
||||||
|
$SessionsTable get sessions => attachedDatabase.sessions;
|
||||||
|
$ActivitiesTable get activities => attachedDatabase.activities;
|
||||||
|
$SessionActivitiesTable get sessionActivities =>
|
||||||
|
attachedDatabase.sessionActivities;
|
||||||
|
}
|
17
lib/daos/sessions_dao.dart
Normal file
17
lib/daos/sessions_dao.dart
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
|
||||||
|
part 'sessions_dao.g.dart';
|
||||||
|
|
||||||
|
@DriftAccessor(tables: [Sessions])
|
||||||
|
class SessionsDao extends DatabaseAccessor<AppDatabase> with _$SessionsDaoMixin {
|
||||||
|
SessionsDao(super.db);
|
||||||
|
|
||||||
|
Future<List<Session>> all() async {
|
||||||
|
return await select(sessions).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Session> find(int id) async {
|
||||||
|
return await (select(sessions)..where((session) => session.id.equals(id) )).getSingle();
|
||||||
|
}
|
||||||
|
}
|
8
lib/daos/sessions_dao.g.dart
Normal file
8
lib/daos/sessions_dao.g.dart
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'sessions_dao.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
mixin _$SessionsDaoMixin on DatabaseAccessor<AppDatabase> {
|
||||||
|
$SessionsTable get sessions => attachedDatabase.sessions;
|
||||||
|
}
|
151
lib/database/database.dart
Normal file
151
lib/database/database.dart
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:drift_flutter/drift_flutter.dart';
|
||||||
|
import 'package:sendtrain/daos/actions_dao.dart';
|
||||||
|
import 'package:sendtrain/daos/activities_dao.dart';
|
||||||
|
import 'package:sendtrain/daos/activity_actions_dao.dart';
|
||||||
|
import 'package:sendtrain/daos/media_items_dao.dart';
|
||||||
|
import 'package:sendtrain/daos/session_activities_dao.dart';
|
||||||
|
import 'package:sendtrain/daos/sessions_dao.dart';
|
||||||
|
import 'package:sendtrain/database/seed.dart';
|
||||||
|
|
||||||
|
part 'database.g.dart';
|
||||||
|
|
||||||
|
@DriftDatabase(tables: [
|
||||||
|
Sessions,
|
||||||
|
SessionActivities,
|
||||||
|
Activities,
|
||||||
|
ActivityActions,
|
||||||
|
Actions,
|
||||||
|
ObjectMediaItems,
|
||||||
|
MediaItems
|
||||||
|
], daos: [
|
||||||
|
SessionsDao,
|
||||||
|
ActivitiesDao,
|
||||||
|
MediaItemsDao,
|
||||||
|
SessionActivitiesDao,
|
||||||
|
ActivityActionsDao,
|
||||||
|
ActionsDao
|
||||||
|
])
|
||||||
|
class AppDatabase extends _$AppDatabase {
|
||||||
|
// After generating code, this class needs to define a `schemaVersion` getter
|
||||||
|
// and a constructor telling drift where the database should be stored.
|
||||||
|
// These are described in the getting started guide: https://drift.simonbinder.eu/setup/
|
||||||
|
AppDatabase() : super(_openConnection());
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get schemaVersion => 4;
|
||||||
|
|
||||||
|
@override
|
||||||
|
MigrationStrategy get migration {
|
||||||
|
return MigrationStrategy(
|
||||||
|
onCreate: (m) async {
|
||||||
|
await m.createAll().then((r) async {
|
||||||
|
await seedDb(this);
|
||||||
|
}); // create all tables
|
||||||
|
},
|
||||||
|
beforeOpen: (details) async {
|
||||||
|
/// Enable foreign_keys
|
||||||
|
await customStatement('PRAGMA foreign_keys = ON');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QueryExecutor _openConnection() {
|
||||||
|
// `driftDatabase` from `package:drift_flutter` stores the database in
|
||||||
|
// `getApplicationDocumentsDirectory()`.
|
||||||
|
return driftDatabase(name: 'sendtrain');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SessionStatus { pending, started, completed, missed }
|
||||||
|
|
||||||
|
class Sessions extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
TextColumn get title => text().withLength(min: 3, max: 32)();
|
||||||
|
TextColumn get content => text().named('body')();
|
||||||
|
TextColumn get status => textEnum<SessionStatus>()();
|
||||||
|
DateTimeColumn get date => dateTime().nullable()();
|
||||||
|
DateTimeColumn get createdAt =>
|
||||||
|
dateTime().withDefault(Variable(DateTime.now()))();
|
||||||
|
}
|
||||||
|
|
||||||
|
class SessionActivities extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
IntColumn get sessionId => integer().references(Sessions, #id)();
|
||||||
|
IntColumn get activityId => integer().references(Activities, #id)();
|
||||||
|
IntColumn get position => integer()();
|
||||||
|
TextColumn get results => text().nullable()();
|
||||||
|
TextColumn get achievements => text().nullable()();
|
||||||
|
DateTimeColumn get createdAt =>
|
||||||
|
dateTime().withDefault(Variable(DateTime.now()))();
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ActivityCategories { fundamentals, conditioning, advanced, custom, pro }
|
||||||
|
|
||||||
|
enum ActivityType {
|
||||||
|
strength,
|
||||||
|
power,
|
||||||
|
conditioning,
|
||||||
|
hypertrophy,
|
||||||
|
endurance,
|
||||||
|
stability,
|
||||||
|
mobility,
|
||||||
|
flexibility,
|
||||||
|
rehabilitation,
|
||||||
|
technical
|
||||||
|
}
|
||||||
|
|
||||||
|
class Activities extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
TextColumn get title => text().withLength(min: 3, max: 32)();
|
||||||
|
TextColumn get type => textEnum<ActivityType>()();
|
||||||
|
TextColumn get description => text().named('body')();
|
||||||
|
TextColumn get category => textEnum<ActivityCategories>()();
|
||||||
|
DateTimeColumn get createdAt =>
|
||||||
|
dateTime().withDefault(Variable(DateTime.now()))();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ActivityActions extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
IntColumn get activityId => integer().references(Activities, #id)();
|
||||||
|
IntColumn get actionId => integer().references(Actions, #id)();
|
||||||
|
IntColumn get position => integer()();
|
||||||
|
DateTimeColumn get createdAt =>
|
||||||
|
dateTime().withDefault(Variable(DateTime.now()))();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Actions extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
TextColumn get title => text().withLength(min: 3, max: 32)();
|
||||||
|
TextColumn get description => text().named('body')();
|
||||||
|
TextColumn get set => text()();
|
||||||
|
DateTimeColumn get createdAt =>
|
||||||
|
dateTime().withDefault(Variable(DateTime.now()))();
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ObjectType {
|
||||||
|
actions,
|
||||||
|
activities,
|
||||||
|
sessions,
|
||||||
|
}
|
||||||
|
|
||||||
|
class ObjectMediaItems extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
IntColumn get objectId => integer()();
|
||||||
|
TextColumn get objectType => textEnum<ObjectType>()();
|
||||||
|
IntColumn get mediaId => integer().references(MediaItems, #id)();
|
||||||
|
DateTimeColumn get createdAt =>
|
||||||
|
dateTime().withDefault(Variable(DateTime.now()))();
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MediaType { youtube, image }
|
||||||
|
|
||||||
|
class MediaItems extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
TextColumn get title => text().withLength(min: 3, max: 32)();
|
||||||
|
TextColumn get description => text().named('body')();
|
||||||
|
TextColumn get reference => text().withLength(min: 3, max: 256)();
|
||||||
|
TextColumn get type => textEnum<MediaType>()();
|
||||||
|
DateTimeColumn get createdAt =>
|
||||||
|
dateTime().withDefault(Variable(DateTime.now()))();
|
||||||
|
}
|
4519
lib/database/database.g.dart
Normal file
4519
lib/database/database.g.dart
Normal file
File diff suppressed because it is too large
Load Diff
688
lib/database/database.steps.dart
Normal file
688
lib/database/database.steps.dart
Normal file
@ -0,0 +1,688 @@
|
|||||||
|
// dart format width=80
|
||||||
|
import 'package:drift/internal/versioned_schema.dart' as i0;
|
||||||
|
import 'package:drift/drift.dart' as i1;
|
||||||
|
import 'package:drift/drift.dart'; // ignore_for_file: type=lint,unused_import
|
||||||
|
|
||||||
|
// GENERATED BY drift_dev, DO NOT MODIFY.
|
||||||
|
final class Schema2 extends i0.VersionedSchema {
|
||||||
|
Schema2({required super.database}) : super(version: 2);
|
||||||
|
@override
|
||||||
|
late final List<i1.DatabaseSchemaEntity> entities = [
|
||||||
|
sessions,
|
||||||
|
activities,
|
||||||
|
sessionActivities,
|
||||||
|
actions,
|
||||||
|
activityActions,
|
||||||
|
mediaItems,
|
||||||
|
objectMediaItems,
|
||||||
|
];
|
||||||
|
late final Shape0 sessions = Shape0(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'sessions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_2,
|
||||||
|
_column_3,
|
||||||
|
_column_4,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape1 activities = Shape1(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'activities',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_6,
|
||||||
|
_column_2,
|
||||||
|
_column_7,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape2 sessionActivities = Shape2(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'session_activities',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_8,
|
||||||
|
_column_9,
|
||||||
|
_column_10,
|
||||||
|
_column_11,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape3 actions = Shape3(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'actions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_2,
|
||||||
|
_column_12,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape4 activityActions = Shape4(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'activity_actions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_9,
|
||||||
|
_column_13,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape5 mediaItems = Shape5(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'media_items',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_2,
|
||||||
|
_column_14,
|
||||||
|
_column_6,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape6 objectMediaItems = Shape6(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'object_media_items',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_15,
|
||||||
|
_column_16,
|
||||||
|
_column_17,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Shape0 extends i0.VersionedTable {
|
||||||
|
Shape0({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get title =>
|
||||||
|
columnsByName['title']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get content =>
|
||||||
|
columnsByName['body']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get status =>
|
||||||
|
columnsByName['status']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<DateTime> get date =>
|
||||||
|
columnsByName['date']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<int> _column_0(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('id', aliasedName, false,
|
||||||
|
hasAutoIncrement: true,
|
||||||
|
type: i1.DriftSqlType.int,
|
||||||
|
defaultConstraints:
|
||||||
|
i1.GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
|
||||||
|
i1.GeneratedColumn<String> _column_1(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('title', aliasedName, false,
|
||||||
|
additionalChecks: i1.GeneratedColumn.checkTextLength(
|
||||||
|
minTextLength: 3, maxTextLength: 32),
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<String> _column_2(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('body', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<String> _column_3(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('status', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<DateTime> _column_4(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<DateTime>('date', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.dateTime);
|
||||||
|
i1.GeneratedColumn<DateTime> _column_5(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<DateTime>('created_at', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.dateTime, defaultValue: Variable(DateTime.now()));
|
||||||
|
|
||||||
|
class Shape1 extends i0.VersionedTable {
|
||||||
|
Shape1({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get title =>
|
||||||
|
columnsByName['title']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get type =>
|
||||||
|
columnsByName['type']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get description =>
|
||||||
|
columnsByName['body']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get category =>
|
||||||
|
columnsByName['category']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<String> _column_6(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('type', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<String> _column_7(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('category', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
|
||||||
|
class Shape2 extends i0.VersionedTable {
|
||||||
|
Shape2({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get sessionId =>
|
||||||
|
columnsByName['session_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get activityId =>
|
||||||
|
columnsByName['activity_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get results =>
|
||||||
|
columnsByName['results']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get achievements =>
|
||||||
|
columnsByName['achievements']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<int> _column_8(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('session_id', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int,
|
||||||
|
defaultConstraints:
|
||||||
|
i1.GeneratedColumn.constraintIsAlways('REFERENCES sessions (id)'));
|
||||||
|
i1.GeneratedColumn<int> _column_9(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('activity_id', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int,
|
||||||
|
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||||
|
'REFERENCES activities (id)'));
|
||||||
|
i1.GeneratedColumn<String> _column_10(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('results', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<String> _column_11(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('achievements', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
|
||||||
|
class Shape3 extends i0.VersionedTable {
|
||||||
|
Shape3({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get title =>
|
||||||
|
columnsByName['title']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get description =>
|
||||||
|
columnsByName['body']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get set =>
|
||||||
|
columnsByName['set']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<String> _column_12(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('set', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
|
||||||
|
class Shape4 extends i0.VersionedTable {
|
||||||
|
Shape4({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get activityId =>
|
||||||
|
columnsByName['activity_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get actionId =>
|
||||||
|
columnsByName['action_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<int> _column_13(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('action_id', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int,
|
||||||
|
defaultConstraints:
|
||||||
|
i1.GeneratedColumn.constraintIsAlways('REFERENCES actions (id)'));
|
||||||
|
|
||||||
|
class Shape5 extends i0.VersionedTable {
|
||||||
|
Shape5({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get title =>
|
||||||
|
columnsByName['title']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get description =>
|
||||||
|
columnsByName['body']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get reference =>
|
||||||
|
columnsByName['reference']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get type =>
|
||||||
|
columnsByName['type']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<String> _column_14(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('reference', aliasedName, false,
|
||||||
|
additionalChecks: i1.GeneratedColumn.checkTextLength(
|
||||||
|
minTextLength: 3, maxTextLength: 256),
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
|
||||||
|
class Shape6 extends i0.VersionedTable {
|
||||||
|
Shape6({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get objectId =>
|
||||||
|
columnsByName['object_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get objectType =>
|
||||||
|
columnsByName['object_type']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<int> get mediaId =>
|
||||||
|
columnsByName['media_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<int> _column_15(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('object_id', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int);
|
||||||
|
i1.GeneratedColumn<String> _column_16(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('object_type', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<int> _column_17(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('media_id', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int,
|
||||||
|
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||||
|
'REFERENCES media_items (id)'));
|
||||||
|
|
||||||
|
final class Schema3 extends i0.VersionedSchema {
|
||||||
|
Schema3({required super.database}) : super(version: 3);
|
||||||
|
@override
|
||||||
|
late final List<i1.DatabaseSchemaEntity> entities = [
|
||||||
|
sessions,
|
||||||
|
activities,
|
||||||
|
sessionActivities,
|
||||||
|
actions,
|
||||||
|
activityActions,
|
||||||
|
mediaItems,
|
||||||
|
objectMediaItems,
|
||||||
|
];
|
||||||
|
late final Shape0 sessions = Shape0(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'sessions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_2,
|
||||||
|
_column_3,
|
||||||
|
_column_4,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape1 activities = Shape1(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'activities',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_6,
|
||||||
|
_column_2,
|
||||||
|
_column_7,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape7 sessionActivities = Shape7(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'session_activities',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_8,
|
||||||
|
_column_9,
|
||||||
|
_column_18,
|
||||||
|
_column_10,
|
||||||
|
_column_11,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape3 actions = Shape3(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'actions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_2,
|
||||||
|
_column_12,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape8 activityActions = Shape8(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'activity_actions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_9,
|
||||||
|
_column_13,
|
||||||
|
_column_18,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape5 mediaItems = Shape5(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'media_items',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_2,
|
||||||
|
_column_14,
|
||||||
|
_column_6,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape6 objectMediaItems = Shape6(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'object_media_items',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_15,
|
||||||
|
_column_16,
|
||||||
|
_column_17,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Shape7 extends i0.VersionedTable {
|
||||||
|
Shape7({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get sessionId =>
|
||||||
|
columnsByName['session_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get activityId =>
|
||||||
|
columnsByName['activity_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get postition =>
|
||||||
|
columnsByName['postition']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get results =>
|
||||||
|
columnsByName['results']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get achievements =>
|
||||||
|
columnsByName['achievements']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<int> _column_18(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('postition', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int);
|
||||||
|
|
||||||
|
class Shape8 extends i0.VersionedTable {
|
||||||
|
Shape8({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get activityId =>
|
||||||
|
columnsByName['activity_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get actionId =>
|
||||||
|
columnsByName['action_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get postition =>
|
||||||
|
columnsByName['postition']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class Schema4 extends i0.VersionedSchema {
|
||||||
|
Schema4({required super.database}) : super(version: 4);
|
||||||
|
@override
|
||||||
|
late final List<i1.DatabaseSchemaEntity> entities = [
|
||||||
|
sessions,
|
||||||
|
activities,
|
||||||
|
sessionActivities,
|
||||||
|
actions,
|
||||||
|
activityActions,
|
||||||
|
mediaItems,
|
||||||
|
objectMediaItems,
|
||||||
|
];
|
||||||
|
late final Shape0 sessions = Shape0(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'sessions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_2,
|
||||||
|
_column_3,
|
||||||
|
_column_4,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape1 activities = Shape1(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'activities',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_6,
|
||||||
|
_column_2,
|
||||||
|
_column_7,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape9 sessionActivities = Shape9(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'session_activities',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_8,
|
||||||
|
_column_9,
|
||||||
|
_column_19,
|
||||||
|
_column_10,
|
||||||
|
_column_11,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape3 actions = Shape3(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'actions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_2,
|
||||||
|
_column_12,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape10 activityActions = Shape10(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'activity_actions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_9,
|
||||||
|
_column_13,
|
||||||
|
_column_19,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape5 mediaItems = Shape5(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'media_items',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_2,
|
||||||
|
_column_14,
|
||||||
|
_column_6,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape6 objectMediaItems = Shape6(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'object_media_items',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_15,
|
||||||
|
_column_16,
|
||||||
|
_column_17,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Shape9 extends i0.VersionedTable {
|
||||||
|
Shape9({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get sessionId =>
|
||||||
|
columnsByName['session_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get activityId =>
|
||||||
|
columnsByName['activity_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get position =>
|
||||||
|
columnsByName['position']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get results =>
|
||||||
|
columnsByName['results']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get achievements =>
|
||||||
|
columnsByName['achievements']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<int> _column_19(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('position', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int);
|
||||||
|
|
||||||
|
class Shape10 extends i0.VersionedTable {
|
||||||
|
Shape10({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get activityId =>
|
||||||
|
columnsByName['activity_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get actionId =>
|
||||||
|
columnsByName['action_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get position =>
|
||||||
|
columnsByName['position']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i0.MigrationStepWithVersion migrationSteps({
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema4 schema) from3To4,
|
||||||
|
}) {
|
||||||
|
return (currentVersion, database) async {
|
||||||
|
switch (currentVersion) {
|
||||||
|
case 1:
|
||||||
|
final schema = Schema2(database: database);
|
||||||
|
final migrator = i1.Migrator(database, schema);
|
||||||
|
await from1To2(migrator, schema);
|
||||||
|
return 2;
|
||||||
|
case 2:
|
||||||
|
final schema = Schema3(database: database);
|
||||||
|
final migrator = i1.Migrator(database, schema);
|
||||||
|
await from2To3(migrator, schema);
|
||||||
|
return 3;
|
||||||
|
case 3:
|
||||||
|
final schema = Schema4(database: database);
|
||||||
|
final migrator = i1.Migrator(database, schema);
|
||||||
|
await from3To4(migrator, schema);
|
||||||
|
return 4;
|
||||||
|
default:
|
||||||
|
throw ArgumentError.value('Unknown migration from $currentVersion');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.OnUpgrade stepByStep({
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema4 schema) from3To4,
|
||||||
|
}) =>
|
||||||
|
i0.VersionedSchema.stepByStepHelper(
|
||||||
|
step: migrationSteps(
|
||||||
|
from1To2: from1To2,
|
||||||
|
from2To3: from2To3,
|
||||||
|
from3To4: from3To4,
|
||||||
|
));
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
167
lib/database/seed.dart
Normal file
167
lib/database/seed.dart
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
|
||||||
|
Future<void> seedDb(AppDatabase database) async {
|
||||||
|
// seed data setup
|
||||||
|
final List<List> sessionValues = [
|
||||||
|
[
|
||||||
|
'Projecting @ Climbers Rock',
|
||||||
|
'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Moonboard @ Boardroom',
|
||||||
|
'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Off-Wall Training',
|
||||||
|
'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Climbing Outdoors',
|
||||||
|
'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Volume Session @ Gravity',
|
||||||
|
'Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.'
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
final List<List> mediaItems = [
|
||||||
|
[
|
||||||
|
'https://www.climbing.com/wp-content/uploads/2022/06/campus-board-e1655470701154.jpeg',
|
||||||
|
MediaType.image
|
||||||
|
],
|
||||||
|
['BgheYcxhrsw', MediaType.youtube]
|
||||||
|
];
|
||||||
|
|
||||||
|
final List<String> actionTypes = [
|
||||||
|
"[[{\"actionID\": 0, \"name\": \"1, 3, 5\", \"type\": \"repititions\", \"amount\": 1, \"weight\": 0}, {\"actionID\": 1, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 300}], [{\"actionID\": 2, \"name\": \"1, 3, 5\", \"type\": \"repititions\", \"amount\": 1, \"weight\": 0}, {\"actionID\": 3, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 300}], [{\"actionID\": 4, \"name\": \"1, 3, 5\", \"type\": \"repititions\", \"amount\": 1, \"weight\": 0}, {\"actionID\": 5, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 300}]]",
|
||||||
|
"[[{\"actionID\": 0, \"name\": \"Long Pulls\", \"type\": \"seconds\", \"amount\": 5, \"weight\": 80}, {\"actionID\": 1, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 5}, {\"actionID\": 2, \"name\": \"Long Pulls\", \"type\": \"seconds\", \"amount\": 5, \"weights\": 80}, {\"actionID\": 3, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 300}], [{\"actionID\": 4, \"name\": \"Long Pulls\", \"type\": \"seconds\", \"amount\": 5, \"weight\": 80}, {\"actionID\": 5, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 5}, {\"actionID\": 6, \"name\": \"Long Pulls\", \"type\": \"seconds\", \"amount\": 5, \"weights\": 80}, {\"actionID\": 7, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 300}], [{\"actionID\": 8, \"name\": \"Long Pulls\", \"type\": \"seconds\", \"amount\": 5, \"weight\": 80}, {\"actionID\": 9, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 5}, {\"actionID\": 10, \"name\": \"Long Pulls\", \"type\": \"seconds\", \"amount\": 5, \"weights\": 80}, {\"actionID\": 11, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 300}], [{\"actionID\": 12, \"name\": \"Long Pulls\", \"type\": \"seconds\", \"amount\": 5, \"weight\": 80}, {\"actionID\": 13, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 5}, {\"actionID\": 14, \"name\": \"Long Pulls\", \"type\": \"seconds\", \"amount\": 5, \"weights\": 80}, {\"actionID\": 15, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 300}], [{\"actionID\": 16, \"name\": \"Long Pulls\", \"type\": \"seconds\", \"amount\": 5, \"weight\": 80}, {\"actionID\": 17, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 5}, {\"actionID\": 18, \"name\": \"Long Pulls\", \"type\": \"seconds\", \"amount\": 5, \"weights\": 80}, {\"actionID\": 19, \"name\": \"Rest\", \"type\": \"seconds\", \"amount\": 300}]]"
|
||||||
|
];
|
||||||
|
|
||||||
|
final int totalSessions = 15;
|
||||||
|
final int totalActivities = 6;
|
||||||
|
final int totalActions = 5;
|
||||||
|
final int totalMedia = 5;
|
||||||
|
final random = Random();
|
||||||
|
|
||||||
|
// seed loop
|
||||||
|
for (int i = 0; i < totalSessions; i++) {
|
||||||
|
// session things
|
||||||
|
var status = SessionStatus.completed;
|
||||||
|
if (i == 0) status = SessionStatus.started;
|
||||||
|
if (i == 1) status = SessionStatus.pending;
|
||||||
|
|
||||||
|
final sessionValue = sessionValues[random.nextInt(sessionValues.length)];
|
||||||
|
await database
|
||||||
|
.into(database.sessions)
|
||||||
|
.insert(SessionsCompanion.insert(
|
||||||
|
title: sessionValue[0],
|
||||||
|
content: sessionValue[1],
|
||||||
|
status: status,
|
||||||
|
date: Value(DateTime.now())))
|
||||||
|
.then((sessionId) async {
|
||||||
|
// activities things
|
||||||
|
for (int j = 0; j <= random.nextInt(totalActivities); j++) {
|
||||||
|
await database
|
||||||
|
.into(database.activities)
|
||||||
|
.insert(ActivitiesCompanion.insert(
|
||||||
|
title: "Test activity $j",
|
||||||
|
type: ActivityType
|
||||||
|
.values[random.nextInt(ActivityType.values.length)],
|
||||||
|
description:
|
||||||
|
"$j Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.",
|
||||||
|
category: ActivityCategories
|
||||||
|
.values[random.nextInt(ActivityCategories.values.length)]))
|
||||||
|
.then((activityId) async {
|
||||||
|
// session activity relationships
|
||||||
|
await database
|
||||||
|
.into(database.sessionActivities)
|
||||||
|
.insert(SessionActivitiesCompanion.insert(
|
||||||
|
sessionId: sessionId,
|
||||||
|
activityId: activityId,
|
||||||
|
position: j,
|
||||||
|
results: Value("results json, will need to test"),
|
||||||
|
achievements: Value("comma, seperated, items"),
|
||||||
|
));
|
||||||
|
|
||||||
|
// actions
|
||||||
|
for (int k = 0; k <= random.nextInt(totalActions); k++) {
|
||||||
|
await database
|
||||||
|
.into(database.actions)
|
||||||
|
.insert(ActionsCompanion.insert(
|
||||||
|
title: 'Test action $k',
|
||||||
|
description:
|
||||||
|
'$k Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.',
|
||||||
|
set: actionTypes[random.nextInt(actionTypes.length)]))
|
||||||
|
.then((actionId) async {
|
||||||
|
// add activity action association
|
||||||
|
await database.into(database.activityActions).insert(
|
||||||
|
ActivityActionsCompanion.insert(
|
||||||
|
activityId: activityId, actionId: actionId, position: k));
|
||||||
|
|
||||||
|
for (int l = 0; l <= random.nextInt(totalMedia); l++) {
|
||||||
|
final mediaItem = mediaItems[random.nextInt(mediaItems.length)];
|
||||||
|
await database
|
||||||
|
.into(database.mediaItems)
|
||||||
|
.insert(MediaItemsCompanion.insert(
|
||||||
|
title: 'Media title $l',
|
||||||
|
description:
|
||||||
|
'Media description $l Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.',
|
||||||
|
reference: mediaItem[0],
|
||||||
|
type: mediaItem[1]))
|
||||||
|
.then((mediaId) async {
|
||||||
|
await database.into(database.objectMediaItems).insert(
|
||||||
|
ObjectMediaItemsCompanion.insert(
|
||||||
|
objectId: actionId,
|
||||||
|
mediaId: mediaId,
|
||||||
|
objectType: ObjectType.actions));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int m = 0; m <= random.nextInt(totalMedia); m++) {
|
||||||
|
final mediaItem = mediaItems[random.nextInt(mediaItems.length)];
|
||||||
|
await database
|
||||||
|
.into(database.mediaItems)
|
||||||
|
.insert(MediaItemsCompanion.insert(
|
||||||
|
title: 'Media title $m',
|
||||||
|
description:
|
||||||
|
'Media description $m Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.',
|
||||||
|
reference: mediaItem[0],
|
||||||
|
type: mediaItem[1]))
|
||||||
|
.then((mediaId) async {
|
||||||
|
await database.into(database.objectMediaItems).insert(
|
||||||
|
ObjectMediaItemsCompanion.insert(
|
||||||
|
objectId: activityId,
|
||||||
|
mediaId: mediaId,
|
||||||
|
objectType: ObjectType.activities));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int n = 0; n <= random.nextInt(totalMedia); n++) {
|
||||||
|
final mediaItem = mediaItems[random.nextInt(mediaItems.length)];
|
||||||
|
await database
|
||||||
|
.into(database.mediaItems)
|
||||||
|
.insert(MediaItemsCompanion.insert(
|
||||||
|
title: 'Media title $n',
|
||||||
|
description:
|
||||||
|
'Media description $n Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.',
|
||||||
|
reference: mediaItem[0],
|
||||||
|
type: mediaItem[1]))
|
||||||
|
.then((mediaId) async {
|
||||||
|
await database.into(database.objectMediaItems).insert(
|
||||||
|
ObjectMediaItemsCompanion.insert(
|
||||||
|
objectId: sessionId,
|
||||||
|
mediaId: mediaId,
|
||||||
|
objectType: ObjectType.sessions));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
1
lib/database/sendtrain/drift_schema_v1.json
Normal file
1
lib/database/sendtrain/drift_schema_v1.json
Normal file
File diff suppressed because one or more lines are too long
84
lib/extensions/string_extensions.dart
Normal file
84
lib/extensions/string_extensions.dart
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
List<String> exceptions = [
|
||||||
|
'a',
|
||||||
|
'abaft',
|
||||||
|
'about',
|
||||||
|
'above',
|
||||||
|
'afore',
|
||||||
|
'after',
|
||||||
|
'along',
|
||||||
|
'amid',
|
||||||
|
'among',
|
||||||
|
'an',
|
||||||
|
'apud',
|
||||||
|
'as',
|
||||||
|
'aside',
|
||||||
|
'at',
|
||||||
|
'atop',
|
||||||
|
'below',
|
||||||
|
'but',
|
||||||
|
'by',
|
||||||
|
'circa',
|
||||||
|
'down',
|
||||||
|
'for',
|
||||||
|
'from',
|
||||||
|
'given',
|
||||||
|
'in',
|
||||||
|
'into',
|
||||||
|
'lest',
|
||||||
|
'like',
|
||||||
|
'mid',
|
||||||
|
'midst',
|
||||||
|
'minus',
|
||||||
|
'near',
|
||||||
|
'next',
|
||||||
|
'of',
|
||||||
|
'off',
|
||||||
|
'on',
|
||||||
|
'onto',
|
||||||
|
'out',
|
||||||
|
'over',
|
||||||
|
'pace',
|
||||||
|
'past',
|
||||||
|
'per',
|
||||||
|
'plus',
|
||||||
|
'pro',
|
||||||
|
'qua',
|
||||||
|
'round',
|
||||||
|
'sans',
|
||||||
|
'save',
|
||||||
|
'since',
|
||||||
|
'than',
|
||||||
|
'thru',
|
||||||
|
'till',
|
||||||
|
'times',
|
||||||
|
'to',
|
||||||
|
'under',
|
||||||
|
'until',
|
||||||
|
'unto',
|
||||||
|
'up',
|
||||||
|
'upon',
|
||||||
|
'via',
|
||||||
|
'vice',
|
||||||
|
'with',
|
||||||
|
'worth',
|
||||||
|
'the","and',
|
||||||
|
'nor',
|
||||||
|
'or',
|
||||||
|
'yet',
|
||||||
|
'so'
|
||||||
|
];
|
||||||
|
|
||||||
|
extension TitleCase on String {
|
||||||
|
String toTitleCase() {
|
||||||
|
return toLowerCase().replaceAllMapped(
|
||||||
|
RegExp(
|
||||||
|
r'[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+'),
|
||||||
|
(Match match) {
|
||||||
|
|
||||||
|
// if (exceptions.contains(match[0])) {
|
||||||
|
// return match[0]!;
|
||||||
|
// }
|
||||||
|
return "${match[0]![0].toUpperCase()}${match[0]!.substring(1).toLowerCase()}";
|
||||||
|
}).replaceAll(RegExp(r'(_|-)+'), ' ');
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
import 'package:sendtrain/models/activity_timer_model.dart';
|
||||||
import 'package:sendtrain/screens/activities_screen.dart';
|
import 'package:sendtrain/screens/activities_screen.dart';
|
||||||
import 'package:sendtrain/screens/sessions_screen.dart';
|
import 'package:sendtrain/screens/sessions_screen.dart';
|
||||||
|
// ignore: unused_import
|
||||||
|
import 'package:sendtrain/database/seed.dart';
|
||||||
|
|
||||||
class SendTrain extends StatelessWidget {
|
class SendTrain extends StatelessWidget {
|
||||||
const SendTrain({super.key});
|
const SendTrain({super.key});
|
||||||
@ -42,7 +47,7 @@ class _AppState extends State<App> {
|
|||||||
body: Padding(
|
body: Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(0, 50, 0, 0),
|
padding: const EdgeInsets.fromLTRB(0, 50, 0, 0),
|
||||||
child: <Widget>[
|
child: <Widget>[
|
||||||
const SessionsScreen(),
|
SessionsScreen(),
|
||||||
const ActivitiesScreen(),
|
const ActivitiesScreen(),
|
||||||
Container(
|
Container(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
@ -88,5 +93,13 @@ class _AppState extends State<App> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const SendTrain());
|
runApp(MultiProvider(
|
||||||
|
providers: [
|
||||||
|
ChangeNotifierProvider(create: (context) => ActivityTimerModel()),
|
||||||
|
Provider<AppDatabase>(
|
||||||
|
create: (context) => AppDatabase(),
|
||||||
|
dispose: (context, db) => db.close()),
|
||||||
|
],
|
||||||
|
child: const SendTrain(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
165
lib/models/activity_timer_model.dart
Normal file
165
lib/models/activity_timer_model.dart
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
|
||||||
|
class ActivityTimerModel with ChangeNotifier {
|
||||||
|
int _actionCounter = 0;
|
||||||
|
Activity? _activity;
|
||||||
|
List _sets = [];
|
||||||
|
List _actions = [];
|
||||||
|
int _currentActionNum = 0;
|
||||||
|
int _currentSetNum = 0;
|
||||||
|
Timer? _periodicTimer;
|
||||||
|
double _progress = 0;
|
||||||
|
ItemScrollController? _isc;
|
||||||
|
int _totalTime = 0;
|
||||||
|
|
||||||
|
int get actionCount => _actionCounter;
|
||||||
|
int get currentActionNum => _currentActionNum;
|
||||||
|
dynamic get currentAction => currentSet[_currentActionNum];
|
||||||
|
int get currentSetNum => _currentSetNum;
|
||||||
|
dynamic get currentSet => _sets[_currentSetNum];
|
||||||
|
Activity? get activity => _activity;
|
||||||
|
List get sets => _sets;
|
||||||
|
Timer? get periodicTimer => _periodicTimer;
|
||||||
|
bool get isActive => _isActive();
|
||||||
|
double get progress => _progress;
|
||||||
|
int get totalTime => _totalTime;
|
||||||
|
|
||||||
|
void setup(Activity activity, List actions) {
|
||||||
|
if (_activity == null || activity.id != _activity?.id) {
|
||||||
|
_periodicTimer?.cancel();
|
||||||
|
_progress = 0;
|
||||||
|
_isc = null;
|
||||||
|
_activity = activity;
|
||||||
|
// only one action for now
|
||||||
|
_sets = json.decode(actions[0].set);
|
||||||
|
_actions = actions;
|
||||||
|
_currentActionNum = 0;
|
||||||
|
_currentSetNum = 0;
|
||||||
|
setActionCount();
|
||||||
|
getTotalTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
moveToIndex(_currentSetNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void getTotalTime() {
|
||||||
|
int time = 0;
|
||||||
|
for(int setIndex = 0; _sets.length > setIndex; setIndex++) {
|
||||||
|
for (int actionIndex = 0; _sets[setIndex].length > actionIndex; actionIndex++) {
|
||||||
|
var action = _sets[setIndex][actionIndex];
|
||||||
|
if (action['type'] == 'seconds') {
|
||||||
|
time = time + action['amount'] as int;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_totalTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
_progress = 0;
|
||||||
|
_currentActionNum = 0;
|
||||||
|
_currentSetNum = 0;
|
||||||
|
_periodicTimer!.cancel();
|
||||||
|
setActionCount();
|
||||||
|
moveToIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setScrollController(ItemScrollController isc) {
|
||||||
|
_isc = isc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isCurrentItem(int setNum, int actionNum) {
|
||||||
|
if (setNum == _currentSetNum && actionNum == _currentActionNum) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int totalActions() {
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < _sets.length; i++) {
|
||||||
|
count = count + _sets[i].length as int;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setActionCount() {
|
||||||
|
_actionCounter = currentAction['amount'];
|
||||||
|
}
|
||||||
|
|
||||||
|
void pause() {
|
||||||
|
_periodicTimer!.cancel();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
_periodicTimer = Timer.periodic(const Duration(seconds: 1), (Timer timer) {
|
||||||
|
switch (currentAction['type']) {
|
||||||
|
// we don't want to count down
|
||||||
|
// if its repititions
|
||||||
|
case 'repititions':
|
||||||
|
break;
|
||||||
|
case 'seconds':
|
||||||
|
if (_actionCounter > 0) {
|
||||||
|
_actionCounter--;
|
||||||
|
_totalTime--;
|
||||||
|
} else {
|
||||||
|
nextAction(_currentActionNum + 1);
|
||||||
|
setActionCount();
|
||||||
|
}
|
||||||
|
updateProgress();
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateProgress() {
|
||||||
|
_progress = (currentAction['actionID'] +
|
||||||
|
(1.0 - _actionCounter / currentAction['amount'])) /
|
||||||
|
totalActions();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAction(int setNum, int actionNum, String type) {
|
||||||
|
_currentActionNum = actionNum;
|
||||||
|
_currentSetNum = setNum;
|
||||||
|
notifyListeners();
|
||||||
|
moveToIndex(_currentSetNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nextAction(int nextActionIndex) {
|
||||||
|
if (currentSet.length > nextActionIndex) {
|
||||||
|
setAction(_currentSetNum, nextActionIndex, 'automatic');
|
||||||
|
} else if (_sets.length > _currentSetNum + 1) {
|
||||||
|
// if the item isn't in the set
|
||||||
|
// increment the set and reset action index
|
||||||
|
setAction(_currentSetNum + 1, 0, 'automatic');
|
||||||
|
} else {
|
||||||
|
// if we're done all the sets
|
||||||
|
// cancel timer and reset activity
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void moveToIndex(int index) {
|
||||||
|
if (_isc != null && _isc!.isAttached) {
|
||||||
|
_isc?.scrollTo(
|
||||||
|
index: index,
|
||||||
|
duration: Duration(milliseconds: 500),
|
||||||
|
curve: Curves.easeInOutCubic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isActive() {
|
||||||
|
return (_periodicTimer != null && _periodicTimer!.isActive) ? true : false;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:sendtrain/classes/activity_action.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart' hide ActivityAction;
|
||||||
|
import 'package:sendtrain/models/activity_model.dart';
|
||||||
|
|
||||||
import '../widgets/activities_header.dart';
|
import '../widgets/activities_header.dart';
|
||||||
import '../widgets/activity_card.dart';
|
import '../widgets/activity_card.dart';
|
||||||
@ -11,25 +14,52 @@ class ActivitiesScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ActivitiesScreenState extends State<ActivitiesScreen> {
|
class _ActivitiesScreenState extends State<ActivitiesScreen> {
|
||||||
|
final Activity? activity = null;
|
||||||
|
|
||||||
|
final data = ActivityModel(
|
||||||
|
id: 1,
|
||||||
|
categories: ['power'],
|
||||||
|
description: 'description',
|
||||||
|
title: 'activity',
|
||||||
|
type: 'fundamentals',
|
||||||
|
actions: List.generate(
|
||||||
|
10,
|
||||||
|
(i) => ActivityAction(
|
||||||
|
id: 1,
|
||||||
|
title: 'test action',
|
||||||
|
description: 'test description',
|
||||||
|
activityActionSet: Set(
|
||||||
|
type: 'drop_set',
|
||||||
|
total: 3,
|
||||||
|
rest: 300000,
|
||||||
|
reps: Reps(
|
||||||
|
type: 'count',
|
||||||
|
tempo: [2, 3, 5],
|
||||||
|
amounts: [5, 3, 2],
|
||||||
|
weights: [50, 70, 80],
|
||||||
|
rest: 20000))),
|
||||||
|
));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<Widget> activities = List.generate(10, (i) => ActivityCard());
|
return Text("N/A");
|
||||||
|
// List<Widget> activities = List.generate(10, (i) => ActivityCard(activity: data, data: activity));
|
||||||
|
|
||||||
return Padding(
|
// return Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(10, 15, 10, 0),
|
// padding: const EdgeInsets.fromLTRB(10, 15, 10, 0),
|
||||||
child: Column(
|
// child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
// children: <Widget>[
|
||||||
const ActivitiesHeader(),
|
// const ActivitiesHeader(),
|
||||||
Expanded(
|
// Expanded(
|
||||||
child: GridView.count(
|
// child: GridView.count(
|
||||||
primary: false,
|
// primary: false,
|
||||||
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
|
// padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
|
||||||
crossAxisSpacing: 10,
|
// crossAxisSpacing: 10,
|
||||||
mainAxisSpacing: 10,
|
// mainAxisSpacing: 10,
|
||||||
crossAxisCount: 2,
|
// crossAxisCount: 2,
|
||||||
children: activities,
|
// children: activities,
|
||||||
))
|
// ))
|
||||||
]));
|
// ]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:sendtrain/daos/sessions_dao.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
import '../widgets/session_card.dart';
|
import '../widgets/session_card.dart';
|
||||||
|
|
||||||
class SessionsScreen extends StatelessWidget {
|
class SessionsScreen extends StatelessWidget {
|
||||||
@ -6,47 +9,68 @@ class SessionsScreen extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<Widget> previousSessions =
|
return FutureBuilder<List<Session>>(
|
||||||
List.generate(10, (i) => const SessionCard(state: 1, type: 1));
|
future: SessionsDao(Provider.of<AppDatabase>(context)).all(),
|
||||||
Widget upcomingSession = const SessionCard(state: 2);
|
builder: (context, snapshot) {
|
||||||
Widget currentSession = const SessionCard();
|
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
||||||
|
final sessions = snapshot.data!;
|
||||||
|
final pending = sessions.where((session) =>
|
||||||
|
session.status == SessionStatus.completed ||
|
||||||
|
session.status == SessionStatus.missed);
|
||||||
|
final upcoming = sessions.firstWhere(
|
||||||
|
(session) => session.status == SessionStatus.pending);
|
||||||
|
final current = sessions.firstWhere(
|
||||||
|
(session) => session.status == SessionStatus.started);
|
||||||
|
|
||||||
return Column(
|
List<Widget> previousSessions = List.generate(pending.length,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
(i) => SessionCard(type: 1, session: pending.elementAt(i)));
|
||||||
children: <Widget>[
|
Widget upcomingSession = SessionCard(session: upcoming);
|
||||||
const Padding(
|
Widget currentSession = SessionCard(session: current);
|
||||||
padding: EdgeInsets.fromLTRB(15, 5, 0, 0),
|
|
||||||
child: Text(
|
return Column(
|
||||||
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
'Current:')),
|
children: <Widget>[
|
||||||
currentSession,
|
const Padding(
|
||||||
const Padding(
|
padding: EdgeInsets.fromLTRB(15, 5, 0, 0),
|
||||||
padding: EdgeInsets.fromLTRB(15, 30, 0, 0),
|
child: Text(
|
||||||
child: Text(
|
style: TextStyle(
|
||||||
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
|
fontSize: 25, fontWeight: FontWeight.bold),
|
||||||
'Upcoming:')),
|
'Current:')),
|
||||||
upcomingSession,
|
currentSession,
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.fromLTRB(15, 30, 0, 0),
|
padding: EdgeInsets.fromLTRB(15, 30, 0, 0),
|
||||||
child: Text(
|
child: Text(
|
||||||
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
|
style: TextStyle(
|
||||||
'Previous:')),
|
fontSize: 25, fontWeight: FontWeight.bold),
|
||||||
SizedBox(
|
'Upcoming:')),
|
||||||
width: double.infinity,
|
upcomingSession,
|
||||||
height: 160,
|
const Padding(
|
||||||
child: GridView.count(
|
padding: EdgeInsets.fromLTRB(15, 30, 0, 0),
|
||||||
padding: const EdgeInsets.fromLTRB(15, 10, 0, 0),
|
child: Text(
|
||||||
scrollDirection: Axis.horizontal,
|
style: TextStyle(
|
||||||
crossAxisSpacing: 5,
|
fontSize: 25, fontWeight: FontWeight.bold),
|
||||||
mainAxisSpacing: 5,
|
'Previous:')),
|
||||||
crossAxisCount: 1,
|
SizedBox(
|
||||||
children: previousSessions))
|
width: double.infinity,
|
||||||
// Flexible(
|
height: 160,
|
||||||
// child: ListView(
|
child: GridView.count(
|
||||||
// scrollDirection: Axis.vertical,
|
padding: const EdgeInsets.fromLTRB(15, 10, 0, 0),
|
||||||
// children: previousSessions,
|
scrollDirection: Axis.horizontal,
|
||||||
// )),
|
crossAxisSpacing: 5,
|
||||||
],
|
mainAxisSpacing: 5,
|
||||||
);
|
crossAxisCount: 1,
|
||||||
|
children: previousSessions))
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 50.0,
|
||||||
|
width: 50.0,
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,10 @@ class ActivitiesHeader extends StatefulWidget {
|
|||||||
const ActivitiesHeader({super.key});
|
const ActivitiesHeader({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_ActivitiesHeaderState createState() => _ActivitiesHeaderState();
|
State<ActivitiesHeader> createState() => ActivitiesHeaderState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ActivitiesHeaderState extends State<ActivitiesHeader> {
|
class ActivitiesHeaderState extends State<ActivitiesHeader> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
110
lib/widgets/activity_action_view.dart
Normal file
110
lib/widgets/activity_action_view.dart
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||||
|
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||||
|
import 'package:sendtrain/models/activity_timer_model.dart';
|
||||||
|
|
||||||
|
class ActivityActionView extends StatefulWidget {
|
||||||
|
const ActivityActionView({super.key, required this.actions});
|
||||||
|
final List actions;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ActivityActionView> createState() => ActivityActionViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ActivityActionViewState extends State<ActivityActionView> {
|
||||||
|
final ItemScrollController itemScrollController = ItemScrollController();
|
||||||
|
final ScrollOffsetController scrollOffsetController =
|
||||||
|
ScrollOffsetController();
|
||||||
|
final ItemPositionsListener itemPositionsListener =
|
||||||
|
ItemPositionsListener.create();
|
||||||
|
final ScrollOffsetListener scrollOffsetListener =
|
||||||
|
ScrollOffsetListener.create();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
ActivityTimerModel atm =
|
||||||
|
Provider.of<ActivityTimerModel>(context, listen: true);
|
||||||
|
List sets = json.decode(widget.actions[0].set);
|
||||||
|
|
||||||
|
// we need to set the scroll controller
|
||||||
|
// so we can update the selected item position
|
||||||
|
atm.setScrollController(itemScrollController);
|
||||||
|
|
||||||
|
return Expanded(
|
||||||
|
child: ScrollablePositionedList.builder(
|
||||||
|
padding: const EdgeInsets.fromLTRB(10, 0, 10, 20),
|
||||||
|
itemCount: sets.length,
|
||||||
|
itemScrollController: itemScrollController,
|
||||||
|
scrollOffsetController: scrollOffsetController,
|
||||||
|
itemPositionsListener: itemPositionsListener,
|
||||||
|
scrollOffsetListener: scrollOffsetListener,
|
||||||
|
itemBuilder: (BuildContext context, int setNum) {
|
||||||
|
List<GestureDetector> content = [];
|
||||||
|
List set = sets[setNum];
|
||||||
|
|
||||||
|
for (int actionNum = 0; actionNum < set.length; actionNum++) {
|
||||||
|
Map<String, dynamic> setItem = set[actionNum];
|
||||||
|
|
||||||
|
content.add(GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
atm.setAction(setNum, actionNum, 'manual');
|
||||||
|
atm.setActionCount();
|
||||||
|
|
||||||
|
itemScrollController.scrollTo(
|
||||||
|
index: setNum,
|
||||||
|
duration: Duration(milliseconds: 500),
|
||||||
|
curve: Curves.easeInOutCubic);
|
||||||
|
},
|
||||||
|
child: Row(children: [
|
||||||
|
Ink(
|
||||||
|
width: 70,
|
||||||
|
padding: const EdgeInsets.all(15),
|
||||||
|
color: atm.isCurrentItem(setNum, actionNum)
|
||||||
|
? Theme.of(context).colorScheme.primaryContainer
|
||||||
|
: Theme.of(context).colorScheme.onPrimary,
|
||||||
|
child: Text(
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
'${setNum + 1}.${actionNum + 1} ')),
|
||||||
|
Expanded(
|
||||||
|
child: Ink(
|
||||||
|
padding: const EdgeInsets.all(15),
|
||||||
|
color: atm.isCurrentItem(setNum, actionNum)
|
||||||
|
? Theme.of(context).colorScheme.surfaceBright
|
||||||
|
: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||||
|
child: Text(
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
'${setItem['name']}: ${setItem['amount']} ${setItem['type']}'.toTitleCase())))
|
||||||
|
])));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setNum == 0) {
|
||||||
|
return Card(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(0),
|
||||||
|
topRight: Radius.circular(0),
|
||||||
|
bottomLeft: Radius.circular(10),
|
||||||
|
bottomRight: Radius.circular(10)),
|
||||||
|
),
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
|
child: Column(children: content));
|
||||||
|
} else {
|
||||||
|
return Card(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(10),
|
||||||
|
topRight: Radius.circular(10),
|
||||||
|
bottomLeft: Radius.circular(10),
|
||||||
|
bottomRight: Radius.circular(10)),
|
||||||
|
),
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
|
child: Column(children: content));
|
||||||
|
}
|
||||||
|
// return Column(children: contents);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
@ -1,46 +1,150 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sendtrain/classes/activity_action.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:sendtrain/models/activity_model.dart';
|
import 'package:sendtrain/daos/media_items_dao.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||||
|
import 'package:sendtrain/models/activity_timer_model.dart';
|
||||||
|
import 'package:sendtrain/widgets/activity_view.dart';
|
||||||
|
|
||||||
class ActivityCard extends StatelessWidget {
|
class ActivityCard extends StatefulWidget {
|
||||||
ActivityCard({super.key});
|
final Activity activity;
|
||||||
|
|
||||||
final data = ActivityModel(
|
const ActivityCard({super.key, required this.activity});
|
||||||
id: 1,
|
|
||||||
categories: ['power'],
|
@override
|
||||||
description: 'description',
|
State<ActivityCard> createState() => ActivityCardState();
|
||||||
title: 'activity',
|
}
|
||||||
type: 'fundamentals',
|
|
||||||
actions: List.generate(
|
class ActivityCardState extends State<ActivityCard> {
|
||||||
10,
|
String formattedTime(int timeInSecond) {
|
||||||
(i) => ActivityAction(
|
int sec = timeInSecond % 60;
|
||||||
id: 1,
|
int min = (timeInSecond / 60).floor();
|
||||||
title: 'test action',
|
String minute = min.toString().length <= 1 ? "0$min" : "$min";
|
||||||
description:'test description',
|
String second = sec.toString().length <= 1 ? "0$sec" : "$sec";
|
||||||
activityActionSet: Set(
|
return "$minute:$second";
|
||||||
type: 'drop_set',
|
}
|
||||||
total: 3,
|
|
||||||
rest: 3000,
|
|
||||||
reps: Reps(
|
|
||||||
type: 'count',
|
|
||||||
tempo: [2,3,5],
|
|
||||||
amounts: [5,3,2],
|
|
||||||
weights: [50,70,80],
|
|
||||||
rest: 200
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),));
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Card(
|
final ActivityTimerModel atm =
|
||||||
clipBehavior: Clip.hardEdge,
|
Provider.of<ActivityTimerModel>(context, listen: false);
|
||||||
child: Align(
|
|
||||||
alignment: Alignment.center,
|
return FutureBuilder<List<MediaItem>>(
|
||||||
child: Text(
|
future: MediaItemsDao(Provider.of<AppDatabase>(context))
|
||||||
data.title,
|
.fromActivity(widget.activity),
|
||||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
builder: (context, snapshot) {
|
||||||
),
|
if (snapshot.hasData) {
|
||||||
));
|
List<MediaItem> mediaItems = snapshot.data!;
|
||||||
|
|
||||||
|
return Card(
|
||||||
|
color: atm.activity?.id == widget.activity.id
|
||||||
|
? Theme.of(context).colorScheme.primaryContainer
|
||||||
|
: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||||
|
clipBehavior: Clip.hardEdge,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () => showGeneralDialog(
|
||||||
|
barrierColor: Colors.black.withOpacity(0.5),
|
||||||
|
transitionDuration: const Duration(milliseconds: 220),
|
||||||
|
transitionBuilder: (BuildContext context,
|
||||||
|
Animation<double> animation,
|
||||||
|
Animation<double> secondaryAnimation,
|
||||||
|
Widget child) {
|
||||||
|
Animation<Offset> custom = Tween<Offset>(
|
||||||
|
begin: const Offset(0.0, 1.0),
|
||||||
|
end: const Offset(0.0, 0.0))
|
||||||
|
.animate(animation);
|
||||||
|
return SlideTransition(
|
||||||
|
position: custom,
|
||||||
|
child: Dialog.fullscreen(
|
||||||
|
child: ActivityView(activity: widget.activity)));
|
||||||
|
},
|
||||||
|
barrierDismissible: true,
|
||||||
|
barrierLabel: '',
|
||||||
|
context: context,
|
||||||
|
pageBuilder: (context, animation1, animation2) {
|
||||||
|
return Container();
|
||||||
|
}),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
ListTile(
|
||||||
|
// visualDensity: VisualDensity(horizontal: VisualDensity.maximumDensity),
|
||||||
|
leading: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
|
||||||
|
child: Container(
|
||||||
|
// padding: EdgeInsets.only(top: 5, bottom: 5),
|
||||||
|
width: 60,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
image:
|
||||||
|
findMediaByType(mediaItems, 'image')),
|
||||||
|
// color: Colors.blue,
|
||||||
|
borderRadius: const BorderRadius.all(
|
||||||
|
Radius.elliptical(8, 8)),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
title: Consumer<ActivityTimerModel>(
|
||||||
|
builder: (context, atm, child) {
|
||||||
|
if (atm.activity?.id == widget.activity.id) {
|
||||||
|
return Text(
|
||||||
|
maxLines: 1,
|
||||||
|
"${widget.activity.title.toTitleCase()} (${formattedTime(atm.totalTime)})");
|
||||||
|
} else {
|
||||||
|
return Text(maxLines: 1, widget.activity.title.toTitleCase());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
subtitle: Text(maxLines: 2, widget.activity.description),
|
||||||
|
trailing: IconButton(
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
icon: Icon(Icons.close_rounded),
|
||||||
|
onPressed: () {
|
||||||
|
showAdaptiveDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) => AlertDialog(
|
||||||
|
title: const Text('Activity Removal'),
|
||||||
|
content: const Text(
|
||||||
|
'Would you like to permanently remove this activity from the current session?'),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
onPressed: () =>
|
||||||
|
Navigator.pop(context, 'Cancel'),
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () =>
|
||||||
|
Navigator.pop(context, 'OK'),
|
||||||
|
child: const Text('OK'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 50.0,
|
||||||
|
width: 50.0,
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageProvider findMediaByType(List<MediaItem> media, String type) {
|
||||||
|
Iterable<MediaItem>? found = media.where((m) => m.type == MediaType.image);
|
||||||
|
|
||||||
|
if (found.isNotEmpty) {
|
||||||
|
return NetworkImage(found.first.reference);
|
||||||
|
} else {
|
||||||
|
// Element is not found
|
||||||
|
return const AssetImage('assets/images/placeholder.jpg');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
196
lib/widgets/activity_view.dart
Normal file
196
lib/widgets/activity_view.dart
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:sendtrain/daos/actions_dao.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||||
|
import 'package:sendtrain/models/activity_timer_model.dart';
|
||||||
|
import 'package:sendtrain/widgets/activity_action_view.dart';
|
||||||
|
import 'package:sendtrain/widgets/activity_view_categories.dart';
|
||||||
|
import 'package:sendtrain/widgets/activity_view_media.dart';
|
||||||
|
import 'package:sendtrain/widgets/activity_view_types.dart';
|
||||||
|
|
||||||
|
class ActivityView extends StatefulWidget {
|
||||||
|
const ActivityView(
|
||||||
|
{super.key, required this.activity});
|
||||||
|
final Activity activity;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ActivityView> createState() => _ActivityViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ActivityViewState extends State<ActivityView> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final Activity activity = widget.activity;
|
||||||
|
ActivityTimerModel atm =
|
||||||
|
Provider.of<ActivityTimerModel>(context, listen: false);
|
||||||
|
|
||||||
|
return FutureBuilder<List>(
|
||||||
|
future: ActionsDao(Provider.of<AppDatabase>(context))
|
||||||
|
.fromActivity(activity),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.hasData) {
|
||||||
|
List actions = snapshot.data!;
|
||||||
|
atm.setup(activity, actions);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
floatingActionButtonLocation: ExpandableFab.location,
|
||||||
|
floatingActionButton: ExpandableFab(
|
||||||
|
distance: 70,
|
||||||
|
type: ExpandableFabType.up,
|
||||||
|
overlayStyle: ExpandableFabOverlayStyle(
|
||||||
|
color: Colors.black.withOpacity(0.5),
|
||||||
|
blur: 10,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
FloatingActionButton.extended(
|
||||||
|
icon: const Icon(Icons.history_outlined),
|
||||||
|
label: Text('Restart'),
|
||||||
|
onPressed: () {},
|
||||||
|
),
|
||||||
|
FloatingActionButton.extended(
|
||||||
|
icon: const Icon(Icons.done_all_outlined),
|
||||||
|
label: Text('Done'),
|
||||||
|
onPressed: () {},
|
||||||
|
),
|
||||||
|
FloatingActionButton.extended(
|
||||||
|
icon: const Icon(Icons.edit_outlined),
|
||||||
|
label: Text('Edit'),
|
||||||
|
onPressed: () {},
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
body: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
AppBar(
|
||||||
|
titleSpacing: 0,
|
||||||
|
centerTitle: true,
|
||||||
|
title: const Text('Activity',
|
||||||
|
style: TextStyle(fontSize: 15)),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 15, right: 20, top: 15, bottom: 10),
|
||||||
|
child: Text(
|
||||||
|
maxLines: 1,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 25, fontWeight: FontWeight.bold),
|
||||||
|
activity.title.toTitleCase())),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(10, 0, 0, 10),
|
||||||
|
child: Flex(direction: Axis.horizontal, children: [
|
||||||
|
ActivityViewCategories(
|
||||||
|
categories: [activity.category]),
|
||||||
|
ActivityViewTypes(types: [activity.type])
|
||||||
|
])),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
top: 0, bottom: 10, left: 15, right: 15),
|
||||||
|
child: Text(
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: const TextStyle(fontSize: 15),
|
||||||
|
activity.description)),
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(15, 20, 0, 10),
|
||||||
|
child: Text(
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
|
'Media:')),
|
||||||
|
ActivityViewMedia(activity: activity),
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(15, 30, 0, 10),
|
||||||
|
child: Text(
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
|
'Actions')),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Card(
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(10),
|
||||||
|
topRight: Radius.circular(10)),
|
||||||
|
),
|
||||||
|
color: Theme.of(context).colorScheme.onPrimary,
|
||||||
|
child: Row(children: [
|
||||||
|
Ink(
|
||||||
|
width: 70,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.primaryContainer,
|
||||||
|
child: Consumer<ActivityTimerModel>(
|
||||||
|
builder: (context, atm, child) {
|
||||||
|
return IconButton(
|
||||||
|
alignment:
|
||||||
|
AlignmentDirectional.center,
|
||||||
|
icon: atm.isActive
|
||||||
|
? const Icon(
|
||||||
|
Icons.pause_rounded)
|
||||||
|
: const Icon(
|
||||||
|
Icons.play_arrow_rounded),
|
||||||
|
onPressed: () => {
|
||||||
|
atm.isActive
|
||||||
|
? atm.pause()
|
||||||
|
: atm.start()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Consumer<ActivityTimerModel>(
|
||||||
|
builder: (context, atm, child) {
|
||||||
|
return Text(
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 20),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
'${atm.actionCount} ${atm.currentAction['type']}'.toTitleCase());
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
padding:
|
||||||
|
EdgeInsets.only(right: 15),
|
||||||
|
child:
|
||||||
|
Consumer<ActivityTimerModel>(
|
||||||
|
builder: (context, atm,
|
||||||
|
child) {
|
||||||
|
return Text(
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 12),
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
'${atm.currentAction['actionID'] + 1} of ${atm.totalActions()}');
|
||||||
|
})),
|
||||||
|
])),
|
||||||
|
]))),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 14, right: 14),
|
||||||
|
child: Consumer<ActivityTimerModel>(
|
||||||
|
builder: (context, atm, child) {
|
||||||
|
return LinearProgressIndicator(
|
||||||
|
value: atm.progress,
|
||||||
|
semanticsLabel: 'Activity Progress',
|
||||||
|
);
|
||||||
|
})),
|
||||||
|
ActivityActionView(actions: actions),
|
||||||
|
]));
|
||||||
|
} else {
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 50.0,
|
||||||
|
width: 50.0,
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
30
lib/widgets/activity_view_categories.dart
Normal file
30
lib/widgets/activity_view_categories.dart
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||||
|
|
||||||
|
class ActivityViewCategories extends StatelessWidget {
|
||||||
|
const ActivityViewCategories({super.key, required this.categories});
|
||||||
|
|
||||||
|
final List<ActivityCategories> categories;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
padding: const EdgeInsets.only(right: 10),
|
||||||
|
itemCount: categories.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return ActionChip(
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
avatar: const Icon(Icons.category_rounded),
|
||||||
|
label: Text(maxLines: 1, categories[index].name.toTitleCase()),
|
||||||
|
tooltip: "Activity Category",
|
||||||
|
onPressed: () {},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
51
lib/widgets/activity_view_media.dart
Normal file
51
lib/widgets/activity_view_media.dart
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:sendtrain/daos/media_items_dao.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
import 'package:sendtrain/widgets/media_card.dart';
|
||||||
|
|
||||||
|
class ActivityViewMedia extends StatelessWidget {
|
||||||
|
const ActivityViewMedia({super.key, required this.activity});
|
||||||
|
|
||||||
|
final Activity activity;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return FutureBuilder<List<MediaItem>>(
|
||||||
|
future: MediaItemsDao(Provider.of<AppDatabase>(context)).fromActivity(activity),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.hasData) {
|
||||||
|
List<MediaItem> mediaItems = snapshot.data!;
|
||||||
|
List<MediaCard> mediaCards = [];
|
||||||
|
|
||||||
|
for (int i = 0; i < mediaItems.length; i++) {
|
||||||
|
mediaCards.add(MediaCard(media: mediaItems[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 100,
|
||||||
|
child: GridView.count(
|
||||||
|
padding: const EdgeInsets.fromLTRB(15, 0, 0, 0),
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
crossAxisSpacing: 5,
|
||||||
|
mainAxisSpacing: 5,
|
||||||
|
crossAxisCount: 1,
|
||||||
|
children: mediaCards))
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 50.0,
|
||||||
|
width: 50.0,
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
30
lib/widgets/activity_view_types.dart
Normal file
30
lib/widgets/activity_view_types.dart
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||||
|
|
||||||
|
class ActivityViewTypes extends StatelessWidget {
|
||||||
|
const ActivityViewTypes({super.key, required this.types});
|
||||||
|
|
||||||
|
final List<ActivityType> types;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
padding: const EdgeInsets.only(right: 10),
|
||||||
|
itemCount: types.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return ActionChip(
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
avatar: const Icon(Icons.fitness_center_rounded),
|
||||||
|
label: Text(maxLines: 1, types[index].name.toTitleCase()),
|
||||||
|
tooltip: "Activity Type",
|
||||||
|
onPressed: () {},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sendtrain/classes/media.dart';
|
import 'package:sendtrain/database/database.dart';
|
||||||
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
|
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
|
||||||
|
|
||||||
class MediaCard extends StatelessWidget {
|
class MediaCard extends StatelessWidget {
|
||||||
const MediaCard({super.key, required this.media});
|
const MediaCard({super.key, required this.media});
|
||||||
|
|
||||||
final Media media;
|
final MediaItem media;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -14,22 +14,22 @@ class MediaCard extends StatelessWidget {
|
|||||||
flags: const YoutubePlayerFlags(
|
flags: const YoutubePlayerFlags(
|
||||||
autoPlay: false, mute: true, showLiveFullscreenButton: false));
|
autoPlay: false, mute: true, showLiveFullscreenButton: false));
|
||||||
|
|
||||||
DecorationImage mediaImage(Media media) {
|
DecorationImage mediaImage(MediaItem media) {
|
||||||
String image = '';
|
String image = '';
|
||||||
|
|
||||||
if (media.type == "image") {
|
if (media.type == MediaType.image) {
|
||||||
image = media.reference;
|
image = media.reference;
|
||||||
} else if (media.type == "youtube") {
|
} else if (media.type == MediaType.youtube) {
|
||||||
image = 'https://img.youtube.com/vi/${media.reference}/0.jpg';
|
image = 'https://img.youtube.com/vi/${media.reference}/0.jpg';
|
||||||
}
|
}
|
||||||
|
|
||||||
return DecorationImage(image: NetworkImage(image), fit: BoxFit.cover);
|
return DecorationImage(image: NetworkImage(image), fit: BoxFit.cover);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget mediaItem(Media media) {
|
Widget mediaItem(MediaItem media) {
|
||||||
if (media.type == "image") {
|
if (media.type == MediaType.image) {
|
||||||
return Image(image: NetworkImage(media.reference));
|
return Image(image: NetworkImage(media.reference));
|
||||||
} else if (media.type == "youtube") {
|
} else if (media.type == MediaType.youtube) {
|
||||||
return YoutubePlayer(
|
return YoutubePlayer(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 9,
|
||||||
@ -62,7 +62,7 @@ class MediaCard extends StatelessWidget {
|
|||||||
mediaItem(media),
|
mediaItem(media),
|
||||||
const SizedBox(height: 15),
|
const SizedBox(height: 15),
|
||||||
Text(
|
Text(
|
||||||
'${media.description}',
|
media.description,
|
||||||
style: const TextStyle(fontSize: 20),
|
style: const TextStyle(fontSize: 20),
|
||||||
),
|
),
|
||||||
const Divider(
|
const Divider(
|
||||||
|
@ -1,140 +1,23 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:intl/date_symbol_data_local.dart';
|
import 'package:intl/date_symbol_data_local.dart';
|
||||||
import 'package:sendtrain/classes/activity_action.dart';
|
import 'package:sendtrain/database/database.dart' hide ActivityAction;
|
||||||
import 'package:sendtrain/classes/media.dart';
|
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||||
import 'package:sendtrain/models/activity_model.dart';
|
|
||||||
import 'package:sendtrain/models/session_model.dart';
|
|
||||||
import 'package:sendtrain/widgets/session_view.dart';
|
import 'package:sendtrain/widgets/session_view.dart';
|
||||||
|
|
||||||
class SessionCard extends StatelessWidget {
|
class SessionCard extends StatelessWidget {
|
||||||
final int state;
|
|
||||||
final int type;
|
final int type;
|
||||||
const SessionCard({super.key, this.state = 0, this.type = 0});
|
final Session session;
|
||||||
|
const SessionCard({super.key, this.type = 0, required this.session});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
initializeDateFormatting('en');
|
initializeDateFormatting('en');
|
||||||
final DateFormat dateFormat = DateFormat('yyyy-MM-dd');
|
final DateFormat dateFormat = DateFormat('yyyy-MM-dd');
|
||||||
|
|
||||||
Color color = (state == 0)
|
Color color = (session.status == SessionStatus.started)
|
||||||
? const Color(0xff3A5FB6)
|
? Theme.of(context).colorScheme.primaryContainer
|
||||||
: ThemeData.dark(useMaterial3: true).colorScheme.surface;
|
: Theme.of(context).colorScheme.surfaceContainerLow;
|
||||||
|
|
||||||
// place holder until we can retrieve real data
|
|
||||||
final data = SessionModel(
|
|
||||||
id: 1,
|
|
||||||
title: "Projecting @ Climbers Rock",
|
|
||||||
content:
|
|
||||||
"Beta pully beta beta pinch one arm crimpy. Futuristic pinch, dyno dynamic drop knee climb. Climbing ondra slopey onsight beta ondra power endurance.",
|
|
||||||
date: DateTime.now(),
|
|
||||||
activities: [
|
|
||||||
ActivityModel(
|
|
||||||
id: 1,
|
|
||||||
title: 'Campus Board',
|
|
||||||
type: 'fundamental',
|
|
||||||
categories: ['strength', 'power'],
|
|
||||||
description:
|
|
||||||
"Campus board session, focussing on explosiveness and contact strength.",
|
|
||||||
actions: [
|
|
||||||
ActivityAction(
|
|
||||||
id: 1,
|
|
||||||
title: 'test action',
|
|
||||||
description:'test description',
|
|
||||||
activityActionSet: Set(
|
|
||||||
type: 'drop_set',
|
|
||||||
total: 3,
|
|
||||||
rest: 3000,
|
|
||||||
reps: Reps(
|
|
||||||
type: 'count',
|
|
||||||
tempo: [2,3,5],
|
|
||||||
amounts: [5,3,2],
|
|
||||||
weights: [50,70,80],
|
|
||||||
rest: 200
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
],
|
|
||||||
resources: ['https://www.youtube.com/watch?v=bLz0xp1PEm4']),
|
|
||||||
ActivityModel(
|
|
||||||
id: 1,
|
|
||||||
title: 'Projecting',
|
|
||||||
type: 'fundamental',
|
|
||||||
categories: ['technique', 'conditioning'],
|
|
||||||
description:
|
|
||||||
"Session focussed on attempting a climb at or beyond your perceived limit.",
|
|
||||||
actions: [
|
|
||||||
ActivityAction(
|
|
||||||
id: 1,
|
|
||||||
title: 'test action',
|
|
||||||
description:'test description',
|
|
||||||
activityActionSet: Set(
|
|
||||||
type: 'drop_set',
|
|
||||||
total: 3,
|
|
||||||
rest: 3000,
|
|
||||||
reps: Reps(
|
|
||||||
type: 'count',
|
|
||||||
tempo: [2,3,5],
|
|
||||||
amounts: [5,3,2],
|
|
||||||
weights: [50,70,80],
|
|
||||||
rest: 200
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
],
|
|
||||||
resources: ['https://www.youtube.com/watch?v=dyAvbUvY_PU']),
|
|
||||||
ActivityModel(
|
|
||||||
id: 1,
|
|
||||||
title: 'Weighted Pull Ups',
|
|
||||||
type: 'fundamental',
|
|
||||||
categories: ['Strength', 'Power'],
|
|
||||||
description:
|
|
||||||
"Weight pullups to increase strength and maximal pulling force.",
|
|
||||||
actions: [
|
|
||||||
ActivityAction(
|
|
||||||
id: 1,
|
|
||||||
title: 'test action',
|
|
||||||
description:'test description',
|
|
||||||
activityActionSet: Set(
|
|
||||||
type: 'drop_set',
|
|
||||||
total: 3,
|
|
||||||
rest: 3000,
|
|
||||||
reps: Reps(
|
|
||||||
type: 'count',
|
|
||||||
tempo: [2,3,5],
|
|
||||||
amounts: [5,3,2],
|
|
||||||
weights: [50,70,80],
|
|
||||||
rest: 200
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
],
|
|
||||||
resources: ['https://www.youtube.com/watch?v=dyAvbUvY_PU']),
|
|
||||||
],
|
|
||||||
achievements: [
|
|
||||||
'got 1 3 5 first time!',
|
|
||||||
'no pain in elbow',
|
|
||||||
'life is pain',
|
|
||||||
'new PR for pullups'
|
|
||||||
],
|
|
||||||
media: [
|
|
||||||
Media(
|
|
||||||
id: 1,
|
|
||||||
reference: 'TwS8ycTY5cc',
|
|
||||||
type: 'youtube',
|
|
||||||
description: 'Attempting crux move'),
|
|
||||||
Media(
|
|
||||||
id: 1,
|
|
||||||
reference:
|
|
||||||
'https://static.wixstatic.com/media/c83481_1dd473ad49524ae5a95d993ba10e0a50~mv2.jpg/v1/fill/w_640,h_426,al_c,q_80,usm_0.66_1.00_0.01,enc_auto/c83481_1dd473ad49524ae5a95d993ba10e0a50~mv2.jpg',
|
|
||||||
type: 'image',
|
|
||||||
description: 'Struggling on deadpoints'),
|
|
||||||
Media(
|
|
||||||
id: 1,
|
|
||||||
reference: 'TwS8ycTY5cc',
|
|
||||||
type: 'youtube',
|
|
||||||
description: 'Attempting crux move')
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
return Card(
|
return Card(
|
||||||
@ -142,7 +25,7 @@ class SessionCard extends StatelessWidget {
|
|||||||
margin: const EdgeInsets.fromLTRB(15, 15, 15, 0),
|
margin: const EdgeInsets.fromLTRB(15, 15, 15, 0),
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
// splashColor: Colors.deepPurple,
|
splashColor: Colors.deepPurple,
|
||||||
onTap: () => showGeneralDialog(
|
onTap: () => showGeneralDialog(
|
||||||
barrierColor: Colors.black.withOpacity(0.5),
|
barrierColor: Colors.black.withOpacity(0.5),
|
||||||
transitionDuration: const Duration(milliseconds: 220),
|
transitionDuration: const Duration(milliseconds: 220),
|
||||||
@ -156,7 +39,7 @@ class SessionCard extends StatelessWidget {
|
|||||||
.animate(animation);
|
.animate(animation);
|
||||||
return SlideTransition(
|
return SlideTransition(
|
||||||
position: custom,
|
position: custom,
|
||||||
child: Dialog.fullscreen(child: SessionView(data: data)));
|
child: Dialog.fullscreen(child: SessionView(session: session)));
|
||||||
},
|
},
|
||||||
barrierDismissible: true,
|
barrierDismissible: true,
|
||||||
barrierLabel: '',
|
barrierLabel: '',
|
||||||
@ -182,8 +65,32 @@ class SessionCard extends StatelessWidget {
|
|||||||
BorderRadius.all(Radius.elliptical(10, 10)),
|
BorderRadius.all(Radius.elliptical(10, 10)),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
title: Text(maxLines: 1, data.title),
|
title: Text(maxLines: 1, session.title.toTitleCase()),
|
||||||
subtitle: Text(maxLines: 1, dateFormat.format(data.date)),
|
subtitle: Text(maxLines: 1, dateFormat.format(session.date as DateTime)),
|
||||||
|
trailing: IconButton(
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
icon: Icon(Icons.close_rounded),
|
||||||
|
onPressed: () {
|
||||||
|
showAdaptiveDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) => AlertDialog(
|
||||||
|
title: const Text('Session Removal'),
|
||||||
|
content: const Text(
|
||||||
|
'Would you like to permanently remove this session?'),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context, 'Cancel'),
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context, 'OK'),
|
||||||
|
child: const Text('OK'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
contentPadding: const EdgeInsets.fromLTRB(15, 0, 15, 15),
|
contentPadding: const EdgeInsets.fromLTRB(15, 0, 15, 15),
|
||||||
@ -191,17 +98,17 @@ class SessionCard extends StatelessWidget {
|
|||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: const TextStyle(fontWeight: FontWeight.w300),
|
style: const TextStyle(fontWeight: FontWeight.w300),
|
||||||
data.content),
|
session.content),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Card(
|
return Card(
|
||||||
color: const Color.fromARGB(125, 0, 0, 0),
|
color: color,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
// overlayColor: MaterialStateColor(Colors.deepPurple as int),
|
// overlayColor: MaterialStateColor(Colors.deepPurple as int),
|
||||||
// splashColor: Colors.deepPurple,
|
splashColor: Colors.deepPurple,
|
||||||
borderRadius: const BorderRadius.all(Radius.elliptical(10, 10)),
|
borderRadius: const BorderRadius.all(Radius.elliptical(10, 10)),
|
||||||
onTap: () => showGeneralDialog(
|
onTap: () => showGeneralDialog(
|
||||||
// barrierColor: Colors.black.withOpacity(0.5),
|
// barrierColor: Colors.black.withOpacity(0.5),
|
||||||
@ -217,7 +124,7 @@ class SessionCard extends StatelessWidget {
|
|||||||
return SlideTransition(
|
return SlideTransition(
|
||||||
position: custom,
|
position: custom,
|
||||||
child:
|
child:
|
||||||
Dialog.fullscreen(child: SessionView(data: data)));
|
Dialog.fullscreen(child: SessionView(session: session)));
|
||||||
},
|
},
|
||||||
barrierDismissible: true,
|
barrierDismissible: true,
|
||||||
barrierLabel: '',
|
barrierLabel: '',
|
||||||
@ -244,11 +151,11 @@ class SessionCard extends StatelessWidget {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
data.title,
|
session.title.toTitleCase(),
|
||||||
textAlign: TextAlign.center),
|
textAlign: TextAlign.center),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
dateFormat.format(data.date),
|
dateFormat.format(session.date as DateTime),
|
||||||
textAlign: TextAlign.center),
|
textAlign: TextAlign.center),
|
||||||
),
|
),
|
||||||
])))));
|
])))));
|
||||||
|
@ -1,221 +1,106 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:intl/date_symbol_data_local.dart';
|
import 'package:intl/date_symbol_data_local.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:sendtrain/daos/activities_dao.dart';
|
||||||
|
|
||||||
import 'package:sendtrain/classes/media.dart';
|
import 'package:sendtrain/database/database.dart';
|
||||||
import 'package:sendtrain/models/activity_model.dart';
|
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||||
import 'package:sendtrain/models/session_model.dart';
|
import 'package:sendtrain/widgets/session_view_achievements.dart';
|
||||||
import 'package:sendtrain/widgets/media_card.dart';
|
import 'package:sendtrain/widgets/session_view_activities.dart';
|
||||||
|
import 'package:sendtrain/widgets/session_view_media.dart';
|
||||||
|
|
||||||
class SessionView extends StatelessWidget {
|
class SessionView extends StatelessWidget {
|
||||||
const SessionView({super.key, required this.data});
|
const SessionView({super.key, required this.session});
|
||||||
|
|
||||||
final SessionModel data;
|
final Session session;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
initializeDateFormatting('en');
|
initializeDateFormatting('en');
|
||||||
final DateFormat dateFormat = DateFormat('yyyy-MM-dd');
|
final DateFormat dateFormat = DateFormat('yyyy-MM-dd');
|
||||||
|
|
||||||
return Column(
|
return FutureBuilder<List<Activity>>(
|
||||||
mainAxisSize: MainAxisSize.min,
|
future: ActivitiesDao(Provider.of<AppDatabase>(context)).sessionActivities(session.id),
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
builder: (context, snapshot) {
|
||||||
children: <Widget>[
|
if (snapshot.hasData) {
|
||||||
AppBar(
|
final activities = snapshot.data!;
|
||||||
centerTitle: true,
|
return Scaffold(
|
||||||
title: Text('Session @ ${dateFormat.format(data.date)}',
|
floatingActionButtonLocation: ExpandableFab.location,
|
||||||
style: const TextStyle(fontSize: 15)),
|
floatingActionButton: ExpandableFab(
|
||||||
),
|
distance: 70,
|
||||||
Padding(
|
type: ExpandableFabType.up,
|
||||||
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 10),
|
overlayStyle: ExpandableFabOverlayStyle(
|
||||||
child: Text(
|
color: Colors.black.withOpacity(0.5),
|
||||||
maxLines: 1,
|
blur: 10,
|
||||||
style:
|
),
|
||||||
const TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
|
children: [
|
||||||
data.title)),
|
FloatingActionButton.extended(
|
||||||
SessionViewAchievements(achievements: data.achievements),
|
icon: const Icon(Icons.history_outlined),
|
||||||
Padding(
|
label: Text('Restart'),
|
||||||
padding: const EdgeInsets.only(left: 15, right: 15),
|
onPressed: () {},
|
||||||
child: Text(textAlign: TextAlign.center, data.content)),
|
),
|
||||||
SessionViewMedia(media: data.media),
|
FloatingActionButton.extended(
|
||||||
const Padding(
|
icon: const Icon(Icons.done_all_outlined),
|
||||||
padding: EdgeInsets.only(top: 25, bottom: 10),
|
label: Text('Done'),
|
||||||
child: Text(
|
onPressed: () {},
|
||||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
),
|
||||||
'Activities:')),
|
FloatingActionButton.extended(
|
||||||
SessionViewActivities(activities: data.activities),
|
icon: const Icon(Icons.edit_outlined),
|
||||||
// TextButton(
|
label: Text('Edit'),
|
||||||
// onPressed: () {
|
onPressed: () {},
|
||||||
// Navigator.pop(context);
|
),
|
||||||
// },
|
]),
|
||||||
// child: const Text('Close'),
|
body: Column(
|
||||||
// ),
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
],
|
children: <Widget>[
|
||||||
);
|
AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
title: Text(
|
||||||
|
'Session @ ${dateFormat.format(session.date as DateTime)}',
|
||||||
|
style: const TextStyle(fontSize: 15)),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 15, right: 20, top: 15, bottom: 10),
|
||||||
|
child: Text(
|
||||||
|
maxLines: 1,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 25, fontWeight: FontWeight.bold),
|
||||||
|
session.title.toTitleCase())),
|
||||||
|
SessionViewAchievements(session: session),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 15, right: 15),
|
||||||
|
child: Text(
|
||||||
|
style: const TextStyle(fontSize: 15),
|
||||||
|
session.content)),
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(15, 30, 0, 10),
|
||||||
|
child: Text(
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
|
'Media:')),
|
||||||
|
SessionViewMedia(session: session),
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(15, 30, 0, 10),
|
||||||
|
child: Text(
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
|
'Activites:')),
|
||||||
|
SessionViewActivities(
|
||||||
|
activities: activities),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 50.0,
|
||||||
|
width: 50.0,
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SessionViewActivities extends StatelessWidget {
|
|
||||||
const SessionViewActivities({super.key, this.activities});
|
|
||||||
|
|
||||||
final List<ActivityModel>? activities;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Expanded(
|
|
||||||
child: ListView.builder(
|
|
||||||
shrinkWrap: true,
|
|
||||||
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
|
||||||
itemCount: activities?.length,
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
return Card(
|
|
||||||
color: const Color(0xff3A5FB6),
|
|
||||||
child: ListTile(
|
|
||||||
// dense: true,
|
|
||||||
focusColor: const Color(0xff3A5FB6),
|
|
||||||
shape: const RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.all(Radius.elliptical(10, 10))),
|
|
||||||
onTap: () => showGeneralDialog(
|
|
||||||
barrierColor: Colors.black.withOpacity(0.5),
|
|
||||||
transitionDuration: const Duration(milliseconds: 220),
|
|
||||||
transitionBuilder: (BuildContext context,
|
|
||||||
Animation<double> animation,
|
|
||||||
Animation<double> secondaryAnimation,
|
|
||||||
Widget child) {
|
|
||||||
Animation<Offset> custom = Tween<Offset>(
|
|
||||||
begin: const Offset(0.0, 1.0),
|
|
||||||
end: const Offset(0.0, 0.0))
|
|
||||||
.animate(animation);
|
|
||||||
return SlideTransition(
|
|
||||||
position: custom,
|
|
||||||
child: Dialog.fullscreen(
|
|
||||||
child: Flex(
|
|
||||||
direction: Axis.vertical,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Text('${activities?[index].title}'),
|
|
||||||
Text('${activities?[index].categories}'),
|
|
||||||
Text('${activities?[index].description}'),
|
|
||||||
Text('${activities?[index].resources}'),
|
|
||||||
Text('${activities?[index].actions[0].title}'),
|
|
||||||
Text(
|
|
||||||
'${activities?[index].actions[0].description}'),
|
|
||||||
])));
|
|
||||||
},
|
|
||||||
barrierDismissible: true,
|
|
||||||
barrierLabel: '',
|
|
||||||
context: context,
|
|
||||||
pageBuilder: (context, animation1, animation2) {
|
|
||||||
return Container();
|
|
||||||
}),
|
|
||||||
enableFeedback: true,
|
|
||||||
title: Text(maxLines: 1, '${activities?[index].title}'),
|
|
||||||
subtitle: Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 3),
|
|
||||||
child:
|
|
||||||
Text(maxLines: 2, '${activities?[index].description}')),
|
|
||||||
));
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SessionViewAchievements extends StatelessWidget {
|
|
||||||
const SessionViewAchievements({super.key, this.achievements});
|
|
||||||
|
|
||||||
final List<String>? achievements;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 10),
|
|
||||||
child: SizedBox(
|
|
||||||
height: 40,
|
|
||||||
child: ListView.builder(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
|
||||||
itemCount: achievements?.length,
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 5),
|
|
||||||
child: ActionChip(
|
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
avatar: const Icon(Icons.check_circle_outline),
|
|
||||||
label: Text(maxLines: 1, '${achievements?[index]}'),
|
|
||||||
onPressed: () {
|
|
||||||
// setState(() {
|
|
||||||
// favorite = !favorite;
|
|
||||||
// });
|
|
||||||
},
|
|
||||||
));
|
|
||||||
// return Card(
|
|
||||||
// child: ListTile(
|
|
||||||
// // dense: true,
|
|
||||||
// focusColor: Colors.deepPurple,
|
|
||||||
// shape: const RoundedRectangleBorder(
|
|
||||||
// borderRadius: BorderRadius.all(Radius.circular(10))),
|
|
||||||
// onTap: () {},
|
|
||||||
// enableFeedback: true,
|
|
||||||
// title: Text(maxLines: 1, '${achievements?[index]}'),
|
|
||||||
// ));
|
|
||||||
},
|
|
||||||
))),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SessionViewMedia extends StatelessWidget {
|
|
||||||
const SessionViewMedia({super.key, this.media});
|
|
||||||
|
|
||||||
final List<Media>? media;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
List<Widget> mediaCards = List.generate((media != null) ? media!.length : 0,
|
|
||||||
(i) => MediaCard(media: media![i]));
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
const Padding(
|
|
||||||
padding: EdgeInsets.only(top: 25),
|
|
||||||
child: Text(
|
|
||||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
|
||||||
'Media:')),
|
|
||||||
SizedBox(
|
|
||||||
width: double.infinity,
|
|
||||||
height: 100,
|
|
||||||
child: GridView.count(
|
|
||||||
padding: const EdgeInsets.fromLTRB(15, 10, 0, 0),
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
crossAxisSpacing: 5,
|
|
||||||
mainAxisSpacing: 5,
|
|
||||||
crossAxisCount: 1,
|
|
||||||
children: mediaCards))
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SizedBox(
|
|
||||||
// height: 100,
|
|
||||||
// width: double.infinity,
|
|
||||||
// child: ListView.builder(
|
|
||||||
// // scrollDirection: Axis.horizontal,
|
|
||||||
// padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
|
||||||
// itemCount: media?.length,
|
|
||||||
// itemBuilder: (BuildContext context, int index) {
|
|
||||||
// return Card(
|
|
||||||
// child: ListTile(
|
|
||||||
// dense: true,
|
|
||||||
// focusColor: Colors.deepPurple,
|
|
||||||
// shape: const RoundedRectangleBorder(
|
|
||||||
// borderRadius: BorderRadius.all(Radius.circular(10))),
|
|
||||||
// onTap: () {},
|
|
||||||
// enableFeedback: true,
|
|
||||||
// title: const Text(maxLines: 1, 'test'),
|
|
||||||
// ));
|
|
||||||
// }))
|
|
||||||
|
|
||||||
|
68
lib/widgets/session_view_achievements.dart
Normal file
68
lib/widgets/session_view_achievements.dart
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:sendtrain/daos/session_activities_dao.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||||
|
|
||||||
|
class SessionViewAchievements extends StatelessWidget {
|
||||||
|
const SessionViewAchievements({super.key, required this.session});
|
||||||
|
|
||||||
|
final Session session;
|
||||||
|
|
||||||
|
List<String> getAchievements(List<SessionActivity> sessionActivities) {
|
||||||
|
List<String> achievements = [];
|
||||||
|
|
||||||
|
for (int i = 0; i < sessionActivities.length; i++) {
|
||||||
|
final SessionActivity sessionActivity = sessionActivities[i];
|
||||||
|
final List? saAchievments = sessionActivity.achievements?.split(',');
|
||||||
|
|
||||||
|
if (saAchievments != null) {
|
||||||
|
saAchievments.forEach((achievement) => achievements.add(achievement));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return achievements;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return FutureBuilder<List<SessionActivity>>(
|
||||||
|
future: SessionActivitiesDao(Provider.of<AppDatabase>(context))
|
||||||
|
.fromSessionId(session.id),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.hasData) {
|
||||||
|
final sessionActivities = snapshot.data!;
|
||||||
|
final achievements = getAchievements(sessionActivities);
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 10),
|
||||||
|
child: SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: ListView.builder(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
||||||
|
itemCount: achievements.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 5),
|
||||||
|
child: ActionChip(
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
avatar:
|
||||||
|
const Icon(Icons.check_circle_outline),
|
||||||
|
label: Text(maxLines: 1, achievements[index].toTitleCase()),
|
||||||
|
onPressed: () {},
|
||||||
|
));
|
||||||
|
},
|
||||||
|
))),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.all(15),
|
||||||
|
child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
23
lib/widgets/session_view_activities.dart
Normal file
23
lib/widgets/session_view_activities.dart
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
import 'package:sendtrain/widgets/activity_card.dart';
|
||||||
|
|
||||||
|
class SessionViewActivities extends StatelessWidget {
|
||||||
|
const SessionViewActivities({super.key, required this.activities });
|
||||||
|
|
||||||
|
final List<Activity> activities;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
// shrinkWrap: true,
|
||||||
|
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
||||||
|
itemCount: activities.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return ActivityCard(
|
||||||
|
activity: activities[index]);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
45
lib/widgets/session_view_media.dart
Normal file
45
lib/widgets/session_view_media.dart
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:sendtrain/daos/media_items_dao.dart';
|
||||||
|
import 'package:sendtrain/database/database.dart';
|
||||||
|
import 'package:sendtrain/widgets/media_card.dart';
|
||||||
|
|
||||||
|
class SessionViewMedia extends StatelessWidget {
|
||||||
|
const SessionViewMedia({super.key, required this.session});
|
||||||
|
|
||||||
|
final Session session;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return FutureBuilder<List<MediaItem>>(
|
||||||
|
future: MediaItemsDao(Provider.of<AppDatabase>(context))
|
||||||
|
.fromSession(session),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.hasData) {
|
||||||
|
final mediaItems = snapshot.data!;
|
||||||
|
|
||||||
|
List<Widget> mediaCards = List.generate(
|
||||||
|
mediaItems.length, (i) => MediaCard(media: mediaItems[i]));
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 100,
|
||||||
|
child: GridView.count(
|
||||||
|
padding: const EdgeInsets.fromLTRB(15, 0, 0, 0),
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
crossAxisSpacing: 5,
|
||||||
|
mainAxisSpacing: 5,
|
||||||
|
crossAxisCount: 1,
|
||||||
|
children: mediaCards))
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.all(15),
|
||||||
|
child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
//
|
|
||||||
// Generated file. Do not edit.
|
|
||||||
//
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
|
||||||
|
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
//
|
|
||||||
// Generated file. Do not edit.
|
|
||||||
//
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
|
|
||||||
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
|
||||||
#define GENERATED_PLUGIN_REGISTRANT_
|
|
||||||
|
|
||||||
#include <flutter_linux/flutter_linux.h>
|
|
||||||
|
|
||||||
// Registers Flutter plugins.
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry);
|
|
||||||
|
|
||||||
#endif // GENERATED_PLUGIN_REGISTRANT_
|
|
@ -1,23 +0,0 @@
|
|||||||
#
|
|
||||||
# Generated file, do not edit.
|
|
||||||
#
|
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
|
||||||
)
|
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
|
||||||
)
|
|
||||||
|
|
||||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
|
||||||
|
|
||||||
foreach(plugin ${FLUTTER_PLUGIN_LIST})
|
|
||||||
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
|
|
||||||
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
|
|
||||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
|
|
||||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
|
|
||||||
endforeach(plugin)
|
|
||||||
|
|
||||||
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
|
|
||||||
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
|
|
||||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
|
|
||||||
endforeach(ffi_plugin)
|
|
@ -1,10 +0,0 @@
|
|||||||
//
|
|
||||||
// Generated file. Do not edit.
|
|
||||||
//
|
|
||||||
|
|
||||||
import FlutterMacOS
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|
||||||
}
|
|
12
macos/RunnerTests/RunnerTests.swift
Normal file
12
macos/RunnerTests/RunnerTests.swift
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import Cocoa
|
||||||
|
import FlutterMacOS
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
class RunnerTests: XCTestCase {
|
||||||
|
|
||||||
|
func testExample() {
|
||||||
|
// If you add code to the Runner application, consider adding tests here.
|
||||||
|
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
610
pubspec.lock
610
pubspec.lock
@ -1,610 +0,0 @@
|
|||||||
# Generated by pub
|
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
|
||||||
packages:
|
|
||||||
_fe_analyzer_shared:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: _fe_analyzer_shared
|
|
||||||
sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "72.0.0"
|
|
||||||
_macros:
|
|
||||||
dependency: transitive
|
|
||||||
description: dart
|
|
||||||
source: sdk
|
|
||||||
version: "0.3.2"
|
|
||||||
analyzer:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: analyzer
|
|
||||||
sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "6.7.0"
|
|
||||||
args:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: args
|
|
||||||
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.6.0"
|
|
||||||
async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: async
|
|
||||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.11.0"
|
|
||||||
boolean_selector:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: boolean_selector
|
|
||||||
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.1"
|
|
||||||
build:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: build
|
|
||||||
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.4.1"
|
|
||||||
build_config:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: build_config
|
|
||||||
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.1"
|
|
||||||
build_daemon:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: build_daemon
|
|
||||||
sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "4.0.1"
|
|
||||||
build_resolvers:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: build_resolvers
|
|
||||||
sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.4.2"
|
|
||||||
build_runner:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: build_runner
|
|
||||||
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.4.13"
|
|
||||||
build_runner_core:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: build_runner_core
|
|
||||||
sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "7.3.0"
|
|
||||||
built_collection:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: built_collection
|
|
||||||
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "5.1.1"
|
|
||||||
built_value:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: built_value
|
|
||||||
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "8.9.2"
|
|
||||||
characters:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: characters
|
|
||||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
checked_yaml:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: checked_yaml
|
|
||||||
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.3"
|
|
||||||
clock:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: clock
|
|
||||||
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.1"
|
|
||||||
code_builder:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: code_builder
|
|
||||||
sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "4.10.0"
|
|
||||||
collection:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: collection
|
|
||||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.18.0"
|
|
||||||
convert:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: convert
|
|
||||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.1.1"
|
|
||||||
crypto:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: crypto
|
|
||||||
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.3"
|
|
||||||
cupertino_icons:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: cupertino_icons
|
|
||||||
sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.5"
|
|
||||||
dart_style:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: dart_style
|
|
||||||
sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.3.6"
|
|
||||||
fake_async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fake_async
|
|
||||||
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.1"
|
|
||||||
file:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: file
|
|
||||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "7.0.1"
|
|
||||||
fixnum:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fixnum
|
|
||||||
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.1"
|
|
||||||
flutter:
|
|
||||||
dependency: "direct main"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_inappwebview:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: flutter_inappwebview
|
|
||||||
sha256: f73505c792cf083d5566e1a94002311be497d984b5607f25be36d685cf6361cf
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "5.7.2+3"
|
|
||||||
flutter_lints:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: flutter_lints
|
|
||||||
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.1"
|
|
||||||
flutter_test:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
frontend_server_client:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: frontend_server_client
|
|
||||||
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "4.0.0"
|
|
||||||
glob:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: glob
|
|
||||||
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.2"
|
|
||||||
graphs:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: graphs
|
|
||||||
sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.3.1"
|
|
||||||
http_multi_server:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: http_multi_server
|
|
||||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.2.1"
|
|
||||||
http_parser:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: http_parser
|
|
||||||
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "4.0.2"
|
|
||||||
intl:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: intl
|
|
||||||
sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.18.0"
|
|
||||||
io:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: io
|
|
||||||
sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.4"
|
|
||||||
js:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: js
|
|
||||||
sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.6.5"
|
|
||||||
json_annotation:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: json_annotation
|
|
||||||
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "4.9.0"
|
|
||||||
json_serializable:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: json_serializable
|
|
||||||
sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "6.9.0"
|
|
||||||
leak_tracker:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: leak_tracker
|
|
||||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "10.0.5"
|
|
||||||
leak_tracker_flutter_testing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: leak_tracker_flutter_testing
|
|
||||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.5"
|
|
||||||
leak_tracker_testing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: leak_tracker_testing
|
|
||||||
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.1"
|
|
||||||
lints:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lints
|
|
||||||
sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.1"
|
|
||||||
logging:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: logging
|
|
||||||
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
macros:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: macros
|
|
||||||
sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.2-main.4"
|
|
||||||
matcher:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: matcher
|
|
||||||
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.12.16+1"
|
|
||||||
material_color_utilities:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: material_color_utilities
|
|
||||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.11.1"
|
|
||||||
meta:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: meta
|
|
||||||
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.15.0"
|
|
||||||
mime:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: mime
|
|
||||||
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.6"
|
|
||||||
package_config:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: package_config
|
|
||||||
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
path:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path
|
|
||||||
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.9.0"
|
|
||||||
pool:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: pool
|
|
||||||
sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.5.1"
|
|
||||||
pub_semver:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: pub_semver
|
|
||||||
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.4"
|
|
||||||
pubspec_parse:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: pubspec_parse
|
|
||||||
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
scaler:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: scaler
|
|
||||||
sha256: d761b02e08445fa6617338c40903fb6cd2c77660000bafafe928b0287bd5f04a
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.2+1"
|
|
||||||
shelf:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: shelf
|
|
||||||
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.4.1"
|
|
||||||
shelf_web_socket:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: shelf_web_socket
|
|
||||||
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.4"
|
|
||||||
sky_engine:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.99"
|
|
||||||
source_gen:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: source_gen
|
|
||||||
sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.5.0"
|
|
||||||
source_helper:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: source_helper
|
|
||||||
sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.4"
|
|
||||||
source_span:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: source_span
|
|
||||||
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.10.0"
|
|
||||||
stack_trace:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stack_trace
|
|
||||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.11.1"
|
|
||||||
stream_channel:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stream_channel
|
|
||||||
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.2"
|
|
||||||
stream_transform:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stream_transform
|
|
||||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
string_scanner:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: string_scanner
|
|
||||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
term_glyph:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: term_glyph
|
|
||||||
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.1"
|
|
||||||
test_api:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: test_api
|
|
||||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.7.2"
|
|
||||||
timing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: timing
|
|
||||||
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
typed_data:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: typed_data
|
|
||||||
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.2"
|
|
||||||
vector_math:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: vector_math
|
|
||||||
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.4"
|
|
||||||
vm_service:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: vm_service
|
|
||||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "14.2.5"
|
|
||||||
watcher:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: watcher
|
|
||||||
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
web:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: web
|
|
||||||
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.5.1"
|
|
||||||
web_socket_channel:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: web_socket_channel
|
|
||||||
sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.4.5"
|
|
||||||
yaml:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: yaml
|
|
||||||
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.1.2"
|
|
||||||
youtube_player_flutter:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: youtube_player_flutter
|
|
||||||
sha256: "72d487e1a1b9155a2dc9d448c137380791101a0ff623723195275ac275ac6942"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "8.1.2"
|
|
||||||
sdks:
|
|
||||||
dart: ">=3.5.0 <4.0.0"
|
|
||||||
flutter: ">=3.18.0-18.0.pre.54"
|
|
15
pubspec.yaml
15
pubspec.yaml
@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
version: 0.2.1
|
version: 0.2.1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.19.2 <3.0.0'
|
sdk: '>=3.0.0 <4.0.0'
|
||||||
|
|
||||||
# Dependencies specify other packages that your package needs in order to work.
|
# Dependencies specify other packages that your package needs in order to work.
|
||||||
# To automatically upgrade your package dependencies to the latest versions
|
# To automatically upgrade your package dependencies to the latest versions
|
||||||
@ -36,9 +36,14 @@ dependencies:
|
|||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.2
|
||||||
scaler: ^1.1.2+1
|
scaler: ^1.1.2+1
|
||||||
intl: ^0.18.0
|
intl: ^0.20.1
|
||||||
youtube_player_flutter: ^8.1.2
|
youtube_player_flutter: ^9.1.1
|
||||||
json_annotation: ^4.9.0
|
json_annotation: ^4.9.0
|
||||||
|
provider: ^6.1.2
|
||||||
|
scrollable_positioned_list: ^0.3.8
|
||||||
|
drift: ^2.22.1
|
||||||
|
flutter_expandable_fab: ^2.3.0
|
||||||
|
drift_flutter: ^0.2.2
|
||||||
|
|
||||||
flutter_launcher_name:
|
flutter_launcher_name:
|
||||||
name: "SendTrain"
|
name: "SendTrain"
|
||||||
@ -52,9 +57,11 @@ dev_dependencies:
|
|||||||
# activated in the `analysis_options.yaml` file located at the root of your
|
# activated in the `analysis_options.yaml` file located at the root of your
|
||||||
# package. See that file for information about deactivating specific lint
|
# package. See that file for information about deactivating specific lint
|
||||||
# rules and activating additional ones.
|
# rules and activating additional ones.
|
||||||
flutter_lints: ^2.0.0
|
flutter_lints: ^5.0.0
|
||||||
build_runner: ^2.4.13
|
build_runner: ^2.4.13
|
||||||
json_serializable: ^6.9.0
|
json_serializable: ^6.9.0
|
||||||
|
drift_dev: ^2.22.1
|
||||||
|
test: ^1.25.7
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
29
test/drift/sendtrain/generated/schema.dart
Normal file
29
test/drift/sendtrain/generated/schema.dart
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// dart format width=80
|
||||||
|
// GENERATED CODE, DO NOT EDIT BY HAND.
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:drift/internal/migrations.dart';
|
||||||
|
import 'schema_v1.dart' as v1;
|
||||||
|
import 'schema_v2.dart' as v2;
|
||||||
|
import 'schema_v3.dart' as v3;
|
||||||
|
import 'schema_v4.dart' as v4;
|
||||||
|
|
||||||
|
class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
|
@override
|
||||||
|
GeneratedDatabase databaseForVersion(QueryExecutor db, int version) {
|
||||||
|
switch (version) {
|
||||||
|
case 1:
|
||||||
|
return v1.DatabaseAtV1(db);
|
||||||
|
case 2:
|
||||||
|
return v2.DatabaseAtV2(db);
|
||||||
|
case 3:
|
||||||
|
return v3.DatabaseAtV3(db);
|
||||||
|
case 4:
|
||||||
|
return v4.DatabaseAtV4(db);
|
||||||
|
default:
|
||||||
|
throw MissingSchemaException(version, versions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const versions = const [1, 2, 3, 4];
|
||||||
|
}
|
1916
test/drift/sendtrain/generated/schema_v1.dart
Normal file
1916
test/drift/sendtrain/generated/schema_v1.dart
Normal file
File diff suppressed because it is too large
Load Diff
1916
test/drift/sendtrain/generated/schema_v2.dart
Normal file
1916
test/drift/sendtrain/generated/schema_v2.dart
Normal file
File diff suppressed because it is too large
Load Diff
1977
test/drift/sendtrain/generated/schema_v3.dart
Normal file
1977
test/drift/sendtrain/generated/schema_v3.dart
Normal file
File diff suppressed because it is too large
Load Diff
1977
test/drift/sendtrain/generated/schema_v4.dart
Normal file
1977
test/drift/sendtrain/generated/schema_v4.dart
Normal file
File diff suppressed because it is too large
Load Diff
104
test/drift/sendtrain/migration_test.dart
Normal file
104
test/drift/sendtrain/migration_test.dart
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// // dart format width=80
|
||||||
|
// // ignore_for_file: unused_local_variable, unused_import
|
||||||
|
// import 'package:drift/drift.dart';
|
||||||
|
// import 'package:drift_dev/api/migrations_native.dart';
|
||||||
|
// import 'package:sendtrain/database/database.dart';
|
||||||
|
// import 'package:test/test.dart';
|
||||||
|
// import 'generated/schema.dart';
|
||||||
|
|
||||||
|
// import 'generated/schema_v1.dart' as v1;
|
||||||
|
// import 'generated/schema_v2.dart' as v2;
|
||||||
|
|
||||||
|
// void main() {
|
||||||
|
// driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
|
||||||
|
// late SchemaVerifier verifier;
|
||||||
|
|
||||||
|
// setUpAll(() {
|
||||||
|
// verifier = SchemaVerifier(GeneratedHelper());
|
||||||
|
// });
|
||||||
|
|
||||||
|
// group('simple database migrations', () {
|
||||||
|
// // These simple tests verify all possible schema updates with a simple (no
|
||||||
|
// // data) migration. This is a quick way to ensure that written database
|
||||||
|
// // migrations properly alter the schema.
|
||||||
|
// final versions = GeneratedHelper.versions;
|
||||||
|
// for (final (i, fromVersion) in versions.indexed) {
|
||||||
|
// group('from $fromVersion', () {
|
||||||
|
// for (final toVersion in versions.skip(i + 1)) {
|
||||||
|
// test('to $toVersion', () async {
|
||||||
|
// final schema = await verifier.schemaAt(fromVersion);
|
||||||
|
// final db = AppDatabase(schema.newConnection());
|
||||||
|
// await verifier.migrateAndValidate(db, toVersion);
|
||||||
|
// await db.close();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // The following template shows how to write tests ensuring your migrations
|
||||||
|
// // preserve existing data.
|
||||||
|
// // Testing this can be useful for migrations that change existing columns
|
||||||
|
// // (e.g. by alterating their type or constraints). Migrations that only add
|
||||||
|
// // tables or columns typically don't need these advanced tests. For more
|
||||||
|
// // information, see https://drift.simonbinder.eu/migrations/tests/#verifying-data-integrity
|
||||||
|
// // TODO: This generated template shows how these tests could be written. Adopt
|
||||||
|
// // it to your own needs when testing migrations with data integrity.
|
||||||
|
// test("migration from v1 to v2 does not corrupt data", () async {
|
||||||
|
// // Add data to insert into the old database, and the expected rows after the
|
||||||
|
// // migration.
|
||||||
|
// // TODO: Fill these lists
|
||||||
|
// final oldSessionsData = <v1.SessionsData>[];
|
||||||
|
// final expectedNewSessionsData = <v2.SessionsData>[];
|
||||||
|
|
||||||
|
// final oldActivitiesData = <v1.ActivitiesData>[];
|
||||||
|
// final expectedNewActivitiesData = <v2.ActivitiesData>[];
|
||||||
|
|
||||||
|
// final oldSessionActivitiesData = <v1.SessionActivitiesData>[];
|
||||||
|
// final expectedNewSessionActivitiesData = <v2.SessionActivitiesData>[];
|
||||||
|
|
||||||
|
// final oldActionsData = <v1.ActionsData>[];
|
||||||
|
// final expectedNewActionsData = <v2.ActionsData>[];
|
||||||
|
|
||||||
|
// final oldActivityActionsData = <v1.ActivityActionsData>[];
|
||||||
|
// final expectedNewActivityActionsData = <v2.ActivityActionsData>[];
|
||||||
|
|
||||||
|
// final oldMediaItemsData = <v1.MediaItemsData>[];
|
||||||
|
// final expectedNewMediaItemsData = <v2.MediaItemsData>[];
|
||||||
|
|
||||||
|
// final oldObjectMediaItemsData = <v1.ObjectMediaItemsData>[];
|
||||||
|
// final expectedNewObjectMediaItemsData = <v2.ObjectMediaItemsData>[];
|
||||||
|
|
||||||
|
// await verifier.testWithDataIntegrity(
|
||||||
|
// oldVersion: 1,
|
||||||
|
// newVersion: 2,
|
||||||
|
// createOld: v1.DatabaseAtV1.new,
|
||||||
|
// createNew: v2.DatabaseAtV2.new,
|
||||||
|
// openTestedDatabase: AppDatabase.new,
|
||||||
|
// createItems: (batch, oldDb) {
|
||||||
|
// batch.insertAll(oldDb.sessions, oldSessionsData);
|
||||||
|
// batch.insertAll(oldDb.activities, oldActivitiesData);
|
||||||
|
// batch.insertAll(oldDb.sessionActivities, oldSessionActivitiesData);
|
||||||
|
// batch.insertAll(oldDb.actions, oldActionsData);
|
||||||
|
// batch.insertAll(oldDb.activityActions, oldActivityActionsData);
|
||||||
|
// batch.insertAll(oldDb.mediaItems, oldMediaItemsData);
|
||||||
|
// batch.insertAll(oldDb.objectMediaItems, oldObjectMediaItemsData);
|
||||||
|
// },
|
||||||
|
// validateItems: (newDb) async {
|
||||||
|
// expect(
|
||||||
|
// expectedNewSessionsData, await newDb.select(newDb.sessions).get());
|
||||||
|
// expect(expectedNewActivitiesData,
|
||||||
|
// await newDb.select(newDb.activities).get());
|
||||||
|
// expect(expectedNewSessionActivitiesData,
|
||||||
|
// await newDb.select(newDb.sessionActivities).get());
|
||||||
|
// expect(expectedNewActionsData, await newDb.select(newDb.actions).get());
|
||||||
|
// expect(expectedNewActivityActionsData,
|
||||||
|
// await newDb.select(newDb.activityActions).get());
|
||||||
|
// expect(expectedNewMediaItemsData,
|
||||||
|
// await newDb.select(newDb.mediaItems).get());
|
||||||
|
// expect(expectedNewObjectMediaItemsData,
|
||||||
|
// await newDb.select(newDb.objectMediaItems).get());
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// });
|
||||||
|
// }
|
@ -1,11 +0,0 @@
|
|||||||
//
|
|
||||||
// Generated file. Do not edit.
|
|
||||||
//
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
|
||||||
|
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
//
|
|
||||||
// Generated file. Do not edit.
|
|
||||||
//
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
|
|
||||||
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
|
||||||
#define GENERATED_PLUGIN_REGISTRANT_
|
|
||||||
|
|
||||||
#include <flutter/plugin_registry.h>
|
|
||||||
|
|
||||||
// Registers Flutter plugins.
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry);
|
|
||||||
|
|
||||||
#endif // GENERATED_PLUGIN_REGISTRANT_
|
|
@ -1,23 +0,0 @@
|
|||||||
#
|
|
||||||
# Generated file, do not edit.
|
|
||||||
#
|
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
|
||||||
)
|
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
|
||||||
)
|
|
||||||
|
|
||||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
|
||||||
|
|
||||||
foreach(plugin ${FLUTTER_PLUGIN_LIST})
|
|
||||||
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
|
|
||||||
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
|
|
||||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
|
|
||||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
|
|
||||||
endforeach(plugin)
|
|
||||||
|
|
||||||
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
|
|
||||||
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
|
|
||||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
|
|
||||||
endforeach(ffi_plugin)
|
|
Reference in New Issue
Block a user