mirror of
https://github.com/meditohq/medito-app.git
synced 2024-09-11 12:15:46 +03:00
new kirby backend!
global colors and themes!
This commit is contained in:
parent
c16256ac16
commit
71e1561368
@ -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":[]}]}
|
6
assets/images/ic_audio.svg
Normal file
6
assets/images/ic_audio.svg
Normal 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 |
6
assets/images/ic_document.svg
Normal file
6
assets/images/ic_document.svg
Normal 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 |
6
assets/images/ic_folder.svg
Normal file
6
assets/images/ic_folder.svg
Normal 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 |
18
ios/Flutter/Flutter.podspec
Normal file
18
ios/Flutter/Flutter.podspec
Normal 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
|
@ -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"
|
||||
|
@ -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
129
ios/Podfile.lock
Normal 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
|
@ -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 */
|
||||
|
@ -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>
|
3
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
3
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
@ -4,4 +4,7 @@
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -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>
|
@ -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
|
||||
|
||||
|
38
ios/Runner/GoogleService-Info.plist
Normal file
38
ios/Runner/GoogleService-Info.plist
Normal 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>
|
@ -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});
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
|
||||
//This
|
||||
class MeditoAudioPlayer {
|
||||
static final MeditoAudioPlayer _singleton = MeditoAudioPlayer._internal();
|
||||
AudioPlayer audioPlayer = AudioPlayer();
|
||||
|
@ -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
7
lib/colors.dart
Normal file
@ -0,0 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MeditioColors {
|
||||
var ripple = Colors.orangeAccent;
|
||||
var main = Colors.green;
|
||||
var secondary = Colors.lightGreen;
|
||||
}
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
346
lib/main.dart
346
lib/main.dart
@ -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("* We’ll 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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
105
lib/place_holder_widget.dart
Normal file
105
lib/place_holder_widget.dart
Normal 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("* We’ll 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,
|
||||
));
|
||||
}
|
||||
}
|
@ -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
276
lib/viewmodel/files.dart
Normal 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;
|
||||
}
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
class ListItemModel {
|
||||
}
|
16
lib/viewmodel/list_item.dart
Normal file
16
lib/viewmodel/list_item.dart
Normal 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}
|
@ -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});
|
||||
}
|
@ -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, I’ve made some changes to my personal infrastructure since last time around. As always, it’s 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. I’ll 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
111
lib/viewmodel/pages.dart
Normal 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;
|
||||
}
|
||||
}
|
97
pubspec.lock
97
pubspec.lock
@ -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"
|
||||
|
11
pubspec.yaml
11
pubspec.yaml
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user