new kirby backend!

global colors and themes!
This commit is contained in:
MSpeed 2020-02-07 18:06:10 +01:00
parent c16256ac16
commit 71e1561368
32 changed files with 1095 additions and 485 deletions

View File

@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"audioplayers","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/audioplayers-0.14.0/","dependencies":["path_provider"]},{"name":"cloud_firestore","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.0+1/","dependencies":["firebase_core"]},{"name":"firebase_analytics","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_analytics-5.0.9/","dependencies":[]},{"name":"firebase_auth","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.15.3+1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.3+2/","dependencies":[]},{"name":"path_provider","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.5.1/","dependencies":[]}],"android":[{"name":"audioplayers","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/audioplayers-0.14.0/","dependencies":["path_provider"]},{"name":"cloud_firestore","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.0+1/","dependencies":["firebase_core"]},{"name":"firebase_analytics","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_analytics-5.0.9/","dependencies":[]},{"name":"firebase_auth","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.15.3+1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.3+2/","dependencies":[]},{"name":"path_provider","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.5.1/","dependencies":[]}],"macos":[{"name":"audioplayers","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/audioplayers-0.14.0/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"audioplayers","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/audioplayers-0.14.0/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.1+1/","dependencies":[]},{"name":"firebase_core_web","path":"/Users/mike/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+1/","dependencies":[]}]},"dependencyGraph":[{"name":"audioplayers","dependencies":["path_provider"]},{"name":"cloud_firestore","dependencies":["firebase_core"]},{"name":"firebase_analytics","dependencies":[]},{"name":"firebase_auth","dependencies":["firebase_core","firebase_auth_web"]},{"name":"firebase_auth_web","dependencies":[]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"path_provider","dependencies":[]}],"date_created":"2020-01-27 15:52:17.624749","version":"1.14.2-pre.53"}
{"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"audioplayers","dependencies":["path_provider"]},{"name":"path_provider","dependencies":[]}]}

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path fill="#000" fill-rule="nonzero" d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6m-1 11h-2v5a2 2 0 1 1-2-2c.4 0 .7.1 1 .3V11h3v2m0-4V3.5L18.5 9H13z"/>
<path d="M0 0h24v24H0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 355 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path fill="#000" fill-rule="nonzero" d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m9 16v-2H6v2h9m3-4v-2H6v2h12z"/>
<path d="M0 0h24v24H0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 335 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path fill="#000" fill-rule="nonzero" d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/>
<path d="M0 0h24v24H0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 318 B

View File

@ -0,0 +1,18 @@
#
# NOTE: This podspec is NOT to be published. It is only used as a local source!
#
Pod::Spec.new do |s|
s.name = 'Flutter'
s.version = '1.0.0'
s.summary = 'High-performance, high-fidelity mobile apps.'
s.description = <<-DESC
Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS.
DESC
s.homepage = 'https://flutter.io'
s.license = { :type => 'MIT' }
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.vendored_frameworks = 'Flutter.framework'
end

View File

@ -2,9 +2,10 @@
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/Users/mike/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/mike/AndroidStudioProjects/medito-app"
export "FLUTTER_TARGET=lib/main.dart"
export "FLUTTER_TARGET=/Users/mike/AndroidStudioProjects/medito-app/lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
export "FLUTTER_FRAMEWORK_DIR=/Users/mike/flutter/bin/cache/artifacts/engine/ios"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "TRACK_WIDGET_CREATION=true"

View File

@ -85,3 +85,8 @@ post_install do |installer|
end
end
end
# add the Firebase pod for Google Analytics
pod 'Firebase/Analytics'
# add pods for any other desired Firebase products
# https://firebase.google.com/docs/ios/setup#available-pods

129
ios/Podfile.lock Normal file
View File

@ -0,0 +1,129 @@
PODS:
- audioplayers (0.0.1):
- Flutter
- Firebase/Analytics (6.16.0):
- Firebase/Core
- Firebase/Core (6.16.0):
- Firebase/CoreOnly
- FirebaseAnalytics (= 6.2.2)
- Firebase/CoreOnly (6.16.0):
- FirebaseCore (= 6.6.1)
- FirebaseAnalytics (6.2.2):
- FirebaseCore (~> 6.6)
- FirebaseInstanceID (~> 4.3)
- GoogleAppMeasurement (= 6.2.2)
- GoogleUtilities/AppDelegateSwizzler (~> 6.0)
- GoogleUtilities/MethodSwizzler (~> 6.0)
- GoogleUtilities/Network (~> 6.0)
- "GoogleUtilities/NSData+zlib (~> 6.0)"
- nanopb (= 0.3.9011)
- FirebaseCore (6.6.1):
- FirebaseCoreDiagnostics (~> 1.2)
- FirebaseCoreDiagnosticsInterop (~> 1.2)
- GoogleUtilities/Environment (~> 6.5)
- GoogleUtilities/Logger (~> 6.5)
- FirebaseCoreDiagnostics (1.2.0):
- FirebaseCoreDiagnosticsInterop (~> 1.2)
- GoogleDataTransportCCTSupport (~> 1.3)
- GoogleUtilities/Environment (~> 6.5)
- GoogleUtilities/Logger (~> 6.5)
- nanopb (~> 0.3.901)
- FirebaseCoreDiagnosticsInterop (1.2.0)
- FirebaseInstallations (1.1.0):
- FirebaseCore (~> 6.6)
- GoogleUtilities/UserDefaults (~> 6.5)
- PromisesObjC (~> 1.2)
- FirebaseInstanceID (4.3.0):
- FirebaseCore (~> 6.6)
- FirebaseInstallations (~> 1.0)
- GoogleUtilities/Environment (~> 6.5)
- GoogleUtilities/UserDefaults (~> 6.5)
- Flutter (1.0.0)
- GoogleAppMeasurement (6.2.2):
- GoogleUtilities/AppDelegateSwizzler (~> 6.0)
- GoogleUtilities/MethodSwizzler (~> 6.0)
- GoogleUtilities/Network (~> 6.0)
- "GoogleUtilities/NSData+zlib (~> 6.0)"
- nanopb (= 0.3.9011)
- GoogleDataTransport (3.3.1)
- GoogleDataTransportCCTSupport (1.3.1):
- GoogleDataTransport (~> 3.3)
- nanopb (~> 0.3.901)
- GoogleUtilities/AppDelegateSwizzler (6.5.1):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (6.5.1)
- GoogleUtilities/Logger (6.5.1):
- GoogleUtilities/Environment
- GoogleUtilities/MethodSwizzler (6.5.1):
- GoogleUtilities/Logger
- GoogleUtilities/Network (6.5.1):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (6.5.1)"
- GoogleUtilities/Reachability (6.5.1):
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (6.5.1):
- GoogleUtilities/Logger
- nanopb (0.3.9011):
- nanopb/decode (= 0.3.9011)
- nanopb/encode (= 0.3.9011)
- nanopb/decode (0.3.9011)
- nanopb/encode (0.3.9011)
- path_provider (0.0.1):
- Flutter
- PromisesObjC (1.2.8)
DEPENDENCIES:
- audioplayers (from `.symlinks/plugins/audioplayers/ios`)
- Firebase/Analytics
- Flutter (from `Flutter`)
- path_provider (from `.symlinks/plugins/path_provider/ios`)
SPEC REPOS:
trunk:
- Firebase
- FirebaseAnalytics
- FirebaseCore
- FirebaseCoreDiagnostics
- FirebaseCoreDiagnosticsInterop
- FirebaseInstallations
- FirebaseInstanceID
- GoogleAppMeasurement
- GoogleDataTransport
- GoogleDataTransportCCTSupport
- GoogleUtilities
- nanopb
- PromisesObjC
EXTERNAL SOURCES:
audioplayers:
:path: ".symlinks/plugins/audioplayers/ios"
Flutter:
:path: Flutter
path_provider:
:path: ".symlinks/plugins/path_provider/ios"
SPEC CHECKSUMS:
audioplayers: 84f968cea3f2deab00ec4f8ff53358b3c0b3992c
Firebase: 497158b816d0a86fc31babbd05546fcd7e6083ff
FirebaseAnalytics: cf95d3aab897612783020fbd98401d5366f135ee
FirebaseCore: 85064903ed6c28e47fec9c7bd149d94ba1b6b6e7
FirebaseCoreDiagnostics: 5e78803ab276bc5b50340e3c539c06c3de35c649
FirebaseCoreDiagnosticsInterop: 296e2c5f5314500a850ad0b83e9e7c10b011a850
FirebaseInstallations: 575cd32f2aec0feeb0e44f5d0110a09e5e60b47b
FirebaseInstanceID: 6668efc1655a4052c083f287a7141f1ead12f9c2
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
GoogleAppMeasurement: d0560d915abf15e692e8538ba1d58442217b6aff
GoogleDataTransport: 0048df6388dab1c254799f2a30365b1dffe20422
GoogleDataTransportCCTSupport: f880d70972efa2ed1be4e9173a0f4c5f3dc2d176
GoogleUtilities: 06eb53bb579efe7099152735900dd04bf09e7275
nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd
path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d
PromisesObjC: c119f3cd559f50b7ae681fa59dc1acd19173b7e6
PODFILE CHECKSUM: b8af44eb4c3d77cc1aa98fc962b2d0a41fc947bf
COCOAPODS: 1.8.4

View File

@ -8,6 +8,8 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
24480205BEE9BAD4E0D04776 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 12EE22FF53D42593D34B2413 /* libPods-Runner.a */; };
27290B5523E1C80A00546788 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 27290B5423E1C80A00546788 /* GoogleService-Info.plist */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@ -37,8 +39,10 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
12EE22FF53D42593D34B2413 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
27290B5423E1C80A00546788 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
@ -53,6 +57,9 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
E00F74376D731E000F73D8D5 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
E423932AC7075EF4D3703817 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
F783C9DD37E80ECD11E22E74 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -62,12 +69,23 @@
files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
24480205BEE9BAD4E0D04776 /* libPods-Runner.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
66CE201F2CE614DBD3474B09 /* Pods */ = {
isa = PBXGroup;
children = (
E00F74376D731E000F73D8D5 /* Pods-Runner.debug.xcconfig */,
E423932AC7075EF4D3703817 /* Pods-Runner.release.xcconfig */,
F783C9DD37E80ECD11E22E74 /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
@ -87,7 +105,8 @@
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
CF3B75C9A7D2FA2A4C99F110 /* Frameworks */,
66CE201F2CE614DBD3474B09 /* Pods */,
B4F17FFDF40DDB90D8AC283B /* Frameworks */,
);
sourceTree = "<group>";
};
@ -108,6 +127,7 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
27290B5423E1C80A00546788 /* GoogleService-Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
@ -123,6 +143,14 @@
name = "Supporting Files";
sourceTree = "<group>";
};
B4F17FFDF40DDB90D8AC283B /* Frameworks */ = {
isa = PBXGroup;
children = (
12EE22FF53D42593D34B2413 /* libPods-Runner.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -130,12 +158,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
B4C77C396A9408DF5B6B85BD /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
7E197E15500F7C460315CD16 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@ -188,6 +218,7 @@
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
27290B5523E1C80A00546788 /* GoogleService-Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -208,6 +239,21 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
};
7E197E15500F7C460315CD16 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@ -222,6 +268,28 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
B4C77C396A9408DF5B6B85BD /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */

View File

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

View File

@ -4,4 +4,7 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

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

View File

@ -1,13 +1,16 @@
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
@import Firebase;
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
[FIRApp configure];
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>969745075381-af18h04fg4a7cqp1u3oaek5110d69l1k.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.969745075381-af18h04fg4a7cqp1u3oaek5110d69l1k</string>
<key>ANDROID_CLIENT_ID</key>
<string>969745075381-ppfpe8si0gmr2hic8c5qqelg2ive2n46.apps.googleusercontent.com</string>
<key>API_KEY</key>
<string>AIzaSyAfubUIAiRDxuSuWUdNwnTFqPgYy11UDLY</string>
<key>GCM_SENDER_ID</key>
<string>969745075381</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>meditofoundation.meditoApp</string>
<key>PROJECT_ID</key>
<string>medito-9c82d</string>
<key>STORAGE_BUCKET</key>
<string>medito-9c82d.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:969745075381:ios:9e44e0cc5f2465a9dd42fc</string>
<key>DATABASE_URL</key>
<string>https://medito-9c82d.firebaseio.com</string>
</dict>
</plist>

View File

@ -1,39 +0,0 @@
import 'package:cloud_firestore/cloud_firestore.dart';
class Api {
final Firestore _db = Firestore.instance;
final String path;
CollectionReference ref;
Api(this.path) {
ref = _db.collection(path);
}
Future<QuerySnapshot> getDataCollection() {
return ref.getDocuments();
}
Stream<QuerySnapshot> streamDataCollection() {
return ref.snapshots();
}
Future<DocumentSnapshot> getDocumentById(String id) {
return ref.document(id).get();
}
Future<void> removeDocument(String id) {
return ref.document(id).delete();
}
Future<DocumentReference> addDocument(Map data) {
return ref.add(data);
}
//https://pub.dev/packages/cloud_firestore
static Future<void> updateSubscribers(String email) {
return Firestore.instance
.collection('subscribers')
.document()
.setData({"1": email});
}
}

View File

@ -1,5 +1,6 @@
import 'package:audioplayers/audioplayers.dart';
//This
class MeditoAudioPlayer {
static final MeditoAudioPlayer _singleton = MeditoAudioPlayer._internal();
AudioPlayer audioPlayer = AudioPlayer();

View File

@ -2,11 +2,12 @@ import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'package:marquee/marquee.dart';
import 'package:medito/audioplayer/audiosingleton.dart';
import 'package:medito/viewmodel/filemodel.dart';
import 'package:medito/viewmodel/list_item.dart';
import 'package:flutter_svg/flutter_svg.dart';
class PlayerWidget extends StatefulWidget {
PlayerWidget({Key key, this.fileModel}) : super(key: key);
final FileModel fileModel;
final ListItem fileModel;
@override
_PlayerWidgetState createState() {
@ -127,13 +128,13 @@ class _PlayerWidgetState extends State<PlayerWidget> {
startPadding: 16,
crossAxisAlignment: CrossAxisAlignment.center,
accelerationCurve: Curves.easeInOut,
text: widget.fileModel != null ? widget.fileModel.fileName : " ",
text: widget.fileModel != null ? widget.fileModel.title : " ",
);
}
void _play() async {
int result =
await MeditoAudioPlayer().audioPlayer.play(widget.fileModel.fileUrl);
await MeditoAudioPlayer().audioPlayer.play(widget.fileModel.url);
if (result == 1) {
setState(() {
_playing = true;

7
lib/colors.dart Normal file
View File

@ -0,0 +1,7 @@
import 'package:flutter/material.dart';
class MeditioColors {
var ripple = Colors.orangeAccent;
var main = Colors.green;
var secondary = Colors.lightGreen;
}

View File

@ -1,10 +1,11 @@
import 'package:flutter/material.dart';
import 'package:medito/viewmodel/filemodel.dart';
import 'package:flutter_svg/svg.dart';
import 'package:medito/viewmodel/list_item.dart';
class ListItemFileWidget extends StatelessWidget {
ListItemFileWidget({Key key, this.item}) : super(key: key);
final FileModel item;
final ListItem item;
@override
Widget build(BuildContext context) {
@ -12,13 +13,12 @@ class ListItemFileWidget extends StatelessWidget {
Flexible(
child: Container(
padding: EdgeInsets.fromLTRB(16, 12, 16, 16),
margin: EdgeInsets.all(4.0),
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(right: 8.0, left: 8),
padding: EdgeInsets.only(right: 12.0, left: 4, top: 4),
child: getIcon(),
),
Flexible(
@ -26,13 +26,13 @@ class ListItemFileWidget extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
item.fileName,
style: const TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.bold,
),
),
Text(item.title, style: Theme.of(context).textTheme.title),
item.description == null || item.description.isEmpty
? Container()
: Text(
item.description,
style: Theme.of(context).textTheme.subhead,
),
],
))),
],
@ -41,15 +41,21 @@ class ListItemFileWidget extends StatelessWidget {
]);
}
Icon getIcon() {
switch (item.type) {
Widget getIcon() {
var path;
switch (item.fileType) {
case FileType.audio:
return Icon(Icons.description);
break;
case FileType.text:
return Icon(Icons.audiotrack);
break;
case FileType.text:
path = 'assets/images/ic_document.svg';
break;
case FileType.both:
path = 'assets/images/ic_audio.svg';
break;
}
return Icon(Icons.audiotrack);
return SvgPicture.asset(
path,
);
}
}

View File

@ -1,11 +1,10 @@
import 'package:flutter/material.dart';
import 'viewmodel/ListItemModel.dart';
import 'package:medito/viewmodel/list_item.dart';
class ListItemFolderWidget extends StatelessWidget {
ListItemFolderWidget({Key key, this.listItemModel}) : super(key: key);
final FolderModel listItemModel;
final ListItem listItemModel;
@override
Widget build(BuildContext context) {
@ -13,13 +12,12 @@ class ListItemFolderWidget extends StatelessWidget {
Flexible(
child: Container(
padding: EdgeInsets.fromLTRB(16, 12, 16, 16),
margin: EdgeInsets.all(4.0),
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(right: 8.0, left: 8),
padding: EdgeInsets.only(right: 12.0, left: 4, top: 4),
child: Icon(Icons.folder),
),
Flexible(
@ -27,15 +25,11 @@ class ListItemFolderWidget extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
listItemModel.title,
style: const TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.bold,
),
),
Container(height: 5),
getDescWidget(),
Text(listItemModel.title,
style: Theme.of(context).textTheme.title),
Container(
height: listItemModel.description.isNotEmpty ? 5 : 0),
getDescWidget(context),
],
))),
],
@ -44,14 +38,12 @@ class ListItemFolderWidget extends StatelessWidget {
]);
}
Widget getDescWidget() {
if (listItemModel.description.isNotEmpty) {
Widget getDescWidget(BuildContext context) {
if (listItemModel.description != null &&
listItemModel.description.isNotEmpty) {
return Text(
listItemModel.description,
style: const TextStyle(
fontSize: 16.0,
color: Colors.black54,
),
style: Theme.of(context).textTheme.subhead,
);
} else
return Container();

View File

@ -1,18 +1,14 @@
import 'dart:async';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:medito/api/api.dart';
import 'package:medito/audioplayer/playerwidget.dart';
import 'package:medito/listitemfilewidget.dart';
import 'package:medito/listitemfolderwidget.dart';
import 'package:medito/navwidget.dart';
import 'package:medito/viewmodel/ListItemModel.dart';
import 'package:medito/viewmodel/filemodel.dart';
import 'package:medito/viewmodel/list_item.dart';
import 'package:medito/viewmodel/listviewmodel.dart';
import 'audioplayer/audiosingleton.dart';
import 'navwidget.dart';
void main() => runApp(MyApp());
@ -24,11 +20,17 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
textTheme: GoogleFonts.dMSansTextTheme(
Theme
.of(context)
.textTheme,
)),
textTheme:
GoogleFonts.dMSansTextTheme(Theme.of(context).textTheme.copyWith(
title: TextStyle(
fontSize: 24.0,
color: Color(0xff2e3134),
fontWeight: FontWeight.w600),
subhead: TextStyle(
fontSize: 16.0,
color: Color(0xff595959),
fontWeight: FontWeight.normal),
))),
title: _title,
home: Scaffold(
appBar: null, //AppBar(title: const Text(_title)),
@ -58,113 +60,12 @@ class MainWidget extends StatefulWidget {
_MainWidgetState createState() => _MainWidgetState();
}
class _PlaceHolderState extends State<MainWidget> {
final _viewModel = new SubscriptionViewModelImpl();
final controller = TextEditingController();
int currentPage = 0;
static List<FolderModel> filesList = [];
final emailAddressController = TextEditingController();
final _formKey = GlobalKey<FormState>();
final String emailRegex =
r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?)*$";
@override
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Image.network("https://source.unsplash.com/AvLHH8qYbAI",
height: 300, width: double.infinity, fit: BoxFit.fitWidth),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
"To make sure we provide the best service possible, we give access to new comers on a daily basis. \n\nEnter your email below and we will let you know when you can access the app.",
style: const TextStyle(
color: const Color(0xff656565),
fontStyle: FontStyle.normal,
fontSize: 16.0)),
),
Padding(
padding: const EdgeInsets.only(left: 16, right: 16),
child: TextFormField(
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black, width: 1.0),
),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 1.0),
),
hintText: 'email address'),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (!RegExp(emailRegex).hasMatch(value)) {
return "Please enter a valid email address";
}
if (value.isEmpty) {
return 'Please enter your emaill address';
}
return null;
},
),
),
Padding(
padding: const EdgeInsets.only(left: 16, right: 16, top: 4),
child: Text("* Well never share your email address",
style: const TextStyle(
fontStyle: FontStyle.normal, fontSize: 10.0)),
),
Padding(
padding: const EdgeInsets.all(16),
child: FlatButton(
textColor: Colors.white,
color: Colors.black,
onPressed: () {
// Validate returns true if the form is valid, or false
// otherwise.
if (_formKey.currentState.validate()) {
// If the form is valid, display a Snackbar.
_fire();
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Subscribing...')));
}
},
child: Text(
'JOIN WAITING LIST',
style: TextStyle(fontWeight: FontWeight.w600),
),
),
),
],
),
),
);
}
void _fire() {
Api.updateSubscribers(emailAddressController.text)
.whenComplete(_doneSnackBar);
}
FutureOr _doneSnackBar() {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('Complete. Thanks!'),
backgroundColor: Colors.green,
));
}
}
/////
class _MainWidgetState extends State<MainWidget> with TickerProviderStateMixin {
final _viewModel = new SubscriptionViewModelImpl();
Future<List<ListItem>> listFuture;
final controller = TextEditingController();
int currentPage = 0;
static List<FolderModel> currentFolderList = [];
static List<FileModel> currentFilesList = [];
var bottomSheetController;
AnimationController _controller;
@ -177,35 +78,43 @@ class _MainWidgetState extends State<MainWidget> with TickerProviderStateMixin {
double fileListOpacity = 1;
String transcriptionText = "";
@override
void initState() {
super.initState();
listFuture = _viewModel.getPage();
}
void initAnimation() {
screenWidth = MediaQuery
.of(context)
.size
.width;
screenHeight = MediaQuery
.of(context)
.size
.height;
// call after initState because MediaQuery
// cannot complete until initState has completed
screenWidth = MediaQuery.of(context).size.width;
screenHeight = MediaQuery.of(context).size.height;
_controller = new AnimationController(
duration: const Duration(milliseconds: 250),
vsync: this,
);
)..addStatusListener((i) {
print(i);
});
_animation = Tween<double>(
end: screenHeight - bottomSheetViewHeight, begin: screenHeight)
end: screenHeight - bottomSheetViewHeight, begin: screenHeight)
.animate(_controller)
..addStatusListener((listener) {
if (listener == AnimationStatus.completed) {
_viewModel.playerOpen = true;
} else if (listener == AnimationStatus.dismissed) {
_viewModel.playerOpen = false;
}
});
..addStatusListener((listener) {
if (listener == AnimationStatus.completed) {
_viewModel.playerOpen = true;
} else if (listener == AnimationStatus.dismissed) {
_viewModel.playerOpen = false;
}
});
}
@override
Widget build(BuildContext context) {
if (_controller == null) {
initAnimation();
}
MeditoAudioPlayer()
.audioPlayer
.onPlayerStateChanged
@ -215,20 +124,14 @@ class _MainWidgetState extends State<MainWidget> with TickerProviderStateMixin {
}
});
// set up first page
if (currentFolderList.isEmpty) {
initAnimation();
currentFolderList.addAll(_viewModel.getFirstFolderContents());
}
// end of set up first page
return Scaffold(
backgroundColor: Color(0xfffff1ec),
body: Stack(children: <Widget>[
SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new NavWidget(
NavWidget(
list: _viewModel.navList,
backPressed: _backPressed,
),
@ -246,18 +149,6 @@ class _MainWidgetState extends State<MainWidget> with TickerProviderStateMixin {
);
}
Container buildBottomSheet() {
return new Container(
color: Colors.green,
child: new PlayerWidget(
fileModel: _viewModel.currentlySelectedFile,
),
margin: EdgeInsets.only(top: _animation.value),
height: bottomSheetViewHeight,
width: screenWidth,
);
}
Stack buildFolderNavigator() {
return Stack(
children: <Widget>[
@ -276,82 +167,56 @@ class _MainWidgetState extends State<MainWidget> with TickerProviderStateMixin {
);
}
void _backPressed(String value) {
setState(() {
if (transcriptionOpacity == 1) {
transcriptionText = "";
transcriptionOpacity = 0;
fileListOpacity = 1;
_viewModel.navList.removeLast();
} else {
currentFolderList = _viewModel.backUp();
currentFilesList.clear();
var files = _viewModel.getFilesForId(currentFolderList[0].parentId);
currentFilesList.addAll(files);
}
});
}
Widget getFolderListItem(FolderModel listItemModel) {
return new ListItemFolderWidget(listItemModel: listItemModel);
}
Widget getListView() {
var length = currentFolderList.length + currentFilesList.length;
return FutureBuilder(
future: listFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.none ||
snapshot.hasData == false ||
snapshot.hasData == null) {
return Container(
color: Colors.red,
);
}
return new ListView.builder(
itemCount: length,
shrinkWrap: true,
itemBuilder: (BuildContext context, int i) {
return Column(
children: <Widget>[
InkWell(
splashColor: Colors.orange,
child: getChildForListView(i),
onTap: () {
listItemTap(i);
setState(() {});
}),
Container(height: i == length -1 ? 200: 0)
],
);
return new ListView.builder(
itemCount: snapshot.data == null ? 0 : snapshot.data.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, int i) {
return Column(
children: <Widget>[
InkWell(
splashColor: Colors.orange,
child: getChildForListView(snapshot.data[i]),
onTap: () {
listItemTap(snapshot.data[i]);
setState(() {});
}),
Container(height: i == snapshot.data.length - 1 ? 200 : 0)
],
);
});
});
}
Widget getChildForListView(int i) {
if (i < currentFolderList.length) {
return getFolderListItem(currentFolderList[i]);
} else {
return getFileListItem(getFileTapped(i));
}
}
void listItemTap(int i) {
void listItemTap(ListItem i) {
//if you tapped on a folder
if (i < currentFolderList.length) {
_viewModel.addToNavList(currentFolderList[i].title);
int id = currentFolderList[i].id;
var folder = _viewModel.getFolderContents(id);
var files = _viewModel.getFilesForId(id);
currentFilesList.clear();
currentFilesList.addAll(files);
if (folder.length != 0) {
currentFolderList.clear();
currentFolderList.addAll(folder);
}
if (i.type == ListItemType.folder) {
setState(() {
_viewModel.addToNavList(i);
listFuture = _viewModel.getPage(id: i.id);
});
}
//if you tapped on a file
else {
var fileTapped = getFileTapped(i);
showPlayer(fileTapped);
if (i.fileType == FileType.audio || i.fileType == FileType.both) {
showPlayer(i);
}
if (fileTapped.transcription.isNotEmpty) {
_viewModel.addToNavList(fileTapped.fileName);
if (i.contentText.isNotEmpty) {
_viewModel.addToNavList(i);
setState(() {
transcriptionText = fileTapped.transcription;
transcriptionText = i.contentText;
transcriptionOpacity = 1;
fileListOpacity = 0;
});
@ -359,14 +224,7 @@ class _MainWidgetState extends State<MainWidget> with TickerProviderStateMixin {
}
}
FileModel getFileTapped(int i) =>
currentFilesList[i - currentFolderList.length];
Widget getFileListItem(FileModel file) {
return new ListItemFileWidget(item: file);
}
void showPlayer(FileModel fileTapped) {
void showPlayer(ListItem fileTapped) {
if (fileTapped == _viewModel.currentlySelectedFile) {
return;
}
@ -390,4 +248,46 @@ class _MainWidgetState extends State<MainWidget> with TickerProviderStateMixin {
_viewModel.playerOpen = false;
}
}
Widget getFolderListItem(ListItem listItemModel) {
return new ListItemFolderWidget(listItemModel: listItemModel);
}
Widget getFileListItem(ListItem item) {
return new ListItemFileWidget(item: item);
}
Widget getChildForListView(ListItem item) {
if (item.type == ListItemType.folder) {
return getFolderListItem(item);
} else {
return getFileListItem(item);
}
}
void _backPressed(String id) {
setState(() {
if (transcriptionOpacity == 1) {
transcriptionText = "";
transcriptionOpacity = 0;
fileListOpacity = 1;
} else {
listFuture = _viewModel.getPage(id: id);
}
_viewModel.navList.removeLast();
});
}
Widget buildBottomSheet() {
return Container(
child: new Container(
color: Colors.green,
child: new PlayerWidget(
fileModel: _viewModel.currentlySelectedFile,
),
margin: EdgeInsets.only(top: _animation.value),
height: bottomSheetViewHeight,
),
);
}
}

View File

@ -1,9 +1,10 @@
import 'package:flutter/material.dart';
import 'package:medito/viewmodel/list_item.dart';
class NavWidget extends StatefulWidget {
const NavWidget({Key key, this.list, this.backPressed}) : super(key: key);
final List<String> list;
final List<ListItem> list;
final ValueChanged<String> backPressed;
@override
@ -58,6 +59,7 @@ class _NavWidgetState extends State<NavWidget>
List<Widget> getPills() {
List<Widget> columns = new List<Widget>();
if (widget.list == null) return columns;
int startNumber = 0;
if (widget.list.length >= 2) {
@ -76,18 +78,19 @@ class _NavWidgetState extends State<NavWidget>
}
});
var label = widget.list[i];
var label = widget.list[i].title;
if (widget.list.length > 1 && i == startNumber) {
label = "< " + label;
}
columns.add(GestureDetector(
onTap: () {
if (i == startNumber) widget.backPressed(widget.list[i]);
if (i == startNumber) widget.backPressed(widget.list[i].parentId);
},
child: AnimatedContainer(
margin: EdgeInsets.only(top: i == startNumber ? 0 : 8),
padding: EdgeInsets.all(i == startNumber ? _item1Padding : _item2Padding),
padding:
EdgeInsets.all(i == startNumber ? _item1Padding : _item2Padding),
decoration: BoxDecoration(
color: i == startNumber ? _item1CurrentColor : _item2CurrentColor,
borderRadius: i == startNumber ? _item1Radius : _item2Radius,
@ -97,6 +100,7 @@ class _NavWidgetState extends State<NavWidget>
),
));
}
return columns;
}
}

View File

@ -0,0 +1,105 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:medito/main.dart';
import 'package:medito/viewmodel/listviewmodel.dart';
class _PlaceHolderState extends State<MainWidget> {
final _viewModel = new SubscriptionViewModelImpl();
final controller = TextEditingController();
int currentPage = 0;
// static List<FolderModel> filesList = [];
final emailAddressController = TextEditingController();
final _formKey = GlobalKey<FormState>();
final String emailRegex =
r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?)*$";
@override
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Image.network("https://source.unsplash.com/AvLHH8qYbAI",
height: 300, width: double.infinity, fit: BoxFit.fitWidth),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
"To make sure we provide the best service possible, we give access to new comers on a daily basis. \n\nEnter your email below and we will let you know when you can access the app.",
style: const TextStyle(
color: const Color(0xff656565),
fontStyle: FontStyle.normal,
fontSize: 16.0)),
),
Padding(
padding: const EdgeInsets.only(left: 16, right: 16),
child: TextFormField(
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black, width: 1.0),
),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 1.0),
),
hintText: 'email address'),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (!RegExp(emailRegex).hasMatch(value)) {
return "Please enter a valid email address";
}
if (value.isEmpty) {
return 'Please enter your emaill address';
}
return null;
},
),
),
Padding(
padding: const EdgeInsets.only(left: 16, right: 16, top: 4),
child: Text("* Well never share your email address",
style: const TextStyle(
fontStyle: FontStyle.normal, fontSize: 10.0)),
),
Padding(
padding: const EdgeInsets.all(16),
child: FlatButton(
textColor: Colors.white,
color: Colors.black,
onPressed: () {
// Validate returns true if the form is valid, or false
// otherwise.
if (_formKey.currentState.validate()) {
// If the form is valid, display a Snackbar.
_fire();
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Subscribing...')));
}
},
child: Text(
'JOIN WAITING LIST',
style: TextStyle(fontWeight: FontWeight.w600),
),
),
),
],
),
),
);
}
void _fire() {
// Api.updateSubscribers(emailAddressController.text)
// .whenComplete(_doneSnackBar);
}
FutureOr _doneSnackBar() {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('Complete. Thanks!'),
backgroundColor: Colors.green,
));
}
}

View File

@ -1,11 +0,0 @@
class FileModel {
String fileName;
String fileUrl;
int folderId;
String transcription;
FileType type;
FileModel(this.fileName, this.folderId, {this.fileUrl ,this.type, this. transcription});
}
enum FileType { text, audio }

276
lib/viewmodel/files.dart Normal file
View File

@ -0,0 +1,276 @@
class Files {
int code;
List<Data> data;
Pagination pagination;
String status;
String type;
Files({this.code, this.data, this.pagination, this.status, this.type});
Files.fromJson(Map<String, dynamic> json) {
code = json['code'];
if (json['data'] != null) {
data = new List<Data>();
json['data'].forEach((v) {
data.add(new Data.fromJson(v));
});
}
pagination = json['pagination'] != null
? new Pagination.fromJson(json['pagination'])
: null;
status = json['status'];
type = json['type'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['code'] = this.code;
if (this.data != null) {
data['data'] = this.data.map((v) => v.toJson()).toList();
}
if (this.pagination != null) {
data['pagination'] = this.pagination.toJson();
}
data['status'] = this.status;
data['type'] = this.type;
return data;
}
}
class Data {
Content content;
Dimensions dimensions;
bool exists;
String extension;
String filename;
String id;
String link;
String mime;
String modified;
Object name;
Object next;
String niceSize;
Options options;
Parent parent;
Object prev;
int size;
Object template;
String type;
String url;
Data(
{this.content,
this.dimensions,
this.exists,
this.extension,
this.filename,
this.id,
this.link,
this.mime,
this.modified,
this.name,
this.next,
this.niceSize,
this.options,
this.parent,
this.prev,
this.size,
this.template,
this.type,
this.url});
Data.fromJson(Map<String, dynamic> json) {
content =
json['content'] != null ? new Content.fromJson(json['content']) : null;
dimensions = json['dimensions'] != null
? new Dimensions.fromJson(json['dimensions'])
: null;
exists = json['exists'];
extension = json['extension'];
filename = json['filename'];
id = json['id'];
link = json['link'];
mime = json['mime'];
modified = json['modified'];
name = json['name'];
next = json['next'];
niceSize = json['niceSize'];
options =
json['options'] != null ? new Options.fromJson(json['options']) : null;
parent =
json['parent'] != null ? new Parent.fromJson(json['parent']) : null;
prev = json['prev'];
size = json['size'];
template = json['template'];
type = json['type'];
url = json['url'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.content != null) {
data['content'] = this.content.toJson();
}
if (this.dimensions != null) {
data['dimensions'] = this.dimensions.toJson();
}
data['exists'] = this.exists;
data['extension'] = this.extension;
data['filename'] = this.filename;
data['id'] = this.id;
data['link'] = this.link;
data['mime'] = this.mime;
data['modified'] = this.modified;
data['name'] = this.name;
data['next'] = this.next;
data['niceSize'] = this.niceSize;
if (this.options != null) {
data['options'] = this.options.toJson();
}
if (this.parent != null) {
data['parent'] = this.parent.toJson();
}
data['prev'] = this.prev;
data['size'] = this.size;
data['template'] = this.template;
data['type'] = this.type;
data['url'] = this.url;
return data;
}
}
class Content {
String alt;
Content({this.alt});
Content.fromJson(Map<String, dynamic> json) {
alt = json['alt'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['alt'] = this.alt;
return data;
}
}
class Dimensions {
int width;
int height;
int ratio;
bool orientation;
Dimensions({this.width, this.height, this.ratio, this.orientation});
Dimensions.fromJson(Map<String, dynamic> json) {
width = json['width'];
height = json['height'];
ratio = json['ratio'];
orientation = json['orientation'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['width'] = this.width;
data['height'] = this.height;
data['ratio'] = this.ratio;
data['orientation'] = this.orientation;
return data;
}
}
class Options {
bool changeName;
bool create;
bool delete;
bool replace;
bool update;
Options(
{this.changeName, this.create, this.delete, this.replace, this.update});
Options.fromJson(Map<String, dynamic> json) {
changeName = json['changeName'];
create = json['create'];
delete = json['delete'];
replace = json['replace'];
update = json['update'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['changeName'] = this.changeName;
data['create'] = this.create;
data['delete'] = this.delete;
data['replace'] = this.replace;
data['update'] = this.update;
return data;
}
}
class Parent {
String description;
String id;
int num;
String template;
String timeCreated;
String title;
String url;
Parent(
{this.description,
this.id,
this.num,
this.template,
this.timeCreated,
this.title,
this.url});
Parent.fromJson(Map<String, dynamic> json) {
description = json['description'];
id = json['id'];
num = json['num'];
template = json['template'];
timeCreated = json['timeCreated'];
title = json['title'];
url = json['url'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['description'] = this.description;
data['id'] = this.id;
data['num'] = this.num;
data['template'] = this.template;
data['timeCreated'] = this.timeCreated;
data['title'] = this.title;
data['url'] = this.url;
return data;
}
}
class Pagination {
int page;
int total;
int offset;
int limit;
Pagination({this.page, this.total, this.offset, this.limit});
Pagination.fromJson(Map<String, dynamic> json) {
page = json['page'];
total = json['total'];
offset = json['offset'];
limit = json['limit'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['page'] = this.page;
data['total'] = this.total;
data['offset'] = this.offset;
data['limit'] = this.limit;
return data;
}
}

View File

@ -1,2 +0,0 @@
class ListItemModel {
}

View File

@ -0,0 +1,16 @@
class ListItem {
String thumbnail;
String title;
String id;
String description = '';
String contentText;
ListItemType type;
FileType fileType;
String url;
String parentId;
ListItem(this.title, this.id, this.description, {this.type, this.fileType, this.url, this.parentId, this.thumbnail, this.contentText});
}
enum ListItemType {folder, file}
enum FileType {audio, text, both}

View File

@ -1,12 +0,0 @@
class FolderModel {
String thumbnail;
String title;
int id;
int parentId;
String description;
int filesId;
FolderModel(
this.thumbnail, this.title, this.id, this.parentId, this.description,
{this.filesId = -1});
}

View File

@ -1,91 +1,95 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:medito/viewmodel/filemodel.dart';
import 'package:http/http.dart' as http;
import 'package:medito/viewmodel/files.dart';
import 'package:medito/viewmodel/list_item.dart';
import 'package:medito/viewmodel/pages.dart';
import 'ListItemModel.dart';
abstract class MainListViewModel {
Sink get inputTextSink;
Stream<List<FolderModel>> get sessionListStream;
void dispose();
}
abstract class MainListViewModel {}
class SubscriptionViewModelImpl implements MainListViewModel {
var _mailTextController = StreamController<String>.broadcast();
List<String> navList = ["Home"];
FileModel currentlySelectedFile;
final String baseUrl = 'https://medito.app/api/pages';
final String basicAuth =
'Basic bWljaGFlbGNzcGVlZEBnbWFpbC5jb206QURNSU5ybzE1OTk1MQ==';
List<ListItem> navList = [ListItem("Home", "", "", parentId: "app")];
int currentPage;
bool playerOpen = false;
ListItem currentlySelectedFile;
List<FolderModel> folders = [
FolderModel("", "0 Meditate", 0, -1, ""),
FolderModel("", "1 Loving-Kindness", 1, 0,
"Be kind to yourself, be kind to others. Great in any situation",
filesId: 1),
FolderModel("", "Subfolder 1.1", 2, 1, ""),
FolderModel("", "Subfolder 1.1.1", 3, 2, ""),
FolderModel("", "Subfolder 1.1.2", 4, 2, ""),
FolderModel("", "Subfolder 1.1.3", 5, 2, ""),
FolderModel("", "Mindfulness of breathing", 6, 1,
"A simple way to relax and feel less stressed. The only thing to do is being aware of your breathing",
filesId: 2),
FolderModel("", "Subfolder 1.1.1", 7, 6, ""),
FolderModel("", "Subfolder 1.1.2", 8, 6, ""),
FolderModel("", "Subfolder 1.1.3", 9, 6, ""),
FolderModel("", "Mantra", 10, 0,
"Use sound as an effective way to improve focus, to find more calm and calm your mind"),
FolderModel("", "Subfolder 2.1", 11, 10, ""),
FolderModel("", "Subfolder 2.2", 12, 10, ""),
FolderModel("", "Folder 3", 13, 10, ""),
];
Future<List<ListItem>> getPage({String id = 'app'}) async {
if (id == null) id = 'app';
List<ListItem> listItemList = [];
var url = baseUrl + '/' + id.replaceAll('/', '+') + '/children';
List<FileModel> fileList = [
FileModel("Really long title this is: The revenge of the titles 1", 1, type: FileType.audio, fileUrl: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-8.mp3", transcription: "Never one to leave well enough alone, Ive made some changes to my personal infrastructure since last time around. As always, its not the technology itself, but what it affords which is important. These affordances are not constants, and as the tech has changed over time so too has my position. Ill quickly explain the what, and then elaborate on the why. This site is built with Vue and deployed with Netlify (frontend). The content is hosted with Github. Different than the last stack, but shares a focus on archivability and portability. "),
FileModel("File 2", 1, type: FileType.text, fileUrl: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-8.mp3"),
FileModel("File 3", 1, type: FileType.audio, fileUrl: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-8.mp3"),
FileModel("File 4", 1, fileUrl: "https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_700KB.mp3"),
FileModel("File 4", 1),
FileModel("File 5", 2, type: FileType.audio),
FileModel("File 6", 2, type: FileType.text),
];
final response = await http.get(
url,
headers: {HttpHeaders.authorizationHeader: basicAuth},
);
final responseJson = json.decode(response.body);
var pageList = Pages.fromJson(responseJson).data;
@override
Sink get inputTextSink => _mailTextController;
for (var value in pageList) {
var parentId = value.id.substring(0, value.id.lastIndexOf('/'));
var contentText = value.contentText == null ? "" : value.contentText;
@override
Stream<List<FolderModel>> get sessionListStream =>
Stream<List<FolderModel>>.value(List<FolderModel>.generate(15, (i) {
return null;
}));
if (value.template == 'default') {
//just a folder
listItemList.add(ListItem(value.title, value.id, value.description,
type: ListItemType.folder,
parentId: parentId,
contentText: contentText));
} else if (value.template == 'media') {
var fileType = getFileType(value);
var url;
@override
void dispose() => _mailTextController.close();
if (fileType == FileType.both || fileType == FileType.audio) {
try {
url = await getFileUrl(id: value.id);
} catch (e, s) {
print(s);
print('Error getting ' + value.title);
}
}
listItemList.add(ListItem(value.title, value.id, value.description,
url: url,
type: ListItemType.file,
fileType: fileType,
parentId: parentId,
contentText: contentText));
}
}
List<FolderModel> getFolderContents(int currentPage) {
this.currentPage = currentPage;
return folders.where((f) => f.parentId == currentPage).toList();
return listItemList;
}
List<FolderModel> backUp() {
var parentItem = folders.where((f) => f.id == currentPage).toList();
this.currentPage = parentItem.first.id;
var result = getFolderContents(parentItem.first.parentId);
navList.removeLast();
return result;
FileType getFileType(var value) {
if (value.hasFiles &&
value.contentText != null &&
value.contentText.isNotEmpty) {
return FileType.both;
} else if (value.hasFiles &&
(value.contentText == null || value.contentText.isEmpty)) {
return FileType.audio;
} else {
return FileType.text;
}
}
List<FolderModel> getFirstFolderContents() {
return folders.where((f) => f.id == 0).toList();
Future getFileUrl({String id = ''}) async {
var url = baseUrl + '/' + id.replaceAll('/', '+') + '/files';
final response = await http.get(
url,
headers: {HttpHeaders.authorizationHeader: basicAuth},
);
final responseJson = json.decode(response.body);
var filesList = Files.fromJson(responseJson).data;
return filesList?.first?.url;
}
List<FileModel> getFilesForId(int id) {
print("!");
return fileList.where((f) => f.folderId == id).toList();
}
void addToNavList(String title) {
navList.add(title);
void addToNavList(ListItem item) {
navList.add(item);
}
}

111
lib/viewmodel/pages.dart Normal file
View File

@ -0,0 +1,111 @@
class Pages {
int code;
List<Data> data;
Pagination pagination;
String status;
String type;
Pages({this.code, this.data, this.pagination, this.status, this.type});
Pages.fromJson(Map<String, dynamic> json) {
code = json['code'];
if (json['data'] != null) {
data = new List<Data>();
json['data'].forEach((v) {
data.add(new Data.fromJson(v));
});
}
pagination = json['pagination'] != null
? new Pagination.fromJson(json['pagination'])
: null;
status = json['status'];
type = json['type'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['code'] = this.code;
if (this.data != null) {
data['data'] = this.data.map((v) => v.toJson()).toList();
}
if (this.pagination != null) {
data['pagination'] = this.pagination.toJson();
}
data['status'] = this.status;
data['type'] = this.type;
return data;
}
}
class Data {
String description;
String contentText;
String id;
int num;
String template;
int timeCreated;
String title;
String url;
bool hasFiles;
Data(
{this.description,
this.contentText,
this.id,
this.num,
this.template,
this.timeCreated,
this.title,
this.url, this.hasFiles});
Data.fromJson(Map<String, dynamic> json) {
description = json['description'];
contentText = json['contentText'];
id = json['id'];
num = json['num'];
template = json['template'];
timeCreated = json['timeCreated'];
title = json['title'];
url = json['url'];
hasFiles = json['hasFiles'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['description'] = this.description;
data['contentText'] = this.contentText;
data['id'] = this.id;
data['num'] = this.num;
data['template'] = this.template;
data['timeCreated'] = this.timeCreated;
data['title'] = this.title;
data['url'] = this.url;
data['hasFiles'] = this.hasFiles;
return data;
}
}
class Pagination {
int page;
int total;
int offset;
int limit;
Pagination({this.page, this.total, this.offset, this.limit});
Pagination.fromJson(Map<String, dynamic> json) {
page = json['page'];
total = json['total'];
offset = json['offset'];
limit = json['limit'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['page'] = this.page;
data['total'] = this.total;
data['offset'] = this.offset;
data['limit'] = this.limit;
return data;
}
}

View File

@ -43,13 +43,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
cloud_firestore:
dependency: "direct main"
description:
name: cloud_firestore
url: "https://pub.dartlang.org"
source: hosted
version: "0.13.0+1"
collection:
dependency: transitive
description:
@ -78,62 +71,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
firebase:
dependency: transitive
description:
name: firebase
url: "https://pub.dartlang.org"
source: hosted
version: "7.1.0"
firebase_analytics:
dependency: "direct main"
description:
name: firebase_analytics
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.9"
firebase_auth:
dependency: "direct main"
description:
name: firebase_auth
url: "https://pub.dartlang.org"
source: hosted
version: "0.15.3+1"
firebase_auth_platform_interface:
dependency: transitive
description:
name: firebase_auth_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
firebase_auth_web:
dependency: transitive
description:
name: firebase_auth_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1+1"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.3+2"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1+1"
flutter:
dependency: "direct main"
description: flutter
@ -153,6 +90,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
flutter_svg:
dependency: "direct main"
description:
name: flutter_svg
url: "https://pub.dartlang.org"
source: hosted
version: "0.17.1"
flutter_swiper:
dependency: "direct main"
description:
@ -176,14 +120,14 @@ packages:
name: google_fonts
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.2"
version: "0.3.7"
http:
dependency: transitive
description:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.0+2"
version: "0.12.0+4"
http_parser:
dependency: transitive
description:
@ -198,13 +142,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.1+1"
marquee:
dependency: "direct main"
description:
@ -233,6 +170,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.4"
path_drawing:
dependency: transitive
description:
name: path_drawing
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.1"
path_parsing:
dependency: transitive
description:
name: path_parsing
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
path_provider:
dependency: transitive
description:
@ -352,4 +303,4 @@ packages:
version: "3.5.0"
sdks:
dart: ">=2.4.0 <3.0.0"
flutter: ">=1.12.13+hotfix.4 <2.0.0"
flutter: ">=1.10.0 <2.0.0"

View File

@ -19,14 +19,11 @@ environment:
dependencies:
flutter:
sdk: flutter
firebase_core: ^0.4.3+2
firebase_analytics: ^5.0.9
firebase_auth: ^0.15.3+1
cloud_firestore: ^0.13.0+1
google_fonts: ^0.3.2
google_fonts: ^0.3.7
flutter_sequence_animation: ^3.0.1
marquee: ^1.3.1
audioplayers: ^0.14.0
flutter_svg: ^0.17.1
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
@ -43,6 +40,10 @@ dev_dependencies:
# The following section is specific to Flutter.
flutter:
assets:
- assets/images/ic_audio.svg
- assets/images/ic_document.svg
- assets/images/ic_folder.svg
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in