├── .idea
├── libraries
│ ├── Dart_Packages.xml
│ └── Dart_SDK.xml
├── misc.xml
├── modules.xml
├── runConfigurations
│ ├── scaled_server_dart.xml
│ └── server_dart.xml
├── vcs.xml
└── workspace.xml
├── README.md
├── client
├── .gitignore
├── .idea
│ ├── modules.xml
│ └── runConfigurations
│ │ └── main_dart.xml
├── README.md
├── android.iml
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── yourcompany
│ │ │ │ └── client
│ │ │ │ └── MainActivity.java
│ │ │ └── res
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ ├── build.gradle
│ ├── gradle.properties
│ └── settings.gradle
├── client.iml
├── client_android.iml
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Podfile
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── Runner
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── main.m
├── lib
│ ├── main.dart
│ └── src
│ │ └── widgets
│ │ ├── chat_home.dart
│ │ ├── chat_login.dart
│ │ └── chat_message_list.dart
├── pubspec.lock
└── pubspec.yaml
├── common
├── .gitignore
├── common.iml
├── lib
│ ├── common.dart
│ └── src
│ │ └── models
│ │ ├── models.dart
│ │ └── models.g.dart
├── pubspec.lock
├── pubspec.yaml
└── tool
│ ├── build.dart
│ ├── phases.dart
│ └── watch.dart
├── screenshots
├── conversation.PNG
├── conversation_small.PNG
├── login.PNG
└── typing.PNG
└── server
├── .analysis-options
├── .dockerignore
├── .gitignore
├── .idea
├── angel.iml
├── misc.xml
├── modules.xml
└── runConfigurations
│ ├── Load_Balanced_Server__PRODUCTION_.xml
│ ├── Message_Tests.xml
│ ├── Multi_Threaded_Server__PRODUCTION_.xml
│ ├── Start_Server.xml
│ ├── Start_Server__PRODUCTION_.xml
│ ├── Todo_Tests.xml
│ └── Users_Tests.xml
├── .vscode
├── launch.json
└── tasks.json
├── Dockerfile
├── LICENSE
├── README.md
├── bin
├── cluster.dart
├── common.dart
├── multi_server.dart
├── scaled_server.dart
└── server.dart
├── config
├── default.yaml
├── development.yaml
└── production.yaml
├── lib
├── server.dart
└── src
│ ├── config
│ ├── config.dart
│ └── plugins
│ │ └── plugins.dart
│ ├── routes
│ ├── controllers
│ │ ├── auth.dart
│ │ └── controllers.dart
│ └── routes.dart
│ ├── services
│ ├── message.dart
│ ├── services.dart
│ └── user.dart
│ └── validators
│ ├── message.dart
│ ├── todo.dart
│ └── user.dart
├── pubspec.lock
├── pubspec.yaml
├── server.iml
├── test
└── services
│ ├── message_test.dart
│ ├── todo_test.dart
│ └── users_test.dart
├── tool
└── grind.dart
├── views
├── error.mustache
└── hello.mustache
└── web
├── images
├── dart.png
├── favicon.png
├── flutter.jpg
└── google.png
└── robots.txt
/.idea/libraries/Dart_Packages.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
883 |
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
900 |
901 |
902 |
903 |
904 |
905 |
906 |
907 |
908 |
909 |
910 |
911 |
912 |
913 |
914 |
915 |
916 |
917 |
918 |
919 |
920 |
921 |
922 |
923 |
924 |
925 |
926 |
927 |
928 |
929 |
930 |
931 |
932 |
933 |
934 |
935 |
936 |
937 |
938 |
939 |
940 |
941 |
942 |
943 |
944 |
945 |
946 |
947 |
948 |
949 |
950 |
951 |
952 |
953 |
954 |
955 |
956 |
957 |
958 |
959 |
960 |
961 |
962 |
963 |
964 |
965 |
966 |
967 |
968 |
969 |
970 |
971 |
972 |
973 |
974 |
975 |
976 |
977 |
978 |
979 |
980 |
981 |
982 |
983 |
984 |
985 |
986 |
987 |
988 |
989 |
990 |
991 |
992 |
993 |
994 |
995 |
996 |
997 |
998 |
999 |
1000 |
1001 |
1002 |
1003 |
1004 |
1005 |
1006 |
1007 |
1008 |
1009 |
1010 |
1011 |
1012 |
1013 |
1014 |
1015 |
1016 |
1017 |
1018 |
1019 |
1020 |
1021 |
1022 |
1023 |
1024 |
1025 |
1026 |
1027 |
1028 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/scaled_server_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/server_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flutter
2 | [Tutorial on Dart Academy](https://dart.academy/building-a-real-time-chat-app-with-angel-and-flutter/)
3 |
4 | A realtime chatroom built with
5 | [Angel](https://angel-dart.github.io) and
6 | [Flutter](https://flutter.io).
7 |
8 | This application uses WebSockets and local authentication,
9 | as well as service hooks. In terms of server-side code, it is relatively
10 | simple; this serves as a testament to Angel's promise of expedited
11 | development cycles.
12 |
13 | 
14 | 
15 |
16 | ## Organization
17 | This project is divided into three sub-projects:
18 |
19 | * `common` - Shared code, i.e. models.
20 | * `server` - A server powered by the Angel framework
21 | * `client` - A mobile app, written with [Flutter](https://flutter.io), that queries the `server`.
22 |
23 | ## Learn More
24 | [](https://angel-dart.github.io)
25 |
26 | To learn more about the Angel framework, check out the
27 | [main website](https://angel-dart.github.io) and
28 | [wiki](https://github.com/angel-dart/angel/wiki).
29 |
30 | Also consider starring the [main repo](https://github.com/angel-dart/angel)! Thank you!
31 |
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Dart template
3 | # See https://www.dartlang.org/tools/private-files.html
4 |
5 | # source_gen
6 | .dart_tool
7 |
8 | # Files and directories created by pub
9 | .buildlog
10 | .packages
11 | .project
12 | .pub/
13 | .scripts-bin/
14 | build/
15 | **/packages/
16 |
17 | # Files created by dart2js
18 | # (Most Dart developers will use pub build to compile Dart, use/modify these
19 | # rules if you intend to use dart2js directly
20 | # Convention is to use extension '.dart.js' for Dart compiled to Javascript to
21 | # differentiate from explicit Javascript files)
22 | *.dart.js
23 | *.part.js
24 | *.js.deps
25 | *.js.map
26 | *.info.json
27 |
28 | # Directory created by dartdoc
29 | doc/api/
30 |
31 | # Don't commit pubspec lock file
32 | # (Library packages only! Remove pattern if developing an application package)
33 | # pubspec.lock
34 | ### JetBrains template
35 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
36 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
37 |
38 | # User-specific stuff:
39 | .idea/workspace.xml
40 | .idea/tasks.xml
41 | .idea/dictionaries
42 | .idea/vcs.xml
43 | .idea/jsLibraryMappings.xml
44 |
45 | # Sensitive or high-churn files:
46 | .idea/dataSources.ids
47 | .idea/dataSources.xml
48 | .idea/dataSources.local.xml
49 | .idea/sqlDataSources.xml
50 | .idea/dynamic.xml
51 | .idea/uiDesigner.xml
52 |
53 | # Gradle:
54 | .idea/gradle.xml
55 | .idea/libraries
56 |
57 | # Mongo Explorer plugin:
58 | .idea/mongoSettings.xml
59 |
60 | ## File-based project format:
61 | *.iws
62 |
63 | ## Plugin-specific files:
64 |
65 | # IntelliJ
66 | /out/
67 |
68 | # mpeltonen/sbt-idea plugin
69 | .idea_modules/
70 |
71 | # JIRA plugin
72 | atlassian-ide-plugin.xml
73 |
74 | # Crashlytics plugin (for Android Studio and IntelliJ)
75 | com_crashlytics_export_strings.xml
76 | crashlytics.properties
77 | crashlytics-build.properties
78 | fabric.properties
79 |
80 | ### VSCode template
81 | .vscode/*
82 | !.vscode/settings.json
83 | !.vscode/tasks.json
84 | !.vscode/launch.json
85 | !.vscode/extensions.json
86 |
87 | logs/
88 | *.pem
89 | .DS_Store
90 |
--------------------------------------------------------------------------------
/client/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/client/.idea/runConfigurations/main_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/client/README.md:
--------------------------------------------------------------------------------
1 | # client
2 |
3 | A new Flutter project.
4 |
5 | ## Getting Started
6 |
7 | For help getting started with Flutter, view our online
8 | [documentation](http://flutter.io/).
9 |
--------------------------------------------------------------------------------
/client/android.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/client/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | GeneratedPluginRegistrant.java
10 |
11 | /gradle
12 | /gradlew
13 | /gradlew.bat
14 |
--------------------------------------------------------------------------------
/client/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withInputStream { stream ->
5 | localProperties.load(stream)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | apply plugin: 'com.android.application'
15 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
16 |
17 | android {
18 | compileSdkVersion 25
19 | buildToolsVersion '25.0.3'
20 |
21 | lintOptions {
22 | disable 'InvalidPackage'
23 | }
24 |
25 | defaultConfig {
26 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
27 |
28 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
29 | applicationId "com.yourcompany.client"
30 | }
31 |
32 | buildTypes {
33 | release {
34 | // TODO: Add your own signing config for the release build.
35 | // Signing with the debug keys for now, so `flutter run --release` works.
36 | signingConfig signingConfigs.debug
37 | }
38 | }
39 | }
40 |
41 | flutter {
42 | source '../..'
43 | }
44 |
45 | dependencies {
46 | androidTestCompile 'com.android.support:support-annotations:25.0.0'
47 | androidTestCompile 'com.android.support.test:runner:0.5'
48 | androidTestCompile 'com.android.support.test:rules:0.5'
49 | }
50 |
--------------------------------------------------------------------------------
/client/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
19 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/client/android/app/src/main/java/com/yourcompany/client/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.yourcompany.client;
2 |
3 | import android.os.Bundle;
4 |
5 | import io.flutter.app.FlutterActivity;
6 | import io.flutter.plugins.GeneratedPluginRegistrant;
7 |
8 | public class MainActivity extends FlutterActivity {
9 | @Override
10 | protected void onCreate(Bundle savedInstanceState) {
11 | super.onCreate(savedInstanceState);
12 | GeneratedPluginRegistrant.registerWith(this);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/client/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | jcenter()
4 | }
5 |
6 | dependencies {
7 | classpath 'com.android.tools.build:gradle:2.2.3'
8 | }
9 | }
10 |
11 | allprojects {
12 | repositories {
13 | jcenter()
14 | }
15 | }
16 |
17 | rootProject.buildDir = '../build'
18 | subprojects {
19 | project.buildDir = "${rootProject.buildDir}/${project.name}"
20 | project.evaluationDependsOn(':app')
21 | }
22 |
23 | task clean(type: Delete) {
24 | delete rootProject.buildDir
25 | }
26 |
27 | task wrapper(type: Wrapper) {
28 | gradleVersion = '2.14.1'
29 | }
30 |
--------------------------------------------------------------------------------
/client/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/client/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withInputStream { stream -> plugins.load(stream) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/client/client.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/client/client_android.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/client/ios/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vagrant/
3 | .sconsign.dblite
4 | .svn/
5 |
6 | .DS_Store
7 | *.swp
8 | profile
9 |
10 | DerivedData/
11 | build/
12 | GeneratedPluginRegistrant.h
13 | GeneratedPluginRegistrant.m
14 |
15 | *.pbxuser
16 | *.mode1v3
17 | *.mode2v3
18 | *.perspectivev3
19 |
20 | !default.pbxuser
21 | !default.mode1v3
22 | !default.mode2v3
23 | !default.perspectivev3
24 |
25 | xcuserdata
26 |
27 | *.moved-aside
28 |
29 | *.pyc
30 | *sync/
31 | Icon?
32 | .tags*
33 |
34 | /Flutter/app.flx
35 | /Flutter/app.zip
36 | /Flutter/App.framework
37 | /Flutter/Flutter.framework
38 | /Flutter/Generated.xcconfig
39 | /ServiceDefinitions.json
40 |
41 | Pods/
42 |
--------------------------------------------------------------------------------
/client/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | UIRequiredDeviceCapabilities
24 |
25 | arm64
26 |
27 | MinimumOSVersion
28 | 8.0
29 |
30 |
31 |
--------------------------------------------------------------------------------
/client/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/client/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/client/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | if ENV['FLUTTER_FRAMEWORK_DIR'] == nil
5 | abort('Please set FLUTTER_FRAMEWORK_DIR to the directory containing Flutter.framework')
6 | end
7 |
8 | target 'Runner' do
9 | # Pods for Runner
10 |
11 | # Flutter Pods
12 | pod 'Flutter', :path => ENV['FLUTTER_FRAMEWORK_DIR']
13 |
14 | if File.exists? '../.flutter-plugins'
15 | flutter_root = File.expand_path('..')
16 | File.foreach('../.flutter-plugins') { |line|
17 | plugin = line.split(pattern='=')
18 | if plugin.length == 2
19 | name = plugin[0].strip()
20 | path = plugin[1].strip()
21 | resolved_path = File.expand_path("#{path}/ios", flutter_root)
22 | pod name, :path => resolved_path
23 | else
24 | puts "Invalid plugin specification: #{line}"
25 | end
26 | }
27 | end
28 | end
29 |
30 | post_install do |installer|
31 | installer.pods_project.targets.each do |target|
32 | target.build_configurations.each do |config|
33 | config.build_settings['ENABLE_BITCODE'] = 'NO'
34 | end
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/client/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
12 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
14 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
15 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
16 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
17 | 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; };
18 | 9740EEBB1CF902C7004384FC /* app.flx in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB71CF902C7004384FC /* app.flx */; };
19 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
20 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
21 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
22 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
23 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
24 | /* End PBXBuildFile section */
25 |
26 | /* Begin PBXCopyFilesBuildPhase section */
27 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
28 | isa = PBXCopyFilesBuildPhase;
29 | buildActionMask = 2147483647;
30 | dstPath = "";
31 | dstSubfolderSpec = 10;
32 | files = (
33 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
34 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
35 | );
36 | name = "Embed Frameworks";
37 | runOnlyForDeploymentPostprocessing = 0;
38 | };
39 | /* End PBXCopyFilesBuildPhase section */
40 |
41 | /* Begin PBXFileReference section */
42 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
43 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
44 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
45 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
46 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
47 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
48 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
49 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
50 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
51 | 9740EEB71CF902C7004384FC /* app.flx */ = {isa = PBXFileReference; lastKnownFileType = file; name = app.flx; path = Flutter/app.flx; sourceTree = ""; };
52 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
53 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
54 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
55 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
56 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
57 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
58 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
59 | /* End PBXFileReference section */
60 |
61 | /* Begin PBXFrameworksBuildPhase section */
62 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
63 | isa = PBXFrameworksBuildPhase;
64 | buildActionMask = 2147483647;
65 | files = (
66 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
67 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
68 | );
69 | runOnlyForDeploymentPostprocessing = 0;
70 | };
71 | /* End PBXFrameworksBuildPhase section */
72 |
73 | /* Begin PBXGroup section */
74 | 9740EEB11CF90186004384FC /* Flutter */ = {
75 | isa = PBXGroup;
76 | children = (
77 | 9740EEB71CF902C7004384FC /* app.flx */,
78 | 3B80C3931E831B6300D905FE /* App.framework */,
79 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
80 | 9740EEBA1CF902C7004384FC /* Flutter.framework */,
81 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
82 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
83 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
84 | );
85 | name = Flutter;
86 | sourceTree = "";
87 | };
88 | 97C146E51CF9000F007C117D = {
89 | isa = PBXGroup;
90 | children = (
91 | 9740EEB11CF90186004384FC /* Flutter */,
92 | 97C146F01CF9000F007C117D /* Runner */,
93 | 97C146EF1CF9000F007C117D /* Products */,
94 | CF3B75C9A7D2FA2A4C99F110 /* Frameworks */,
95 | );
96 | sourceTree = "";
97 | };
98 | 97C146EF1CF9000F007C117D /* Products */ = {
99 | isa = PBXGroup;
100 | children = (
101 | 97C146EE1CF9000F007C117D /* Runner.app */,
102 | );
103 | name = Products;
104 | sourceTree = "";
105 | };
106 | 97C146F01CF9000F007C117D /* Runner */ = {
107 | isa = PBXGroup;
108 | children = (
109 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
110 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
111 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
112 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
113 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
114 | 97C147021CF9000F007C117D /* Info.plist */,
115 | 97C146F11CF9000F007C117D /* Supporting Files */,
116 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
117 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
118 | );
119 | path = Runner;
120 | sourceTree = "";
121 | };
122 | 97C146F11CF9000F007C117D /* Supporting Files */ = {
123 | isa = PBXGroup;
124 | children = (
125 | 97C146F21CF9000F007C117D /* main.m */,
126 | );
127 | name = "Supporting Files";
128 | sourceTree = "";
129 | };
130 | /* End PBXGroup section */
131 |
132 | /* Begin PBXNativeTarget section */
133 | 97C146ED1CF9000F007C117D /* Runner */ = {
134 | isa = PBXNativeTarget;
135 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
136 | buildPhases = (
137 | 9740EEB61CF901F6004384FC /* Run Script */,
138 | 97C146EA1CF9000F007C117D /* Sources */,
139 | 97C146EB1CF9000F007C117D /* Frameworks */,
140 | 97C146EC1CF9000F007C117D /* Resources */,
141 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
142 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
143 | );
144 | buildRules = (
145 | );
146 | dependencies = (
147 | );
148 | name = Runner;
149 | productName = Runner;
150 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
151 | productType = "com.apple.product-type.application";
152 | };
153 | /* End PBXNativeTarget section */
154 |
155 | /* Begin PBXProject section */
156 | 97C146E61CF9000F007C117D /* Project object */ = {
157 | isa = PBXProject;
158 | attributes = {
159 | LastUpgradeCheck = 0830;
160 | ORGANIZATIONNAME = "The Chromium Authors";
161 | TargetAttributes = {
162 | 97C146ED1CF9000F007C117D = {
163 | CreatedOnToolsVersion = 7.3.1;
164 | };
165 | };
166 | };
167 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
168 | compatibilityVersion = "Xcode 3.2";
169 | developmentRegion = English;
170 | hasScannedForEncodings = 0;
171 | knownRegions = (
172 | en,
173 | Base,
174 | );
175 | mainGroup = 97C146E51CF9000F007C117D;
176 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
177 | projectDirPath = "";
178 | projectRoot = "";
179 | targets = (
180 | 97C146ED1CF9000F007C117D /* Runner */,
181 | );
182 | };
183 | /* End PBXProject section */
184 |
185 | /* Begin PBXResourcesBuildPhase section */
186 | 97C146EC1CF9000F007C117D /* Resources */ = {
187 | isa = PBXResourcesBuildPhase;
188 | buildActionMask = 2147483647;
189 | files = (
190 | 9740EEBB1CF902C7004384FC /* app.flx in Resources */,
191 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
192 | 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */,
193 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
194 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
195 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
196 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
197 | );
198 | runOnlyForDeploymentPostprocessing = 0;
199 | };
200 | /* End PBXResourcesBuildPhase section */
201 |
202 | /* Begin PBXShellScriptBuildPhase section */
203 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
204 | isa = PBXShellScriptBuildPhase;
205 | buildActionMask = 2147483647;
206 | files = (
207 | );
208 | inputPaths = (
209 | );
210 | name = "Thin Binary";
211 | outputPaths = (
212 | );
213 | runOnlyForDeploymentPostprocessing = 0;
214 | shellPath = /bin/sh;
215 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
216 | };
217 | 9740EEB61CF901F6004384FC /* Run Script */ = {
218 | isa = PBXShellScriptBuildPhase;
219 | buildActionMask = 2147483647;
220 | files = (
221 | );
222 | inputPaths = (
223 | );
224 | name = "Run Script";
225 | outputPaths = (
226 | );
227 | runOnlyForDeploymentPostprocessing = 0;
228 | shellPath = /bin/sh;
229 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
230 | };
231 | /* End PBXShellScriptBuildPhase section */
232 |
233 | /* Begin PBXSourcesBuildPhase section */
234 | 97C146EA1CF9000F007C117D /* Sources */ = {
235 | isa = PBXSourcesBuildPhase;
236 | buildActionMask = 2147483647;
237 | files = (
238 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
239 | 97C146F31CF9000F007C117D /* main.m in Sources */,
240 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
241 | );
242 | runOnlyForDeploymentPostprocessing = 0;
243 | };
244 | /* End PBXSourcesBuildPhase section */
245 |
246 | /* Begin PBXVariantGroup section */
247 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
248 | isa = PBXVariantGroup;
249 | children = (
250 | 97C146FB1CF9000F007C117D /* Base */,
251 | );
252 | name = Main.storyboard;
253 | sourceTree = "";
254 | };
255 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
256 | isa = PBXVariantGroup;
257 | children = (
258 | 97C147001CF9000F007C117D /* Base */,
259 | );
260 | name = LaunchScreen.storyboard;
261 | sourceTree = "";
262 | };
263 | /* End PBXVariantGroup section */
264 |
265 | /* Begin XCBuildConfiguration section */
266 | 97C147031CF9000F007C117D /* Debug */ = {
267 | isa = XCBuildConfiguration;
268 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
269 | buildSettings = {
270 | ALWAYS_SEARCH_USER_PATHS = NO;
271 | CLANG_ANALYZER_NONNULL = YES;
272 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
273 | CLANG_CXX_LIBRARY = "libc++";
274 | CLANG_ENABLE_MODULES = YES;
275 | CLANG_ENABLE_OBJC_ARC = YES;
276 | CLANG_WARN_BOOL_CONVERSION = YES;
277 | CLANG_WARN_CONSTANT_CONVERSION = YES;
278 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
279 | CLANG_WARN_EMPTY_BODY = YES;
280 | CLANG_WARN_ENUM_CONVERSION = YES;
281 | CLANG_WARN_INFINITE_RECURSION = YES;
282 | CLANG_WARN_INT_CONVERSION = YES;
283 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
284 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
285 | CLANG_WARN_UNREACHABLE_CODE = YES;
286 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
287 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
288 | COPY_PHASE_STRIP = NO;
289 | DEBUG_INFORMATION_FORMAT = dwarf;
290 | ENABLE_STRICT_OBJC_MSGSEND = YES;
291 | ENABLE_TESTABILITY = YES;
292 | GCC_C_LANGUAGE_STANDARD = gnu99;
293 | GCC_DYNAMIC_NO_PIC = NO;
294 | GCC_NO_COMMON_BLOCKS = YES;
295 | GCC_OPTIMIZATION_LEVEL = 0;
296 | GCC_PREPROCESSOR_DEFINITIONS = (
297 | "DEBUG=1",
298 | "$(inherited)",
299 | );
300 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
301 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
302 | GCC_WARN_UNDECLARED_SELECTOR = YES;
303 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
304 | GCC_WARN_UNUSED_FUNCTION = YES;
305 | GCC_WARN_UNUSED_VARIABLE = YES;
306 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
307 | MTL_ENABLE_DEBUG_INFO = YES;
308 | ONLY_ACTIVE_ARCH = YES;
309 | SDKROOT = iphoneos;
310 | TARGETED_DEVICE_FAMILY = "1,2";
311 | };
312 | name = Debug;
313 | };
314 | 97C147041CF9000F007C117D /* Release */ = {
315 | isa = XCBuildConfiguration;
316 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
317 | buildSettings = {
318 | ALWAYS_SEARCH_USER_PATHS = NO;
319 | CLANG_ANALYZER_NONNULL = YES;
320 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
321 | CLANG_CXX_LIBRARY = "libc++";
322 | CLANG_ENABLE_MODULES = YES;
323 | CLANG_ENABLE_OBJC_ARC = YES;
324 | CLANG_WARN_BOOL_CONVERSION = YES;
325 | CLANG_WARN_CONSTANT_CONVERSION = YES;
326 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
327 | CLANG_WARN_EMPTY_BODY = YES;
328 | CLANG_WARN_ENUM_CONVERSION = YES;
329 | CLANG_WARN_INFINITE_RECURSION = YES;
330 | CLANG_WARN_INT_CONVERSION = YES;
331 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
332 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
333 | CLANG_WARN_UNREACHABLE_CODE = YES;
334 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
336 | COPY_PHASE_STRIP = NO;
337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
338 | ENABLE_NS_ASSERTIONS = NO;
339 | ENABLE_STRICT_OBJC_MSGSEND = YES;
340 | GCC_C_LANGUAGE_STANDARD = gnu99;
341 | GCC_NO_COMMON_BLOCKS = YES;
342 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
343 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
344 | GCC_WARN_UNDECLARED_SELECTOR = YES;
345 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
346 | GCC_WARN_UNUSED_FUNCTION = YES;
347 | GCC_WARN_UNUSED_VARIABLE = YES;
348 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
349 | MTL_ENABLE_DEBUG_INFO = NO;
350 | SDKROOT = iphoneos;
351 | TARGETED_DEVICE_FAMILY = "1,2";
352 | VALIDATE_PRODUCT = YES;
353 | };
354 | name = Release;
355 | };
356 | 97C147061CF9000F007C117D /* Debug */ = {
357 | isa = XCBuildConfiguration;
358 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
359 | buildSettings = {
360 | ARCHS = arm64;
361 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
362 | ENABLE_BITCODE = NO;
363 | FRAMEWORK_SEARCH_PATHS = (
364 | "$(inherited)",
365 | "$(PROJECT_DIR)/Flutter",
366 | );
367 | INFOPLIST_FILE = Runner/Info.plist;
368 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
369 | LIBRARY_SEARCH_PATHS = (
370 | "$(inherited)",
371 | "$(PROJECT_DIR)/Flutter",
372 | );
373 | PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.client;
374 | PRODUCT_NAME = "$(TARGET_NAME)";
375 | };
376 | name = Debug;
377 | };
378 | 97C147071CF9000F007C117D /* Release */ = {
379 | isa = XCBuildConfiguration;
380 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
381 | buildSettings = {
382 | ARCHS = arm64;
383 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
384 | ENABLE_BITCODE = NO;
385 | FRAMEWORK_SEARCH_PATHS = (
386 | "$(inherited)",
387 | "$(PROJECT_DIR)/Flutter",
388 | );
389 | INFOPLIST_FILE = Runner/Info.plist;
390 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
391 | LIBRARY_SEARCH_PATHS = (
392 | "$(inherited)",
393 | "$(PROJECT_DIR)/Flutter",
394 | );
395 | PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.client;
396 | PRODUCT_NAME = "$(TARGET_NAME)";
397 | };
398 | name = Release;
399 | };
400 | /* End XCBuildConfiguration section */
401 |
402 | /* Begin XCConfigurationList section */
403 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
404 | isa = XCConfigurationList;
405 | buildConfigurations = (
406 | 97C147031CF9000F007C117D /* Debug */,
407 | 97C147041CF9000F007C117D /* Release */,
408 | );
409 | defaultConfigurationIsVisible = 0;
410 | defaultConfigurationName = Release;
411 | };
412 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
413 | isa = XCConfigurationList;
414 | buildConfigurations = (
415 | 97C147061CF9000F007C117D /* Debug */,
416 | 97C147071CF9000F007C117D /* Release */,
417 | );
418 | defaultConfigurationIsVisible = 0;
419 | defaultConfigurationName = Release;
420 | };
421 | /* End XCConfigurationList section */
422 | };
423 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
424 | }
425 |
--------------------------------------------------------------------------------
/client/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/client/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/client/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/client/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/client/ios/Runner/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #include "AppDelegate.h"
2 | #include "GeneratedPluginRegistrant.h"
3 |
4 | @implementation AppDelegate
5 |
6 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
7 | [GeneratedPluginRegistrant registerWithRegistry:self];
8 | // Override point for customization after application launch.
9 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
10 | }
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | }
111 | ],
112 | "info" : {
113 | "version" : 1,
114 | "author" : "xcode"
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/client/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/client/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | client
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | arm64
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 | UIViewControllerBasedStatusBarAppearance
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/client/ios/Runner/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char * argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/client/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'src/widgets/chat_home.dart';
3 |
4 | void main() {
5 | runApp(new ChatApp());
6 | }
7 |
8 | class ChatApp extends StatelessWidget {
9 | @override
10 | Widget build(BuildContext context) {
11 | return new MaterialApp(
12 | theme: new ThemeData(primarySwatch: Colors.teal),
13 | home: new ChatHome(),
14 | );
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/client/lib/src/widgets/chat_home.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:angel_client/flutter.dart';
3 | import 'package:angel_websocket/flutter.dart';
4 | import 'package:common/common.dart';
5 | import 'package:flutter/material.dart';
6 | import 'chat_login.dart';
7 | import 'chat_message_list.dart';
8 |
9 | class ChatHome extends StatefulWidget {
10 | @override
11 | State createState() => new _ChatHomeState();
12 | }
13 |
14 | class _ChatHomeState extends State {
15 | final Angel restApp = new Rest('http://10.134.80.167:3000');
16 | String token;
17 | User user;
18 | WebSockets wsApp;
19 | Service service;
20 | bool connecting = true, error = false;
21 | List messages = [];
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | if (user == null) {
26 | return new Scaffold(
27 | appBar: new AppBar(
28 | title: new Text('Log In'),
29 | ),
30 | body: new ChatLogin(restApp, (AngelAuthResult auth) {
31 | setState(() {
32 | user = User.parse(auth.data);
33 | token = auth.token;
34 | wsApp = new WebSockets('ws://10.134.80.167:3000/ws');
35 | });
36 |
37 | wsApp
38 | .connect()
39 | .then((_) {
40 | var c = new Completer();
41 | StreamSubscription onAuth, onError;
42 |
43 | onAuth = wsApp.onAuthenticated.listen((_) {
44 | service = wsApp.service('api/messages');
45 |
46 | service
47 | ..onIndexed.listen((WebSocketEvent e) {
48 | setState(() {
49 | messages
50 | ..clear()
51 | ..addAll(e.data.map(Message.parse));
52 | });
53 | })
54 | ..onCreated.listen((WebSocketEvent e) {
55 | setState(() {
56 | messages.add(Message.parse(e.data));
57 | });
58 | });
59 |
60 | service.index();
61 | onAuth.cancel();
62 | c.complete();
63 | });
64 |
65 | onError = wsApp.onError.listen((e) {
66 | onError.cancel();
67 | c.completeError(e);
68 | });
69 |
70 | wsApp.authenticateViaJwt(auth.token);
71 | return c.future;
72 | })
73 | .timeout(new Duration(minutes: 1))
74 | .catchError((e) {
75 | showDialog(
76 | context: context,
77 | child: new SimpleDialog(
78 | title: new Text('Couldn\'t connect to chat server.'),
79 | )).then((_) {
80 | setState(() => error = true);
81 | });
82 | })
83 | .whenComplete(() {
84 | setState(() => connecting = false);
85 | });
86 | }),
87 | );
88 | }
89 |
90 | Widget body;
91 |
92 | // Render different content depending on the state of the application.
93 | if (connecting)
94 | body = new Text('Connecting to server...');
95 | else if (error)
96 | body = new Text('An error occurred while connecting to the server.');
97 | else {
98 | body = new ChatMessageList(restApp, service, messages, user);
99 | }
100 |
101 | return new Scaffold(
102 | appBar: new AppBar(
103 | title: new Text('Chat (${messages.length} messages)'),
104 | ),
105 | body: body,
106 | );
107 | }
108 | }
--------------------------------------------------------------------------------
/client/lib/src/widgets/chat_login.dart:
--------------------------------------------------------------------------------
1 | import 'package:angel_client/flutter.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | /// A callback that handles the result of successful authentication against a server.
5 | typedef void HandleAuth(AngelAuthResult auth);
6 |
7 | /// Renders a log-in screen that POSTs to /auth/lccal on our server.
8 | class ChatLogin extends StatefulWidget {
9 | /// An [Angel] client that interacts with the server over plain HTTP.
10 | ///
11 | /// We need this to POST to /auth/local and receive a JWT.
12 | ///
13 | /// Once we receive the JWT, we can use it to authenticate our WebSocket.
14 | final Angel restApp;
15 |
16 | /// Invoke this with the [AngelAuthResult] that contains an authenticated user, and a JWT.
17 | final HandleAuth handleAuth;
18 |
19 | ChatLogin(this.restApp, this.handleAuth);
20 |
21 | @override
22 | State createState() => new _ChatLoginState(restApp, handleAuth);
23 | }
24 |
25 | class _ChatLoginState extends State {
26 | final Angel restApp;
27 | final HandleAuth handleAuth;
28 | String username, password;
29 | bool sending = false;
30 |
31 | _ChatLoginState(this.restApp, this.handleAuth);
32 |
33 | @override
34 | Widget build(BuildContext context) {
35 | return new Padding(
36 | padding: const EdgeInsets.all(16.0),
37 | child: new Form(
38 | child: new Column(
39 | children: [
40 | new TextField(
41 | decoration: new InputDecoration(labelText: 'Username'),
42 | onChanged: (String str) => setState(() => username = str),
43 | ),
44 | new TextField(
45 | decoration: new InputDecoration(labelText: 'Password'),
46 | onChanged: (String str) => setState(() => password = str),
47 | ),
48 | sending
49 | ? new CircularProgressIndicator()
50 | : new RaisedButton(
51 | onPressed: () {
52 | setState(() => sending = true);
53 |
54 | // The `authenticate` method will not only POST to /auth/,
55 | // but also parse the server's response.
56 | //
57 | // Naturally, this API expects that your server is using
58 | // `package:angel_auth`, which issues signed JWT's.
59 | //
60 | // For more documentation:
61 | // * https://github.com/angel-dart/auth
62 | // * https://github.com/angel-dart/client
63 | // * https://jwt.io
64 | restApp.authenticate(type: 'local', credentials: {
65 | 'username': username,
66 | 'password': password
67 | }).then((auth) {
68 | // Alert the parent widget that we've logged in!
69 | handleAuth(auth);
70 | }).catchError((e) {
71 | // If we fail to log-in, tell the user that something went wrong.
72 | showDialog(
73 | context: context,
74 | child: new SimpleDialog(
75 | title: new Text('Login Error: $e'),
76 | ));
77 | }).whenComplete(() {
78 | setState(() => sending = false);
79 | });
80 | },
81 | color: Theme.of(context).primaryColor,
82 | highlightColor: Theme.of(context).highlightColor,
83 | child: new Text(
84 | 'SUBMIT',
85 | style: new TextStyle(color: Colors.white),
86 | ),
87 | )
88 | ],
89 | ),
90 | ),
91 | );
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/client/lib/src/widgets/chat_message_list.dart:
--------------------------------------------------------------------------------
1 | import 'package:angel_client/angel_client.dart';
2 | import 'package:common/common.dart';
3 | import 'package:flutter/material.dart';
4 |
5 | /// Simply renders a list of chat messages.
6 | class ChatMessageList extends StatelessWidget {
7 | /// An [Angel] client pointing toward an HTTP server.
8 | ///
9 | /// We need it for its [basePath] property.
10 | final Angel restApp;
11 |
12 | /// A client-side [Service], which mirrors the server-side implementation.
13 | ///
14 | /// We use this to create messages on the server, in this case via WebSocket.
15 | final Service service;
16 | final List messages;
17 | final User user;
18 |
19 | ChatMessageList(this.restApp, this.service, this.messages, this.user);
20 |
21 | @override
22 | Widget build(BuildContext context) {
23 | return new Column(
24 | children: [
25 | new Flexible(
26 | child: messages.isEmpty
27 | ? new Text('Nobody has said anything yet... Break the silence!')
28 | : new ListView.builder(
29 | itemCount: messages.length,
30 | itemBuilder: (_, int i) {
31 | return new ListTile(
32 | // Resolve the path of an image on the server, using the `basePath`
33 | // of our `restApp`.
34 | leading: new Image.network(
35 | '${restApp.basePath}/images/${messages[i].user.avatar}'),
36 | title: new Text(
37 | messages[i].user.username,
38 | style: new TextStyle(fontWeight: FontWeight.bold),
39 | ),
40 | subtitle: new Text(messages[i].text),
41 | );
42 | }),
43 | ),
44 | new Divider(height: 1.0),
45 | new Container(
46 | decoration: new BoxDecoration(color: Theme.of(context).cardColor),
47 | child: new Padding(
48 | padding: const EdgeInsets.only(left: 8.0, right: 8.0),
49 | child: new TextField(
50 | decoration: new InputDecoration(labelText: 'Send a message...'),
51 | onSubmitted: (String msg) {
52 | if (msg.isNotEmpty) {
53 | // When the user wants to send a message, all
54 | // we need to do is send an action through our
55 | // WebSocket.
56 | //
57 | // `package:angel_websocket` provides a clean API
58 | // that accomplishes this while also implementing the
59 | // `package:angel_client` API.
60 | //
61 | // This resembles the server-side, and makes developing full-stack
62 | // with Angel make a little bit more sense.
63 | //
64 | // We don't need to call any fancy state-setting functions, because
65 | // our chat app is already listening to our WebSocket to modify its state
66 | // when new messages come in.
67 | service.create({'text': msg});
68 | }
69 | },
70 | ),
71 | ),
72 | )
73 | ],
74 | );
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/client/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See http://pub.dartlang.org/doc/glossary.html#lockfile
3 | packages:
4 | analyzer:
5 | description:
6 | name: analyzer
7 | url: "https://pub.dartlang.org"
8 | source: hosted
9 | version: "0.30.0+2"
10 | angel_auth:
11 | description:
12 | name: angel_auth
13 | url: "https://pub.dartlang.org"
14 | source: hosted
15 | version: "1.0.5"
16 | angel_client:
17 | description:
18 | name: angel_client
19 | url: "https://pub.dartlang.org"
20 | source: hosted
21 | version: "1.0.7"
22 | angel_framework:
23 | description:
24 | name: angel_framework
25 | url: "https://pub.dartlang.org"
26 | source: hosted
27 | version: "1.0.6"
28 | angel_route:
29 | description:
30 | name: angel_route
31 | url: "https://pub.dartlang.org"
32 | source: hosted
33 | version: "1.0.4"
34 | angel_serialize:
35 | description:
36 | name: angel_serialize
37 | url: "https://pub.dartlang.org"
38 | source: hosted
39 | version: "1.0.0-alpha"
40 | angel_websocket:
41 | description:
42 | name: angel_websocket
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "1.0.8"
46 | args:
47 | description:
48 | name: args
49 | url: "https://pub.dartlang.org"
50 | source: hosted
51 | version: "0.13.7"
52 | async:
53 | description:
54 | name: async
55 | url: "https://pub.dartlang.org"
56 | source: hosted
57 | version: "1.13.3"
58 | body_parser:
59 | description:
60 | name: body_parser
61 | url: "https://pub.dartlang.org"
62 | source: hosted
63 | version: "1.0.1"
64 | build:
65 | description:
66 | name: build
67 | url: "https://pub.dartlang.org"
68 | source: hosted
69 | version: "0.9.3"
70 | charcode:
71 | description:
72 | name: charcode
73 | url: "https://pub.dartlang.org"
74 | source: hosted
75 | version: "1.1.1"
76 | cli_util:
77 | description:
78 | name: cli_util
79 | url: "https://pub.dartlang.org"
80 | source: hosted
81 | version: "0.1.1"
82 | code_builder:
83 | description:
84 | name: code_builder
85 | url: "https://pub.dartlang.org"
86 | source: hosted
87 | version: "1.0.4"
88 | collection:
89 | description:
90 | name: collection
91 | url: "https://pub.dartlang.org"
92 | source: hosted
93 | version: "1.14.1"
94 | common:
95 | description:
96 | path: "..\\common"
97 | relative: true
98 | source: path
99 | version: "0.0.0"
100 | container:
101 | description:
102 | name: container
103 | url: "https://pub.dartlang.org"
104 | source: hosted
105 | version: "0.1.2"
106 | convert:
107 | description:
108 | name: convert
109 | url: "https://pub.dartlang.org"
110 | source: hosted
111 | version: "2.0.1"
112 | crypto:
113 | description:
114 | name: crypto
115 | url: "https://pub.dartlang.org"
116 | source: hosted
117 | version: "2.0.1"
118 | csslib:
119 | description:
120 | name: csslib
121 | url: "https://pub.dartlang.org"
122 | source: hosted
123 | version: "0.14.0"
124 | dart_style:
125 | description:
126 | name: dart_style
127 | url: "https://pub.dartlang.org"
128 | source: hosted
129 | version: "1.0.6"
130 | flatten:
131 | description:
132 | name: flatten
133 | url: "https://pub.dartlang.org"
134 | source: hosted
135 | version: "1.0.0"
136 | flutter:
137 | description: flutter
138 | source: sdk
139 | version: "0.0.27"
140 | front_end:
141 | description:
142 | name: front_end
143 | url: "https://pub.dartlang.org"
144 | source: hosted
145 | version: "0.1.0-alpha.4"
146 | func:
147 | description:
148 | name: func
149 | url: "https://pub.dartlang.org"
150 | source: hosted
151 | version: "1.0.0"
152 | glob:
153 | description:
154 | name: glob
155 | url: "https://pub.dartlang.org"
156 | source: hosted
157 | version: "1.1.3"
158 | html:
159 | description:
160 | name: html
161 | url: "https://pub.dartlang.org"
162 | source: hosted
163 | version: "0.13.2"
164 | http:
165 | description:
166 | name: http
167 | url: "https://pub.dartlang.org"
168 | source: hosted
169 | version: "0.11.3+13"
170 | http_parser:
171 | description:
172 | name: http_parser
173 | url: "https://pub.dartlang.org"
174 | source: hosted
175 | version: "3.1.1"
176 | http_server:
177 | description:
178 | name: http_server
179 | url: "https://pub.dartlang.org"
180 | source: hosted
181 | version: "0.9.6"
182 | id:
183 | description:
184 | name: id
185 | url: "https://pub.dartlang.org"
186 | source: hosted
187 | version: "1.0.16"
188 | intl:
189 | description:
190 | name: intl
191 | url: "https://pub.dartlang.org"
192 | source: hosted
193 | version: "0.14.0"
194 | isolate:
195 | description:
196 | name: isolate
197 | url: "https://pub.dartlang.org"
198 | source: hosted
199 | version: "1.0.0"
200 | json_god:
201 | description:
202 | name: json_god
203 | url: "https://pub.dartlang.org"
204 | source: hosted
205 | version: "2.0.0-beta+1"
206 | kernel:
207 | description:
208 | name: kernel
209 | url: "https://pub.dartlang.org"
210 | source: hosted
211 | version: "0.3.0-alpha.1"
212 | logging:
213 | description:
214 | name: logging
215 | url: "https://pub.dartlang.org"
216 | source: hosted
217 | version: "0.11.3+1"
218 | matcher:
219 | description:
220 | name: matcher
221 | url: "https://pub.dartlang.org"
222 | source: hosted
223 | version: "0.12.1+1"
224 | merge_map:
225 | description:
226 | name: merge_map
227 | url: "https://pub.dartlang.org"
228 | source: hosted
229 | version: "1.0.0"
230 | meta:
231 | description:
232 | name: meta
233 | url: "https://pub.dartlang.org"
234 | source: hosted
235 | version: "1.0.5"
236 | mime:
237 | description:
238 | name: mime
239 | url: "https://pub.dartlang.org"
240 | source: hosted
241 | version: "0.9.3"
242 | package_config:
243 | description:
244 | name: package_config
245 | url: "https://pub.dartlang.org"
246 | source: hosted
247 | version: "1.0.1"
248 | path:
249 | description:
250 | name: path
251 | url: "https://pub.dartlang.org"
252 | source: hosted
253 | version: "1.4.2"
254 | plugin:
255 | description:
256 | name: plugin
257 | url: "https://pub.dartlang.org"
258 | source: hosted
259 | version: "0.2.0"
260 | quiver:
261 | description:
262 | name: quiver
263 | url: "https://pub.dartlang.org"
264 | source: hosted
265 | version: "0.24.0"
266 | random_string:
267 | description:
268 | name: random_string
269 | url: "https://pub.dartlang.org"
270 | source: hosted
271 | version: "0.0.1"
272 | recase:
273 | description:
274 | name: recase
275 | url: "https://pub.dartlang.org"
276 | source: hosted
277 | version: "1.0.0+1"
278 | sky_engine:
279 | description:
280 | path: "..\\..\\..\\Source\\flutter\\bin\\cache\\pkg\\sky_engine"
281 | relative: true
282 | source: path
283 | version: "0.0.99"
284 | source_gen:
285 | description:
286 | name: source_gen
287 | url: "https://pub.dartlang.org"
288 | source: hosted
289 | version: "0.5.10+1"
290 | source_span:
291 | description:
292 | name: source_span
293 | url: "https://pub.dartlang.org"
294 | source: hosted
295 | version: "1.4.0"
296 | stack_trace:
297 | description:
298 | name: stack_trace
299 | url: "https://pub.dartlang.org"
300 | source: hosted
301 | version: "1.7.4"
302 | stream_channel:
303 | description:
304 | name: stream_channel
305 | url: "https://pub.dartlang.org"
306 | source: hosted
307 | version: "1.6.1"
308 | string_scanner:
309 | description:
310 | name: string_scanner
311 | url: "https://pub.dartlang.org"
312 | source: hosted
313 | version: "1.0.2"
314 | typed_data:
315 | description:
316 | name: typed_data
317 | url: "https://pub.dartlang.org"
318 | source: hosted
319 | version: "1.1.3"
320 | utf:
321 | description:
322 | name: utf
323 | url: "https://pub.dartlang.org"
324 | source: hosted
325 | version: "0.9.0+3"
326 | uuid:
327 | description:
328 | name: uuid
329 | url: "https://pub.dartlang.org"
330 | source: hosted
331 | version: "0.5.3"
332 | vector_math:
333 | description:
334 | name: vector_math
335 | url: "https://pub.dartlang.org"
336 | source: hosted
337 | version: "2.0.4"
338 | watcher:
339 | description:
340 | name: watcher
341 | url: "https://pub.dartlang.org"
342 | source: hosted
343 | version: "0.9.7+3"
344 | web_socket_channel:
345 | description:
346 | name: web_socket_channel
347 | url: "https://pub.dartlang.org"
348 | source: hosted
349 | version: "1.0.4"
350 | yaml:
351 | description:
352 | name: yaml
353 | url: "https://pub.dartlang.org"
354 | source: hosted
355 | version: "2.1.12"
356 | sdks:
357 | dart: ">=1.23.0-dev.0.0 <2.0.0"
358 |
--------------------------------------------------------------------------------
/client/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: client
2 | description: A new Flutter project.
3 |
4 | dependencies:
5 | angel_websocket: ^1.0.0
6 | common:
7 | path: ../common
8 | flutter:
9 | sdk: flutter
10 |
11 | # For information on the generic Dart part of this file, see the
12 | # following page: https://www.dartlang.org/tools/pub/pubspec
13 |
14 | # The following section is specific to Flutter.
15 | flutter:
16 |
17 | # The following line ensures that the Material Icons font is
18 | # included with your application, so that you can use the icons in
19 | # the Icons class.
20 | uses-material-design: true
21 |
22 | # To add assets to your application, add an assets section here, in
23 | # this "flutter" section, as in:
24 | # assets:
25 | # - images/a_dot_burr.jpeg
26 | # - images/a_dot_ham.jpeg
27 |
28 | # To add assets from package dependencies, first ensure the asset
29 | # is in the lib/ directory of the dependency. Then,
30 | # refer to the asset with a path prefixed with
31 | # `packages/PACKAGE_NAME/`. Note: the `lib/` is implied, do not
32 | # include `lib/` in the asset path.
33 | #
34 | # Here is an example:
35 | #
36 | # assets:
37 | # - packages/PACKAGE_NAME/path/to/asset
38 |
39 | # To add custom fonts to your application, add a fonts section here,
40 | # in this "flutter" section. Each entry in this list should have a
41 | # "family" key with the font family name, and a "fonts" key with a
42 | # list giving the asset and other descriptors for the font. For
43 | # example:
44 | # fonts:
45 | # - family: Schyler
46 | # fonts:
47 | # - asset: fonts/Schyler-Regular.ttf
48 | # - asset: fonts/Schyler-Italic.ttf
49 | # style: italic
50 | # - family: Trajan Pro
51 | # fonts:
52 | # - asset: fonts/TrajanPro.ttf
53 | # - asset: fonts/TrajanPro_Bold.ttf
54 | # weight: 700
55 |
--------------------------------------------------------------------------------
/common/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Dart template
3 | # See https://www.dartlang.org/tools/private-files.html
4 |
5 | # source_gen
6 | .dart_tool
7 |
8 | # Files and directories created by pub
9 | .buildlog
10 | .packages
11 | .project
12 | .pub/
13 | .scripts-bin/
14 | build/
15 | **/packages/
16 |
17 | # Files created by dart2js
18 | # (Most Dart developers will use pub build to compile Dart, use/modify these
19 | # rules if you intend to use dart2js directly
20 | # Convention is to use extension '.dart.js' for Dart compiled to Javascript to
21 | # differentiate from explicit Javascript files)
22 | *.dart.js
23 | *.part.js
24 | *.js.deps
25 | *.js.map
26 | *.info.json
27 |
28 | # Directory created by dartdoc
29 | doc/api/
30 |
31 | # Don't commit pubspec lock file
32 | # (Library packages only! Remove pattern if developing an application package)
33 | # pubspec.lock
34 | ### JetBrains template
35 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
36 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
37 |
38 | # User-specific stuff:
39 | .idea/workspace.xml
40 | .idea/tasks.xml
41 | .idea/dictionaries
42 | .idea/vcs.xml
43 | .idea/jsLibraryMappings.xml
44 |
45 | # Sensitive or high-churn files:
46 | .idea/dataSources.ids
47 | .idea/dataSources.xml
48 | .idea/dataSources.local.xml
49 | .idea/sqlDataSources.xml
50 | .idea/dynamic.xml
51 | .idea/uiDesigner.xml
52 |
53 | # Gradle:
54 | .idea/gradle.xml
55 | .idea/libraries
56 |
57 | # Mongo Explorer plugin:
58 | .idea/mongoSettings.xml
59 |
60 | ## File-based project format:
61 | *.iws
62 |
63 | ## Plugin-specific files:
64 |
65 | # IntelliJ
66 | /out/
67 |
68 | # mpeltonen/sbt-idea plugin
69 | .idea_modules/
70 |
71 | # JIRA plugin
72 | atlassian-ide-plugin.xml
73 |
74 | # Crashlytics plugin (for Android Studio and IntelliJ)
75 | com_crashlytics_export_strings.xml
76 | crashlytics.properties
77 | crashlytics-build.properties
78 | fabric.properties
79 |
80 | ### VSCode template
81 | .vscode/*
82 | !.vscode/settings.json
83 | !.vscode/tasks.json
84 | !.vscode/launch.json
85 | !.vscode/extensions.json
86 |
87 | logs/
88 | *.pem
89 | .DS_Store
90 |
--------------------------------------------------------------------------------
/common/common.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/common/lib/common.dart:
--------------------------------------------------------------------------------
1 | export 'src/models/models.dart';
--------------------------------------------------------------------------------
/common/lib/src/models/models.dart:
--------------------------------------------------------------------------------
1 | library common.models;
2 | import 'package:angel_model/angel_model.dart';
3 | import 'package:angel_serialize/angel_serialize.dart';
4 | part 'models.g.dart';
5 |
6 | @serializable
7 | class _User extends Model {
8 | String username, password, salt, avatar;
9 | }
10 |
11 | @serializable
12 | class _Message extends Model {
13 | String userId, text;
14 | _User user;
15 | }
--------------------------------------------------------------------------------
/common/lib/src/models/models.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of common.models;
4 |
5 | // **************************************************************************
6 | // Generator: JsonModelGenerator
7 | // Target: class _User
8 | // **************************************************************************
9 |
10 | class User extends _User {
11 | @override
12 | String id;
13 |
14 | @override
15 | String username;
16 |
17 | @override
18 | String password;
19 |
20 | @override
21 | String salt;
22 |
23 | @override
24 | String avatar;
25 |
26 | @override
27 | DateTime createdAt;
28 |
29 | @override
30 | DateTime updatedAt;
31 |
32 | User(
33 | {this.id,
34 | this.username,
35 | this.password,
36 | this.salt,
37 | this.avatar,
38 | this.createdAt,
39 | this.updatedAt});
40 |
41 | factory User.fromJson(Map data) {
42 | return new User(
43 | id: data['id'],
44 | username: data['username'],
45 | password: data['password'],
46 | salt: data['salt'],
47 | avatar: data['avatar'],
48 | createdAt: data['created_at'] is DateTime
49 | ? data['created_at']
50 | : (data['created_at'] is String
51 | ? DateTime.parse(data['created_at'])
52 | : null),
53 | updatedAt: data['updated_at'] is DateTime
54 | ? data['updated_at']
55 | : (data['updated_at'] is String
56 | ? DateTime.parse(data['updated_at'])
57 | : null));
58 | }
59 |
60 | Map toJson() => {
61 | 'id': id,
62 | 'username': username,
63 | 'password': password,
64 | 'salt': salt,
65 | 'avatar': avatar,
66 | 'created_at': createdAt == null ? null : createdAt.toIso8601String(),
67 | 'updated_at': updatedAt == null ? null : updatedAt.toIso8601String()
68 | };
69 |
70 | static User parse(Map map) => new User.fromJson(map);
71 | }
72 |
73 | // **************************************************************************
74 | // Generator: JsonModelGenerator
75 | // Target: class _Message
76 | // **************************************************************************
77 |
78 | class Message extends _Message {
79 | @override
80 | String id;
81 |
82 | @override
83 | String userId;
84 |
85 | @override
86 | String text;
87 |
88 | @override
89 | _User user;
90 |
91 | @override
92 | DateTime createdAt;
93 |
94 | @override
95 | DateTime updatedAt;
96 |
97 | Message(
98 | {this.id,
99 | this.userId,
100 | this.text,
101 | this.user,
102 | this.createdAt,
103 | this.updatedAt});
104 |
105 | factory Message.fromJson(Map data) {
106 | return new Message(
107 | id: data['id'],
108 | userId: data['user_id'],
109 | text: data['text'],
110 | user: data['user'] == null
111 | ? null
112 | : (data['user'] is User
113 | ? data['user']
114 | : new User.fromJson(data['user'])),
115 | createdAt: data['created_at'] is DateTime
116 | ? data['created_at']
117 | : (data['created_at'] is String
118 | ? DateTime.parse(data['created_at'])
119 | : null),
120 | updatedAt: data['updated_at'] is DateTime
121 | ? data['updated_at']
122 | : (data['updated_at'] is String
123 | ? DateTime.parse(data['updated_at'])
124 | : null));
125 | }
126 |
127 | Map toJson() => {
128 | 'id': id,
129 | 'user_id': userId,
130 | 'text': text,
131 | 'user': user,
132 | 'created_at': createdAt == null ? null : createdAt.toIso8601String(),
133 | 'updated_at': updatedAt == null ? null : updatedAt.toIso8601String()
134 | };
135 |
136 | static Message parse(Map map) => new Message.fromJson(map);
137 | }
138 |
--------------------------------------------------------------------------------
/common/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See http://pub.dartlang.org/doc/glossary.html#lockfile
3 | packages:
4 | analyzer:
5 | description:
6 | name: analyzer
7 | url: "https://pub.dartlang.org"
8 | source: hosted
9 | version: "0.30.0+2"
10 | angel_model:
11 | description:
12 | name: angel_model
13 | url: "https://pub.dartlang.org"
14 | source: hosted
15 | version: "1.0.0"
16 | angel_serialize:
17 | description:
18 | name: angel_serialize
19 | url: "https://pub.dartlang.org"
20 | source: hosted
21 | version: "1.0.0-alpha+1"
22 | angel_serialize_generator:
23 | description:
24 | name: angel_serialize_generator
25 | url: "https://pub.dartlang.org"
26 | source: hosted
27 | version: "1.0.0-alpha+1"
28 | args:
29 | description:
30 | name: args
31 | url: "https://pub.dartlang.org"
32 | source: hosted
33 | version: "0.13.7"
34 | async:
35 | description:
36 | name: async
37 | url: "https://pub.dartlang.org"
38 | source: hosted
39 | version: "1.13.3"
40 | barback:
41 | description:
42 | name: barback
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "0.15.2+11"
46 | build:
47 | description:
48 | name: build
49 | url: "https://pub.dartlang.org"
50 | source: hosted
51 | version: "0.9.3"
52 | build_barback:
53 | description:
54 | name: build_barback
55 | url: "https://pub.dartlang.org"
56 | source: hosted
57 | version: "0.3.0"
58 | build_runner:
59 | description:
60 | name: build_runner
61 | url: "https://pub.dartlang.org"
62 | source: hosted
63 | version: "0.3.4+1"
64 | charcode:
65 | description:
66 | name: charcode
67 | url: "https://pub.dartlang.org"
68 | source: hosted
69 | version: "1.1.1"
70 | cli_util:
71 | description:
72 | name: cli_util
73 | url: "https://pub.dartlang.org"
74 | source: hosted
75 | version: "0.1.2"
76 | code_builder:
77 | description:
78 | name: code_builder
79 | url: "https://pub.dartlang.org"
80 | source: hosted
81 | version: "1.0.4"
82 | code_transformers:
83 | description:
84 | name: code_transformers
85 | url: "https://pub.dartlang.org"
86 | source: hosted
87 | version: "0.5.1+3"
88 | collection:
89 | description:
90 | name: collection
91 | url: "https://pub.dartlang.org"
92 | source: hosted
93 | version: "1.14.3"
94 | convert:
95 | description:
96 | name: convert
97 | url: "https://pub.dartlang.org"
98 | source: hosted
99 | version: "2.0.1"
100 | crypto:
101 | description:
102 | name: crypto
103 | url: "https://pub.dartlang.org"
104 | source: hosted
105 | version: "2.0.2"
106 | csslib:
107 | description:
108 | name: csslib
109 | url: "https://pub.dartlang.org"
110 | source: hosted
111 | version: "0.14.0"
112 | dart_style:
113 | description:
114 | name: dart_style
115 | url: "https://pub.dartlang.org"
116 | source: hosted
117 | version: "1.0.7"
118 | front_end:
119 | description:
120 | name: front_end
121 | url: "https://pub.dartlang.org"
122 | source: hosted
123 | version: "0.1.0-alpha.4"
124 | func:
125 | description:
126 | name: func
127 | url: "https://pub.dartlang.org"
128 | source: hosted
129 | version: "1.0.0"
130 | glob:
131 | description:
132 | name: glob
133 | url: "https://pub.dartlang.org"
134 | source: hosted
135 | version: "1.1.3"
136 | html:
137 | description:
138 | name: html
139 | url: "https://pub.dartlang.org"
140 | source: hosted
141 | version: "0.13.2"
142 | http_parser:
143 | description:
144 | name: http_parser
145 | url: "https://pub.dartlang.org"
146 | source: hosted
147 | version: "3.1.1"
148 | id:
149 | description:
150 | name: id
151 | url: "https://pub.dartlang.org"
152 | source: hosted
153 | version: "1.0.16"
154 | isolate:
155 | description:
156 | name: isolate
157 | url: "https://pub.dartlang.org"
158 | source: hosted
159 | version: "1.0.0"
160 | kernel:
161 | description:
162 | name: kernel
163 | url: "https://pub.dartlang.org"
164 | source: hosted
165 | version: "0.3.0-alpha.1"
166 | logging:
167 | description:
168 | name: logging
169 | url: "https://pub.dartlang.org"
170 | source: hosted
171 | version: "0.11.3+1"
172 | matcher:
173 | description:
174 | name: matcher
175 | url: "https://pub.dartlang.org"
176 | source: hosted
177 | version: "0.12.1+1"
178 | meta:
179 | description:
180 | name: meta
181 | url: "https://pub.dartlang.org"
182 | source: hosted
183 | version: "1.1.1"
184 | mime:
185 | description:
186 | name: mime
187 | url: "https://pub.dartlang.org"
188 | source: hosted
189 | version: "0.9.3"
190 | package_config:
191 | description:
192 | name: package_config
193 | url: "https://pub.dartlang.org"
194 | source: hosted
195 | version: "1.0.2"
196 | path:
197 | description:
198 | name: path
199 | url: "https://pub.dartlang.org"
200 | source: hosted
201 | version: "1.4.2"
202 | plugin:
203 | description:
204 | name: plugin
205 | url: "https://pub.dartlang.org"
206 | source: hosted
207 | version: "0.2.0+1"
208 | pool:
209 | description:
210 | name: pool
211 | url: "https://pub.dartlang.org"
212 | source: hosted
213 | version: "1.3.1"
214 | quiver:
215 | description:
216 | name: quiver
217 | url: "https://pub.dartlang.org"
218 | source: hosted
219 | version: "0.24.0"
220 | recase:
221 | description:
222 | name: recase
223 | url: "https://pub.dartlang.org"
224 | source: hosted
225 | version: "1.0.0+1"
226 | shelf:
227 | description:
228 | name: shelf
229 | url: "https://pub.dartlang.org"
230 | source: hosted
231 | version: "0.6.8"
232 | shelf_static:
233 | description:
234 | name: shelf_static
235 | url: "https://pub.dartlang.org"
236 | source: hosted
237 | version: "0.2.5"
238 | source_gen:
239 | description:
240 | name: source_gen
241 | url: "https://pub.dartlang.org"
242 | source: hosted
243 | version: "0.6.1+1"
244 | source_maps:
245 | description:
246 | name: source_maps
247 | url: "https://pub.dartlang.org"
248 | source: hosted
249 | version: "0.10.4"
250 | source_span:
251 | description:
252 | name: source_span
253 | url: "https://pub.dartlang.org"
254 | source: hosted
255 | version: "1.4.0"
256 | stack_trace:
257 | description:
258 | name: stack_trace
259 | url: "https://pub.dartlang.org"
260 | source: hosted
261 | version: "1.8.0"
262 | stream_channel:
263 | description:
264 | name: stream_channel
265 | url: "https://pub.dartlang.org"
266 | source: hosted
267 | version: "1.6.1"
268 | stream_transform:
269 | description:
270 | name: stream_transform
271 | url: "https://pub.dartlang.org"
272 | source: hosted
273 | version: "0.0.7"
274 | string_scanner:
275 | description:
276 | name: string_scanner
277 | url: "https://pub.dartlang.org"
278 | source: hosted
279 | version: "1.0.2"
280 | typed_data:
281 | description:
282 | name: typed_data
283 | url: "https://pub.dartlang.org"
284 | source: hosted
285 | version: "1.1.3"
286 | utf:
287 | description:
288 | name: utf
289 | url: "https://pub.dartlang.org"
290 | source: hosted
291 | version: "0.9.0+3"
292 | watcher:
293 | description:
294 | name: watcher
295 | url: "https://pub.dartlang.org"
296 | source: hosted
297 | version: "0.9.7+3"
298 | yaml:
299 | description:
300 | name: yaml
301 | url: "https://pub.dartlang.org"
302 | source: hosted
303 | version: "2.1.12"
304 | sdks:
305 | dart: ">=1.22.1 <2.0.0-dev.infinity"
306 |
--------------------------------------------------------------------------------
/common/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: common
2 | dependencies:
3 | angel_model: ^1.0.0
4 | angel_serialize: ^1.0.0-alpha
5 | dev_dependencies:
6 | angel_serialize_generator: ^1.0.0-alpha
7 | build_runner: ^0.3.0
--------------------------------------------------------------------------------
/common/tool/build.dart:
--------------------------------------------------------------------------------
1 | import 'package:build_runner/build_runner.dart';
2 | import 'phases.dart';
3 |
4 | main() => build(PHASES, deleteFilesByDefault: true);
--------------------------------------------------------------------------------
/common/tool/phases.dart:
--------------------------------------------------------------------------------
1 | import 'package:angel_serialize_generator/angel_serialize_generator.dart';
2 | import 'package:build_runner/build_runner.dart';
3 | import 'package:source_gen/source_gen.dart';
4 |
5 | final PhaseGroup PHASES = new PhaseGroup.singleAction(
6 | new GeneratorBuilder([new JsonModelGenerator()]),
7 | new InputSet('common', const ['lib/src/models/*.dart']));
8 |
--------------------------------------------------------------------------------
/common/tool/watch.dart:
--------------------------------------------------------------------------------
1 | import 'package:build_runner/build_runner.dart';
2 | import 'phases.dart';
3 |
4 | main() => watch(PHASES, deleteFilesByDefault: true);
--------------------------------------------------------------------------------
/screenshots/conversation.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/screenshots/conversation.PNG
--------------------------------------------------------------------------------
/screenshots/conversation_small.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/screenshots/conversation_small.PNG
--------------------------------------------------------------------------------
/screenshots/login.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/screenshots/login.PNG
--------------------------------------------------------------------------------
/screenshots/typing.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/screenshots/typing.PNG
--------------------------------------------------------------------------------
/server/.analysis-options:
--------------------------------------------------------------------------------
1 | analyzer:
2 | strong-mode: true
3 | exclude:
4 | - .scripts-bin/**/*.dart
5 |
--------------------------------------------------------------------------------
/server/.dockerignore:
--------------------------------------------------------------------------------
1 | .dart_tool
2 | .idea
3 | .pub
4 | .vscode
5 | logs/
6 | test/
7 | build/
8 | .analysis-options
9 | .packages
10 | *.g.dart
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Dart template
3 | # See https://www.dartlang.org/tools/private-files.html
4 |
5 | # source_gen
6 | .dart_tool
7 |
8 | # Files and directories created by pub
9 | .buildlog
10 | .packages
11 | .project
12 | .pub/
13 | .scripts-bin/
14 | build/
15 | **/packages/
16 |
17 | # Files created by dart2js
18 | # (Most Dart developers will use pub build to compile Dart, use/modify these
19 | # rules if you intend to use dart2js directly
20 | # Convention is to use extension '.dart.js' for Dart compiled to Javascript to
21 | # differentiate from explicit Javascript files)
22 | *.dart.js
23 | *.part.js
24 | *.js.deps
25 | *.js.map
26 | *.info.json
27 |
28 | # Directory created by dartdoc
29 | doc/api/
30 |
31 | # Don't commit pubspec lock file
32 | # (Library packages only! Remove pattern if developing an application package)
33 | # pubspec.lock
34 | ### JetBrains template
35 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
36 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
37 |
38 | # User-specific stuff:
39 | .idea/workspace.xml
40 | .idea/tasks.xml
41 | .idea/dictionaries
42 | .idea/vcs.xml
43 | .idea/jsLibraryMappings.xml
44 |
45 | # Sensitive or high-churn files:
46 | .idea/dataSources.ids
47 | .idea/dataSources.xml
48 | .idea/dataSources.local.xml
49 | .idea/sqlDataSources.xml
50 | .idea/dynamic.xml
51 | .idea/uiDesigner.xml
52 |
53 | # Gradle:
54 | .idea/gradle.xml
55 | .idea/libraries
56 |
57 | # Mongo Explorer plugin:
58 | .idea/mongoSettings.xml
59 |
60 | ## File-based project format:
61 | *.iws
62 |
63 | ## Plugin-specific files:
64 |
65 | # IntelliJ
66 | /out/
67 |
68 | # mpeltonen/sbt-idea plugin
69 | .idea_modules/
70 |
71 | # JIRA plugin
72 | atlassian-ide-plugin.xml
73 |
74 | # Crashlytics plugin (for Android Studio and IntelliJ)
75 | com_crashlytics_export_strings.xml
76 | crashlytics.properties
77 | crashlytics-build.properties
78 | fabric.properties
79 |
80 | ### VSCode template
81 | .vscode/*
82 | !.vscode/settings.json
83 | !.vscode/tasks.json
84 | !.vscode/launch.json
85 | !.vscode/extensions.json
86 |
87 | logs/
88 | *.pem
89 | .DS_Store
90 |
--------------------------------------------------------------------------------
/server/.idea/angel.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/server/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | General
15 |
16 |
17 | XPath
18 |
19 |
20 |
21 |
22 | AngularJS
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/server/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/server/.idea/runConfigurations/Load_Balanced_Server__PRODUCTION_.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/server/.idea/runConfigurations/Message_Tests.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/server/.idea/runConfigurations/Multi_Threaded_Server__PRODUCTION_.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/server/.idea/runConfigurations/Start_Server.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/server/.idea/runConfigurations/Start_Server__PRODUCTION_.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/server/.idea/runConfigurations/Todo_Tests.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/server/.idea/runConfigurations/Users_Tests.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/server/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "Start Server",
6 | "type": "dart-cli",
7 | "request": "launch",
8 | "program": "${workspaceRoot}/bin/server.dart",
9 | "checkedMode": true
10 | },
11 | {
12 | "name": "Multi-Threaded Server",
13 | "type": "dart-cli",
14 | "request": "launch",
15 | "program": "${workspaceRoot}/bin/scaled_server.dart",
16 | "checkedMode": true
17 | },
18 | {
19 | "name": "Load-Balanced Server",
20 | "type": "dart-cli",
21 | "request": "launch",
22 | "program": "${workspaceRoot}/bin/multi_server.dart",
23 | "checkedMode": true
24 | }
25 | ]
26 | }
--------------------------------------------------------------------------------
/server/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "0.1.0",
5 | "command": "pub",
6 | "isShellCommand": true,
7 | "echoCommand": true,
8 | "showOutput": "always",
9 | "tasks": [
10 | {
11 | "taskName": "pub:build",
12 | "suppressTaskName": true,
13 | "args": [
14 | "build"
15 | ]
16 | },
17 | {
18 | "taskName": "pub:serve",
19 | "showOutput": "silent",
20 | "suppressTaskName": true,
21 | "isBackground": true,
22 | "args": [
23 | "serve"
24 | ]
25 | }
26 | ]
27 | }
--------------------------------------------------------------------------------
/server/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:14.04
2 | MAINTAINER Tobe O
3 |
4 | # Install Dart SDK 1.21.0
5 | RUN sudo apt-get update
6 | RUN sudo apt-get install -y apt-transport-https
7 | RUN sudo apt-get install -y curl
8 | RUN sudo sh -c 'curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -'
9 | RUN sudo sh -c 'curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list'
10 | RUN sudo apt-get update
11 | RUN sudo apt-get install -y dart=1.21.0-1
12 | RUN export PATH="/usr/lib/dart/bin:$PATH"
13 |
14 | # Copy necessary files
15 | ADD bin/ bin/
16 | ADD config/ config/
17 | ADD lib/ lib/
18 | ADD tool/ tool/
19 | ADD views/ views/
20 | ADD web/ web/
21 | ADD pubspec.yaml pubspec.yaml
22 |
23 | # Install dependencies, pre-build
24 | RUN /usr/lib/dart/bin/pub get
25 | RUN /usr/lib/dart/bin/dart tool/build.dart
26 | RUN /usr/lib/dart/bin/pub build
27 |
28 | # Set environment, start multi-server :)
29 | ENV ANGEL_ENV=production
30 | EXPOSE 3000
31 | ENTRYPOINT ["/usr/lib/dart/bin/dart"]
32 | CMD ["bin/multi_server.dart"]
--------------------------------------------------------------------------------
/server/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 angel-dart
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/server/README.md:
--------------------------------------------------------------------------------
1 | [](https://angel-dart.github.io)
2 |
3 | [](https://gitter.im/angel_dart/discussion)
4 | [](https://pub.dartlang.org/packages/angel_common)
5 |
6 | **Fill out the [v1.0.0 survey](https://docs.google.com/forms/d/e/1FAIpQLSfEgBNsOoi_nYZMmg2IAGyMv1nNaa6B3kUk3QdNJU5987ucVA/viewform?usp=sf_link) now!!!**
7 |
8 | [Wiki (in-depth documentation)](https://github.com/angel-dart/angel/wiki)
9 |
10 | [API Documentation](http://www.dartdocs.org/documentation/angel_common/latest)
11 |
12 | [Roadmap](https://github.com/angel-dart/roadmap/blob/master/ROADMAP.md)
13 |
14 | [File an Issue](https://github.com/angel-dart/roadmap/issues)
15 |
16 | **The Dart server framework that's ready for showtime.**
17 |
18 | Angel is a full-featured server-side Web application framework for the Dart programming language. It strives to be a flexible, extensible system, to be easily scalable, and to allow as much code to be shared between clients and servers as possible. Ultimately, I believe that this approach will shorten the time it takes to build a full-stack Web application, from start to finish. [Read more...](https://medium.com/the-angel-framework/announcing-angel-v1-0-0-beta-46dfb4aa8afe)
19 |
20 | Like what you see? Please lend us a star. :star:
21 |
22 | ## Newest Tutorials
23 | * [Serving Static Files](https://medium.com/the-angel-framework/serving-static-files-with-the-angel-framework-2ddc7a2b84ae)
24 | * Use With Angular2 ([article](https://dart.academy/using-angel-with-angular2/) | [video](https://www.youtube.com/watch?v=O8tCXj_lljY&feature=youtu.be))
25 | * [Instant REST API's - Intro to Services](https://medium.com/the-angel-framework/instant-rest-apis-and-more-an-introduction-to-angel-services-b843f3187f67)
26 |
27 | ## Installation & Setup
28 | *Having errors with a fresh Angel installation? See [here](https://github.com/angel-dart/angel/wiki/Installation-&-Setup) for help.*
29 |
30 | Once you have [Dart](https://www.dartlang.org/) installed, bootstrapping a project is as simple as running one shell command:
31 |
32 | Install the [Angel CLI](https://github.com/angel-dart/cli):
33 |
34 | ```bash
35 | pub global activate angel_cli
36 | ```
37 |
38 | Bootstrap a project:
39 |
40 | ```bash
41 | angel init hello
42 | ```
43 |
44 | You can even have your server run and be *live-reloaded* on file changes:
45 |
46 | ```bash
47 | dart bin/server.dart
48 | ```
49 |
50 | Next, check out the [detailed documentation](https://github.com/angel-dart/angel/wiki) to learn to flesh out your project.
51 |
52 | ## Features
53 | With features like the following, Angel is the all-in-one framework you should choose to build your next project:
54 | * [Advanced, Modular Routing](https://github.com/angel-dart/route)
55 | * [Middleware](https://github.com/angel-dart/angel/wiki/Middleware)
56 | * [Dependency Injection](https://github.com/angel-dart/angel/wiki/Dependency-Injection)
57 | * And [much more](https://github.com/angel-dart)...
58 |
59 | ## Basic Example
60 | More examples and complete projects can be found in the [angel-example](https://github.com/angel-example) organization.
61 |
62 | The following is an [explosive application](https://github.com/angel-example/explode) complete with a REST API and
63 | WebSocket support. It interacts with a MongoDB database, and reads configuration automatically from a `config/.yaml` file. Templates are rendered with Mustache, and all responses are compressed via GZIP.
64 |
65 | **All in just about 20 lines of actual code.**
66 |
67 | ```dart
68 | import 'dart:async';
69 | import 'package:angel_common/angel_common.dart';
70 | import 'package:angel_websocket/server.dart';
71 | import 'package:mongo_dart/mongo_dart.dart';
72 |
73 | main() async {
74 | var app = await createServer();
75 | var server = await app.startServer(InternetAddress.LOOPBACK_IP_V4, 8080);
76 | print('Angel listening at http://${server.address.address}:${server.port}');
77 | }
78 |
79 | Future createServer() async {
80 | // New instance...
81 | var app = new Angel();
82 |
83 | // Configuration
84 | await app.configure(loadConfigurationFile());
85 | await app.configure(mustache());
86 | Db db = new Db();
87 | await db.open(app.mongodb_url);
88 | app.container.singleton(db); // Add to DI
89 |
90 | // Routes
91 | app.get('/foo', (req, res) => res.render('hello'));
92 |
93 | app.post('/query', (Db db) async {
94 | // Db is an injected dependency here :)
95 | return await db.collection('foo').find().toList();
96 | });
97 |
98 | // Services (which build REST API's and are broadcasted over WS)
99 | app.use('/bombs', new MongoService(db.collection('bombs')));
100 | app.use('/users', new MongoService(db.collection('users')));
101 | app.use('/explosions', new AnonymousService(create: (data, [params]) => data));
102 |
103 |
104 | // Setup WebSockets, add GZIP, etc.
105 | await app.configure(new AngelWebSocket());
106 | app.responseFinalizers.add(gzip());
107 |
108 | return app;
109 | }
110 | ```
111 |
112 | ## Get Social
113 | Join an activate chat about the Angel Framework, or seek assistance: https://gitter.im/angel_dart/discussion
114 |
--------------------------------------------------------------------------------
/server/bin/cluster.dart:
--------------------------------------------------------------------------------
1 | library server.cluster;
2 |
3 | import 'dart:async';
4 | import 'common.dart';
5 | import 'dart:isolate';
6 |
7 | main(args, SendPort sendPort) async {
8 | runZoned(startServer(args, sendPort: sendPort), onError: onError);
9 | }
10 |
--------------------------------------------------------------------------------
/server/bin/common.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:isolate';
3 | import 'package:server/server.dart';
4 | import 'package:angel_diagnostics/angel_diagnostics.dart';
5 | import 'package:angel_hot/angel_hot.dart';
6 | import 'package:intl/intl.dart';
7 |
8 | /// Start a single instance of this application.
9 | ///
10 | /// If a [sendPort] is provided, then the URL of the mounted server will be sent through the port.
11 | /// Use this if you are starting multiple instances of your server.
12 | startServer(args, {SendPort sendPort}) {
13 | return () async {
14 | var app = await createServer();
15 | var dateFormat = new DateFormat("y-MM-dd");
16 | var logFile = new File("logs/${dateFormat.format(new DateTime.now())}.txt");
17 | InternetAddress host;
18 | int port;
19 |
20 | // Load the right host and port from application config.
21 | host = new InternetAddress(app.properties['host']);
22 |
23 | // Listen on port 0 if we are using the load balancer.
24 | port = sendPort != null ? 0 : app.properties['port'];
25 |
26 | // Log requests and errors to a log file.
27 | await app.configure(logRequests(logFile));
28 | HttpServer server;
29 |
30 | // Use `package:angel_hot` in any case, EXCEPT if starting in production mode.
31 | //
32 | // With hot-reloading, our server will automatically reload in-place on file changes,
33 | // for a faster development cycle. :)
34 | if (Platform.environment['ANGEL_ENV'] == 'production')
35 | server = await app.startServer(host, port);
36 | else {
37 | var hot = new HotReloader(() async {
38 | // If we are hot-reloading, we need to provide a callback
39 | // to use to start a fresh instance on-the-fly.
40 | var app = await createServer();
41 | await app.configure(logRequests(logFile));
42 | return app;
43 | },
44 | // Paths we might want to listen for changes on...
45 | [
46 | new Directory('config'),
47 | new Directory('lib'),
48 | new Directory('views')
49 | ]);
50 | server = await hot.startServer(host, port);
51 | }
52 |
53 | if (sendPort == null) {
54 | print('Listening at http://${server.address.address}:${server.port}');
55 | } else
56 | sendPort?.send([server.address.address, server.port]);
57 | };
58 | }
59 |
60 | onError(error, [StackTrace stackTrace]) {
61 | stderr.writeln("Unhandled error occurred: $error");
62 | if (stackTrace != null) {
63 | stderr.writeln(stackTrace);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/server/bin/multi_server.dart:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env dart
2 | library server.multi_server;
3 |
4 | import 'dart:io';
5 | import 'package:angel_compress/angel_compress.dart';
6 | import 'package:angel_multiserver/angel_multiserver.dart';
7 |
8 | final Uri cluster = Platform.script.resolve('cluster.dart');
9 |
10 | /// The number of isolates to spawn. You might consider starting one instance
11 | /// per processor core on your machine.
12 | final int nInstances = Platform.numberOfProcessors;
13 |
14 | main() async {
15 | var app = new LoadBalancer();
16 | // Or, for SSL:
17 | // var app = new LoadBalancer.secure('', '');
18 |
19 | // Response compression!
20 | app.responseFinalizers.add(gzip());
21 |
22 | // Cache static assets - just to lower response time
23 | await app.configure(cacheResponses(filters: [new RegExp(r'images/.*')]));
24 |
25 | // Start up multiple instances of our main application.
26 | await app.spawnIsolates(cluster, count: nInstances);
27 |
28 | app.onCrash.listen((_) async {
29 | // Boot up a new instance on crash
30 | await app.spawnIsolates(cluster);
31 | });
32 |
33 | var host = InternetAddress.ANY_IP_V4;
34 | var port = 3000;
35 | var server = await app.startServer(host, port);
36 | print('Listening at http://${server.address.address}:${server.port}');
37 | print('Load-balancing $nInstances instance(s)');
38 | }
39 |
--------------------------------------------------------------------------------
/server/bin/scaled_server.dart:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env dart
2 |
3 | library server.scaled_server;
4 |
5 | import 'dart:io';
6 | import 'dart:isolate';
7 | import 'package:angel_compress/angel_compress.dart';
8 | import 'package:angel_diagnostics/angel_diagnostics.dart';
9 | import 'package:angel_multiserver/angel_multiserver.dart';
10 | import 'package:server/server.dart';
11 |
12 | /// The number of isolates to spawn. You might consider starting one instance
13 | /// per processor core on your machine.
14 | final int nInstances = Platform.numberOfProcessors;
15 |
16 | main() {
17 | var startupPort = new ReceivePort();
18 | List startupMessages = [];
19 |
20 | // Start up multiple instances of our application.
21 | for (int i = 0; i < nInstances; i++) {
22 | Isolate.spawn(isolateMain, [i, startupPort.sendPort]);
23 | }
24 |
25 | int nStarted = 0;
26 |
27 | // Listen for notifications of application startup...
28 | startupPort.listen((String startupMessage) {
29 | startupMessages.add(startupMessage);
30 |
31 | if (++nStarted == nInstances) {
32 | // Keep track of how many instances successfully started up,
33 | // and print a success message when they all boot.
34 | startupMessages.forEach(print);
35 | print('Spawned $nInstances instance(s) of Angel.');
36 | }
37 | });
38 | }
39 |
40 | void isolateMain(List args) {
41 | int instanceId = args[0];
42 | SendPort startupPort = args[1];
43 |
44 | createServer().then((app) async {
45 | // Response compression via GZIP.
46 | //
47 | // See the documentation here:
48 | // https://github.com/angel-dart/compress
49 | app.responseFinalizers.add(gzip());
50 |
51 | // Cache static assets - just to lower response time.
52 | //
53 | // See the documentation here:
54 | // https://github.com/angel-dart/multiserver
55 | //
56 | // Here is an example of response caching:
57 | // https://github.com/angel-dart/multiserver/blob/master/example/cache.dart
58 | await app.configure(cacheResponses(filters: [new RegExp(r'images/.*')]));
59 |
60 | var server = await app.startServer(
61 | InternetAddress.ANY_IP_V4, app.properties['port'] ?? 3000);
62 |
63 | // Print request and error information to the console.
64 | await app.configure(logRequests());
65 |
66 | // Send a notification back to the main isolate
67 | startupPort.send('Instance #$instanceId listening at http://${server.address.address}:${server.port}');
68 | });
69 | }
70 |
--------------------------------------------------------------------------------
/server/bin/server.dart:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env dart
2 | import 'dart:async';
3 | import 'common.dart';
4 |
5 | main(args) async {
6 | runZoned(startServer(args), onError: onError);
7 | }
8 |
--------------------------------------------------------------------------------
/server/config/default.yaml:
--------------------------------------------------------------------------------
1 | # Default server configuration.
2 | host: 0.0.0.0
3 | mongo_db: mongodb://localhost:27017/server
4 | port: 3000
5 | jwt_secret: "VU517um0wJMWcA7H8Uatje80WnfDkR0W"
--------------------------------------------------------------------------------
/server/config/development.yaml:
--------------------------------------------------------------------------------
1 | # Development-only server configuration.
2 | debug: true
--------------------------------------------------------------------------------
/server/config/production.yaml:
--------------------------------------------------------------------------------
1 | # Production-only server configuration
2 | debug: false
3 | # jwt_secret: "72302125357831322256836652434772"
--------------------------------------------------------------------------------
/server/lib/server.dart:
--------------------------------------------------------------------------------
1 | library server;
2 |
3 | import 'dart:async';
4 | import 'package:angel_common/angel_common.dart';
5 | import 'package:angel_websocket/server.dart';
6 | import 'src/config/config.dart' as configuration;
7 | import 'src/routes/routes.dart' as routes;
8 | import 'src/services/services.dart' as services;
9 |
10 | /// Creates and configures the server instance.
11 | Future createServer() async {
12 | /// Passing `startShared` to the constructor allows us to start multiple
13 | /// instances of our application concurrently, listening on a single port.
14 | ///
15 | /// This effectively lets us multi-thread the application.
16 | var app = new Angel.custom(startShared);
17 |
18 | /// Set up our application, using three plug-ins defined with this project.
19 | await app.configure(configuration.configureServer);
20 | await app.configure(services.configureServer);
21 | await app.configure(routes.configureServer);
22 | await app.configure(new AngelWebSocket());
23 |
24 | return app;
25 | }
26 |
--------------------------------------------------------------------------------
/server/lib/src/config/config.dart:
--------------------------------------------------------------------------------
1 | library server.config;
2 |
3 | import 'dart:convert';
4 | import 'dart:io';
5 | import 'package:angel_common/angel_common.dart';
6 | import 'plugins/plugins.dart' as plugins;
7 |
8 | /// This is a perfect place to include configuration and load plug-ins.
9 | configureServer(Angel app) async {
10 | // Speed boost.
11 | app.lazyParseBodies = true;
12 | //app.injectSerializer(JSON.encode);
13 |
14 | // Load configuration from the `config/` directory.
15 | //
16 | // See: https://github.com/angel-dart/configuration
17 | await app.configure(loadConfigurationFile());
18 |
19 | // Configure our application to render Mustache templates from the `views/` directory.
20 | //
21 | // See: https://github.com/angel-dart/mustache
22 | await app.configure(mustache(new Directory('views')));
23 |
24 | // Apply another plug-ins, i.e. ones that *you* have written.
25 | //
26 | // Typically, the plugins in `lib/src/config/plugins/plugins.dart` are plug-ins
27 | // that add functionality specific to your application.
28 | //
29 | // If you write a plug-in that you plan to use again, or are
30 | // using one created by the community, include it in
31 | // `lib/src/config/config.dart`.
32 | await plugins.configureServer(app);
33 | }
34 |
--------------------------------------------------------------------------------
/server/lib/src/config/plugins/plugins.dart:
--------------------------------------------------------------------------------
1 | library server.config.plugins;
2 |
3 | import 'dart:async';
4 | import 'package:angel_common/angel_common.dart';
5 | import 'package:angel_seeder/angel_seeder.dart';
6 |
7 | Future configureServer(Angel app) async {
8 | // Include any plugins you have made here.
9 | await app.configure(seedApp);
10 | }
11 |
12 | Future seedApp(Angel app) async {
13 | await app.configure(seedUsers);
14 | }
15 |
16 | Future seedUsers(Angel app) async {
17 | // Auto-generate users...
18 | app.justBeforeStart.add((app) async {
19 | await app.configure(seed(
20 | 'api/users',
21 | new SeederConfiguration(count: 10, template: {
22 | 'username': () => faker.internet.userName(),
23 | 'password': () => faker.internet.password()
24 | })));
25 | });
26 | }
27 |
--------------------------------------------------------------------------------
/server/lib/src/routes/controllers/auth.dart:
--------------------------------------------------------------------------------
1 | library server.routes.controllers.auth;
2 |
3 | import 'package:angel_common/angel_common.dart';
4 | import 'package:common/common.dart';
5 | import '../../services/user.dart';
6 |
7 | /// Configures the application to authenticate users securely.
8 | /// See the documentation for controllers:
9 | ///
10 | /// https://github.com/angel-dart/angel/wiki/Controllers
11 | @Expose('/auth')
12 | class AuthController extends Controller {
13 | /// Controls application authentication.
14 | ///
15 | /// See the documentation:
16 | /// * https://medium.com/the-angel-framework/logging-users-in-to-angel-applications-ccf32aba0dac
17 | /// * https://github.com/angel-dart/auth
18 | AngelAuth auth;
19 |
20 | /// Clients will see the result of `deserializer`, so let's pretend to be a client.
21 | ///
22 | /// Our User service is already wired to remove sensitive data from serialized JSON.
23 | deserializer(String id) async =>
24 | app.service('api/users').read(id, {'provider': Providers.REST});
25 |
26 | serializer(User user) async => user.id;
27 |
28 | /// Attempts to log a user in.
29 | LocalAuthVerifier localVerifier(Service userService) {
30 | return (String username, String password) async {
31 | Iterable users = (await userService.index({
32 | 'query': {'username': username}
33 | }))
34 | .map(User.parse);
35 |
36 | if (users.isNotEmpty) {
37 | return users.firstWhere((user) {
38 | var hash = hashPassword(password, user.salt, app.jwt_secret);
39 | return user.username == username && user.password == hash;
40 | }, orElse: () => null);
41 | } else {
42 | // Let's just make a new user, because I am lazy.
43 | return await app.service('api/users').create(
44 | {'username': username, 'password': password}).then(User.parse);
45 | }
46 | };
47 | }
48 |
49 | @override
50 | call(Angel app) async {
51 | // Wire up local authentication, connected to our User service
52 | auth = new AngelAuth(jwtKey: app.jwt_secret)
53 | ..serializer = serializer
54 | ..deserializer = deserializer
55 | ..strategies
56 | .add(new LocalAuthStrategy(localVerifier(app.service('api/users'))));
57 |
58 | await super.call(app);
59 | await app.configure(auth);
60 | }
61 |
62 | @Expose('/local', method: 'POST')
63 | login() => auth.authenticate('local');
64 | }
65 |
--------------------------------------------------------------------------------
/server/lib/src/routes/controllers/controllers.dart:
--------------------------------------------------------------------------------
1 | library server.routes.controllers;
2 |
3 | import 'package:angel_common/angel_common.dart';
4 | import 'auth.dart';
5 |
6 | configureServer(Angel app) async {
7 | /// Controllers will not function unless wired to the application!
8 | await app.configure(new AuthController());
9 | }
10 |
--------------------------------------------------------------------------------
/server/lib/src/routes/routes.dart:
--------------------------------------------------------------------------------
1 | library server.routes;
2 |
3 | import 'dart:io';
4 | import 'package:angel_common/angel_common.dart';
5 | import 'controllers/controllers.dart' as controllers;
6 |
7 | /// Adds global middleware to the application.
8 | ///
9 | /// Use these to apply functionality to requests before business logic is run.
10 | ///
11 | /// More on the request lifecycle:
12 | /// https://github.com/angel-dart/angel/wiki/Request-Lifecycle
13 | configureBefore(Angel app) async {
14 | app.before.add(cors());
15 | }
16 |
17 | /// Put your app routes here!
18 | ///
19 | /// See the wiki for information about routing, requests, and responses:
20 | /// * https://github.com/angel-dart/angel/wiki/Basic-Routing
21 | /// * https://github.com/angel-dart/angel/wiki/Requests-&-Responses
22 | configureRoutes(Angel app) async {
23 | // Render `views/hello.mustache` when a user visits the application root.
24 | app.get('/', (req, ResponseContext res) => res.render('hello'));
25 | }
26 |
27 | /// Configures fallback middleware.
28 | ///
29 | /// Use these to run generic actions on requests that were not terminated by
30 | /// earlier request handlers.
31 | ///
32 | /// Note that these middleware might not always run.
33 | ///
34 | /// More on the request lifecycle: https://github.com/angel-dart/angel/wiki/Request-Lifecycle
35 | configureAfter(Angel app) async {
36 | // Uncomment this to proxy over `pub serve` while in development.
37 | // This is a useful feature for full-stack applications, especially if you
38 | // are using Angular2.
39 | //
40 | // For documentation, see `package:angel_proxy`:
41 | // https://github.com/angel-dart/proxy
42 | //
43 | // await app.configure(new PubServeLayer());
44 |
45 | // Mount static server at /web or /build/web, depending on if
46 | // you are running in production mode. `Cache-Control` headers will also be enabled.
47 | //
48 | // Read the following two sources for documentation:
49 | // * https://medium.com/the-angel-framework/serving-static-files-with-the-angel-framework-2ddc7a2b84ae
50 | // * https://github.com/angel-dart/static
51 | await app.configure(new CachingVirtualDirectory());
52 |
53 | // Set our application up to handle different errors.
54 | //
55 | // Read the following two sources for documentation:
56 | // * https://github.com/angel-dart/angel/wiki/Error-Handling
57 | // * https://github.com/angel-dart/errors
58 | var errors = new ErrorHandler(handlers: {
59 | // Display a 404 page if no resource is found.
60 | 404: (req, res) async =>
61 | res.render('error', {'message': 'No file exists at ${req.path}.'}),
62 |
63 | // On generic errors, give information about why the application failed.
64 | //
65 | // An `AngelHttpException` instance will be present in `req.properties`
66 | // as `error`.
67 | 500: (req, res) async => res.render('error', {'message': req.error.message})
68 | });
69 |
70 | // Use a fatal error handler to attempt to resolve any issues that
71 | // result in Angel not being able to send the user a response.
72 | errors.fatalErrorHandler = (AngelFatalError e) async {
73 | try {
74 | // Manually create a request and response context.
75 | var req = await RequestContext.from(e.request, app);
76 | var res = new ResponseContext(e.request.response, app);
77 |
78 | // *Attempt* to render an error page.
79 | res.render('error', {'message': 'Internal Server Error: ${e.error}'});
80 | await app.sendResponse(e.request, req, res);
81 | } catch (_) {
82 | // If execution fails here, there is nothing we can do.
83 | stderr..writeln('Fatal error: ${e.error}')..writeln(e.stack);
84 | }
85 | };
86 |
87 | // Throw a 404 if no route matched the request.
88 | app.after.add(() => throw new AngelHttpException.notFound());
89 |
90 | // Handle errors when they occur, based on outgoing status code.
91 | // By default, requests will go through the 500 handler, unless
92 | // they have an outgoing 200, or their status code has a handler
93 | // registered.
94 | app.after.add(errors.middleware());
95 |
96 | // Pass AngelHttpExceptions through handler as well.
97 | //
98 | // Again, here is the error handling documentation:
99 | // * https://github.com/angel-dart/angel/wiki/Error-Handling
100 | // * https://github.com/angel-dart/errors
101 | await app.configure(errors);
102 | }
103 |
104 | /// Adds response finalizers to the application.
105 | ///
106 | /// These run after every request.
107 | ///
108 | /// See more on the request lifecycle here:
109 | /// https://github.com/angel-dart/angel/wiki/Request-Lifecycle
110 | configureFinalizers(Angel app) async {}
111 |
112 | /// Adds routes to our application.
113 | ///
114 | /// See the wiki for information about routing, requests, and responses:
115 | /// * https://github.com/angel-dart/angel/wiki/Basic-Routing
116 | /// * https://github.com/angel-dart/angel/wiki/Requests-&-Responses
117 | configureServer(Angel app) async {
118 | // The order in which we run these plug-ins is relatively significant.
119 | // Try not to change it.
120 |
121 | // Add global middleware.
122 | await configureBefore(app);
123 |
124 | // Typically, you want to mount controllers first, after any global middleware.
125 | await app.configure(controllers.configureServer);
126 |
127 | // Next, you can add any supplemental routes.
128 | await configureRoutes(app);
129 |
130 | // Add handlers to run after requests are handled.
131 | //
132 | // See the request lifecycle docs to find out why these two
133 | // are separate:
134 | // https://github.com/angel-dart/angel/wiki/Request-Lifecycle
135 | await configureAfter(app);
136 | await configureFinalizers(app);
137 | }
138 |
--------------------------------------------------------------------------------
/server/lib/src/services/message.dart:
--------------------------------------------------------------------------------
1 | import 'package:angel_common/angel_common.dart';
2 | import 'package:angel_framework/hooks.dart' as hooks;
3 | import 'package:angel_relations/angel_relations.dart' as relations;
4 | import 'package:angel_security/hooks.dart' as auth;
5 | import 'package:angel_websocket/hooks.dart' as ws;
6 |
7 | AngelConfigurer configureServer() {
8 | return (Angel app) async {
9 | app.use('/api/messages', new MapService());
10 | var service = app.service('api/messages') as HookedService;
11 |
12 | // Users should only be able to index the message collection,
13 | // read individual messages, and create new messages.
14 | //
15 | // Disable everything else (for clients);
16 | service.before([
17 | HookedServiceEvent.MODIFIED,
18 | HookedServiceEvent.UPDATED,
19 | HookedServiceEvent.REMOVED
20 | ], hooks.chainListeners([hooks.disable(), ws.doNotBroadcast()]));
21 |
22 | // Each message should have a `user_id` pointing to the user who sent it.
23 | //
24 | // Use this hook to automatically set a `user_id` on create events.
25 | // This hook also throws a 403 if the user is not logged in.
26 | service.beforeCreated
27 | .listen(auth.associateCurrentUser(ownerField: 'user_id'));
28 |
29 | // Use a simple belongsTo hook to populate a 'user' field.
30 | //
31 | // This assumes that each Message has a `user_id`. It then
32 | // searches the `api/users` services for a user with a matching ID.
33 | //
34 | // If it finds a user, it sets `user` to the user it finds. The hook
35 | // is intelligent enough to set this `user` field on both Maps and Dart
36 | // objects without hassle.
37 | service.afterAll(
38 | relations.belongsTo('api/users', as: 'user', localKey: 'user_id'));
39 | };
40 | }
41 |
--------------------------------------------------------------------------------
/server/lib/src/services/services.dart:
--------------------------------------------------------------------------------
1 | library server.services;
2 |
3 | import 'package:angel_common/angel_common.dart';
4 | import 'message.dart' as message;
5 | import 'user.dart' as user;
6 |
7 | /// Configure our application to use *services*.
8 | /// Services must be wired to the app via `app.use`.
9 | ///
10 | /// They provide many benefits, such as instant REST API generation,
11 | /// and respond to both REST and WebSockets.
12 | ///
13 | /// Read more here:
14 | /// https://github.com/angel-dart/angel/wiki/Service-Basics
15 | configureServer(Angel app) async {
16 | await app.configure(message.configureServer());
17 | await app.configure(user.configureServer());
18 | }
19 |
--------------------------------------------------------------------------------
/server/lib/src/services/user.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math' as math;
2 | import 'package:angel_common/angel_common.dart';
3 | import 'package:angel_framework/hooks.dart' as hooks;
4 | import 'package:angel_websocket/hooks.dart' as ws;
5 | import 'package:crypto/crypto.dart' show sha256;
6 | import 'package:random_string/random_string.dart' as rs;
7 | // import '../validators/user.dart';
8 |
9 | const List avatars = const [
10 | 'dart.png',
11 | 'favicon.png',
12 | 'flutter.jpg',
13 | 'google.png'
14 | ];
15 |
16 | /// Sets up a service mounted at `api/users`.
17 | ///
18 | /// In the real world, you will want to hook this up to a database.
19 | /// However, for the sake of the boilerplate, an in-memory service is used,
20 | /// so that users are not tied into using just one database. :)
21 | configureServer() {
22 | return (Angel app) async {
23 | // Store data in-memory.
24 | app.use('/api/users', new MapService());
25 |
26 | // Configure hooks for the user service.
27 | // Hooks can be used to add additional functionality, or change the behavior
28 | // of services, and run on any service, regardless of which database you are using.
29 | //
30 | // If you have not already, *definitely* read the service hook documentation:
31 | // https://github.com/angel-dart/angel/wiki/Hooks
32 |
33 | var service = app.service('api/users') as HookedService;
34 |
35 | // Clients can't create, modify, update, or remove users.
36 | //
37 | // Refrain from broadcasting these events via WebSockets.
38 | service.before([
39 | HookedServiceEvent.CREATED,
40 | HookedServiceEvent.MODIFIED,
41 | HookedServiceEvent.UPDATED,
42 | HookedServiceEvent.REMOVED
43 | ], hooks.chainListeners([hooks.disable(), ws.doNotBroadcast()]));
44 |
45 | // Hash user passwords.
46 | service.beforeCreated.listen((e) {
47 | var salt = rs.randomAlphaNumeric(12);
48 | e.data
49 | ..['password'] = hashPassword(e.data['password'], salt, app.jwt_secret)
50 | ..['salt'] = salt;
51 | });
52 |
53 | // Choose a random avatar when a new user is created.
54 | var rnd = new math.Random();
55 |
56 | service.beforeCreated.listen((HookedServiceEvent e) {
57 | var avatar = avatars[rnd.nextInt(avatars.length)];
58 | e.data['avatar'] = avatar;
59 | });
60 |
61 | // Remove sensitive data from serialized JSON.
62 | service.afterAll(hooks.remove(['password', 'salt']));
63 | };
64 | }
65 |
66 | /// SHA-256 hash any string, particularly a password.
67 | String hashPassword(String password, String salt, String pepper) =>
68 | sha256.convert(('$salt:$password:$pepper').codeUnits).toString();
69 |
--------------------------------------------------------------------------------
/server/lib/src/validators/message.dart:
--------------------------------------------------------------------------------
1 | library server.validtors.message;
2 | import 'package:angel_validate/angel_validate.dart';
3 |
4 | final Validator MESSAGE = new Validator({
5 | 'name': [isString, isNotEmpty],
6 | 'desc': [isString, isNotEmpty]
7 | });
8 |
9 | final Validator CREATE_MESSAGE = MESSAGE.extend({})
10 | ..requiredFields.addAll(['name', 'desc']);
--------------------------------------------------------------------------------
/server/lib/src/validators/todo.dart:
--------------------------------------------------------------------------------
1 | library server.validtors.todo;
2 | import 'package:angel_validate/angel_validate.dart';
3 |
4 | final Validator TODO = new Validator({
5 | 'name': [isString, isNotEmpty],
6 | 'desc': [isString, isNotEmpty]
7 | });
8 |
9 | final Validator CREATE_TODO = TODO.extend({})
10 | ..requiredFields.addAll(['name', 'desc']);
--------------------------------------------------------------------------------
/server/lib/src/validators/user.dart:
--------------------------------------------------------------------------------
1 | import 'package:angel_validate/angel_validate.dart';
2 |
3 | // Validators can be used on the server, in the browser, and even in Flutter.
4 | //
5 | // It is highly recommended that you read the documentation:
6 | // https://github.com/angel-dart/validate
7 | final Validator USER = new Validator({
8 | 'email': [isString, isNotEmpty, isEmail],
9 | 'username': [isString, isNotEmpty],
10 | 'password': [isString, isNotEmpty]
11 | });
12 |
13 | final Validator CREATE_USER = USER.extend({})
14 | ..requiredFields.addAll(['email', 'username', 'password'])
15 | ..forbiddenFields.addAll(['salt', 'roles']);
16 |
--------------------------------------------------------------------------------
/server/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See http://pub.dartlang.org/doc/glossary.html#lockfile
3 | packages:
4 | _discoveryapis_commons:
5 | description:
6 | name: _discoveryapis_commons
7 | url: "https://pub.dartlang.org"
8 | source: hosted
9 | version: "0.1.4"
10 | analyzer:
11 | description:
12 | name: analyzer
13 | url: "https://pub.dartlang.org"
14 | source: hosted
15 | version: "0.30.0+2"
16 | angel_auth:
17 | description:
18 | name: angel_auth
19 | url: "https://pub.dartlang.org"
20 | source: hosted
21 | version: "1.0.5"
22 | angel_auth_google:
23 | description:
24 | name: angel_auth_google
25 | url: "https://pub.dartlang.org"
26 | source: hosted
27 | version: "1.0.0+1"
28 | angel_client:
29 | description:
30 | name: angel_client
31 | url: "https://pub.dartlang.org"
32 | source: hosted
33 | version: "1.0.7"
34 | angel_common:
35 | description:
36 | name: angel_common
37 | url: "https://pub.dartlang.org"
38 | source: hosted
39 | version: "1.0.0"
40 | angel_compress:
41 | description:
42 | name: angel_compress
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "1.0.0+2"
46 | angel_configuration:
47 | description:
48 | name: angel_configuration
49 | url: "https://pub.dartlang.org"
50 | source: hosted
51 | version: "1.0.4"
52 | angel_cors:
53 | description:
54 | name: angel_cors
55 | url: "https://pub.dartlang.org"
56 | source: hosted
57 | version: "1.0.0+1"
58 | angel_diagnostics:
59 | description:
60 | name: angel_diagnostics
61 | url: "https://pub.dartlang.org"
62 | source: hosted
63 | version: "1.0.2"
64 | angel_errors:
65 | description:
66 | name: angel_errors
67 | url: "https://pub.dartlang.org"
68 | source: hosted
69 | version: "1.0.0"
70 | angel_file_security:
71 | description:
72 | name: angel_file_security
73 | url: "https://pub.dartlang.org"
74 | source: hosted
75 | version: "1.0.1"
76 | angel_framework:
77 | description:
78 | name: angel_framework
79 | url: "https://pub.dartlang.org"
80 | source: hosted
81 | version: "1.0.7+1"
82 | angel_hot:
83 | description:
84 | name: angel_hot
85 | url: "https://pub.dartlang.org"
86 | source: hosted
87 | version: "1.0.1"
88 | angel_model:
89 | description:
90 | name: angel_model
91 | url: "https://pub.dartlang.org"
92 | source: hosted
93 | version: "1.0.0"
94 | angel_mongo:
95 | description:
96 | name: angel_mongo
97 | url: "https://pub.dartlang.org"
98 | source: hosted
99 | version: "1.1.6"
100 | angel_multiserver:
101 | description:
102 | name: angel_multiserver
103 | url: "https://pub.dartlang.org"
104 | source: hosted
105 | version: "1.0.9"
106 | angel_mustache:
107 | description:
108 | name: angel_mustache
109 | url: "https://pub.dartlang.org"
110 | source: hosted
111 | version: "1.0.3"
112 | angel_proxy:
113 | description:
114 | name: angel_proxy
115 | url: "https://pub.dartlang.org"
116 | source: hosted
117 | version: "1.0.8"
118 | angel_relations:
119 | description:
120 | name: angel_relations
121 | url: "https://pub.dartlang.org"
122 | source: hosted
123 | version: "1.0.1"
124 | angel_route:
125 | description:
126 | name: angel_route
127 | url: "https://pub.dartlang.org"
128 | source: hosted
129 | version: "1.0.4"
130 | angel_security:
131 | description:
132 | name: angel_security
133 | url: "https://pub.dartlang.org"
134 | source: hosted
135 | version: "1.0.2"
136 | angel_seeder:
137 | description:
138 | name: angel_seeder
139 | url: "https://pub.dartlang.org"
140 | source: hosted
141 | version: "1.0.1"
142 | angel_serialize:
143 | description:
144 | name: angel_serialize
145 | url: "https://pub.dartlang.org"
146 | source: hosted
147 | version: "1.0.0-alpha+1"
148 | angel_static:
149 | description:
150 | name: angel_static
151 | url: "https://pub.dartlang.org"
152 | source: hosted
153 | version: "1.2.4"
154 | angel_test:
155 | description:
156 | name: angel_test
157 | url: "https://pub.dartlang.org"
158 | source: hosted
159 | version: "1.0.6"
160 | angel_validate:
161 | description:
162 | name: angel_validate
163 | url: "https://pub.dartlang.org"
164 | source: hosted
165 | version: "1.0.2+4"
166 | angel_websocket:
167 | description:
168 | name: angel_websocket
169 | url: "https://pub.dartlang.org"
170 | source: hosted
171 | version: "1.0.8"
172 | ansicolor:
173 | description:
174 | name: ansicolor
175 | url: "https://pub.dartlang.org"
176 | source: hosted
177 | version: "0.0.9"
178 | args:
179 | description:
180 | name: args
181 | url: "https://pub.dartlang.org"
182 | source: hosted
183 | version: "0.13.7"
184 | async:
185 | description:
186 | name: async
187 | url: "https://pub.dartlang.org"
188 | source: hosted
189 | version: "1.13.3"
190 | barback:
191 | description:
192 | name: barback
193 | url: "https://pub.dartlang.org"
194 | source: hosted
195 | version: "0.15.2+11"
196 | body_parser:
197 | description:
198 | name: body_parser
199 | url: "https://pub.dartlang.org"
200 | source: hosted
201 | version: "1.0.2"
202 | boolean_selector:
203 | description:
204 | name: boolean_selector
205 | url: "https://pub.dartlang.org"
206 | source: hosted
207 | version: "1.0.2"
208 | bson:
209 | description:
210 | name: bson
211 | url: "https://pub.dartlang.org"
212 | source: hosted
213 | version: "0.2.0"
214 | charcode:
215 | description:
216 | name: charcode
217 | url: "https://pub.dartlang.org"
218 | source: hosted
219 | version: "1.1.1"
220 | cli_util:
221 | description:
222 | name: cli_util
223 | url: "https://pub.dartlang.org"
224 | source: hosted
225 | version: "0.1.2"
226 | collection:
227 | description:
228 | name: collection
229 | url: "https://pub.dartlang.org"
230 | source: hosted
231 | version: "1.14.3"
232 | common:
233 | description:
234 | path: "..\\common"
235 | relative: true
236 | source: path
237 | version: "0.0.0"
238 | console:
239 | description:
240 | name: console
241 | url: "https://pub.dartlang.org"
242 | source: hosted
243 | version: "2.2.4"
244 | container:
245 | description:
246 | name: container
247 | url: "https://pub.dartlang.org"
248 | source: hosted
249 | version: "0.1.2"
250 | convert:
251 | description:
252 | name: convert
253 | url: "https://pub.dartlang.org"
254 | source: hosted
255 | version: "2.0.1"
256 | crypto:
257 | description:
258 | name: crypto
259 | url: "https://pub.dartlang.org"
260 | source: hosted
261 | version: "2.0.2"
262 | csslib:
263 | description:
264 | name: csslib
265 | url: "https://pub.dartlang.org"
266 | source: hosted
267 | version: "0.14.0"
268 | dotenv:
269 | description:
270 | name: dotenv
271 | url: "https://pub.dartlang.org"
272 | source: hosted
273 | version: "0.1.3+3"
274 | faker:
275 | description:
276 | name: faker
277 | url: "https://pub.dartlang.org"
278 | source: hosted
279 | version: "0.0.5"
280 | fixnum:
281 | description:
282 | name: fixnum
283 | url: "https://pub.dartlang.org"
284 | source: hosted
285 | version: "0.10.6"
286 | flatten:
287 | description:
288 | name: flatten
289 | url: "https://pub.dartlang.org"
290 | source: hosted
291 | version: "1.0.0"
292 | fnx_profiler:
293 | description:
294 | name: fnx_profiler
295 | url: "https://pub.dartlang.org"
296 | source: hosted
297 | version: "0.9.1"
298 | front_end:
299 | description:
300 | name: front_end
301 | url: "https://pub.dartlang.org"
302 | source: hosted
303 | version: "0.1.0-alpha.4"
304 | glob:
305 | description:
306 | name: glob
307 | url: "https://pub.dartlang.org"
308 | source: hosted
309 | version: "1.1.3"
310 | googleapis:
311 | description:
312 | name: googleapis
313 | url: "https://pub.dartlang.org"
314 | source: hosted
315 | version: "0.32.0"
316 | googleapis_auth:
317 | description:
318 | name: googleapis_auth
319 | url: "https://pub.dartlang.org"
320 | source: hosted
321 | version: "0.2.3+6"
322 | grinder:
323 | description:
324 | name: grinder
325 | url: "https://pub.dartlang.org"
326 | source: hosted
327 | version: "0.8.0+3"
328 | html:
329 | description:
330 | name: html
331 | url: "https://pub.dartlang.org"
332 | source: hosted
333 | version: "0.13.2"
334 | html_builder:
335 | description:
336 | name: html_builder
337 | url: "https://pub.dartlang.org"
338 | source: hosted
339 | version: "1.0.1"
340 | http:
341 | description:
342 | name: http
343 | url: "https://pub.dartlang.org"
344 | source: hosted
345 | version: "0.11.3+14"
346 | http_multi_server:
347 | description:
348 | name: http_multi_server
349 | url: "https://pub.dartlang.org"
350 | source: hosted
351 | version: "2.0.3"
352 | http_parser:
353 | description:
354 | name: http_parser
355 | url: "https://pub.dartlang.org"
356 | source: hosted
357 | version: "3.1.1"
358 | http_server:
359 | description:
360 | name: http_server
361 | url: "https://pub.dartlang.org"
362 | source: hosted
363 | version: "0.9.6"
364 | intl:
365 | description:
366 | name: intl
367 | url: "https://pub.dartlang.org"
368 | source: hosted
369 | version: "0.15.0"
370 | isolate:
371 | description:
372 | name: isolate
373 | url: "https://pub.dartlang.org"
374 | source: hosted
375 | version: "1.0.0"
376 | js:
377 | description:
378 | name: js
379 | url: "https://pub.dartlang.org"
380 | source: hosted
381 | version: "0.6.1"
382 | json_god:
383 | description:
384 | name: json_god
385 | url: "https://pub.dartlang.org"
386 | source: hosted
387 | version: "2.0.0-beta+1"
388 | json_rpc_2:
389 | description:
390 | name: json_rpc_2
391 | url: "https://pub.dartlang.org"
392 | source: hosted
393 | version: "2.0.4"
394 | kernel:
395 | description:
396 | name: kernel
397 | url: "https://pub.dartlang.org"
398 | source: hosted
399 | version: "0.3.0-alpha.1"
400 | logging:
401 | description:
402 | name: logging
403 | url: "https://pub.dartlang.org"
404 | source: hosted
405 | version: "0.11.3+1"
406 | matcher:
407 | description:
408 | name: matcher
409 | url: "https://pub.dartlang.org"
410 | source: hosted
411 | version: "0.12.1+1"
412 | memcached_client:
413 | description:
414 | name: memcached_client
415 | url: "https://pub.dartlang.org"
416 | source: hosted
417 | version: "0.5.3"
418 | merge_map:
419 | description:
420 | name: merge_map
421 | url: "https://pub.dartlang.org"
422 | source: hosted
423 | version: "1.0.0"
424 | meta:
425 | description:
426 | name: meta
427 | url: "https://pub.dartlang.org"
428 | source: hosted
429 | version: "1.1.1"
430 | mime:
431 | description:
432 | name: mime
433 | url: "https://pub.dartlang.org"
434 | source: hosted
435 | version: "0.9.3"
436 | mock_request:
437 | description:
438 | name: mock_request
439 | url: "https://pub.dartlang.org"
440 | source: hosted
441 | version: "1.0.2"
442 | mockable_filesystem:
443 | description:
444 | name: mockable_filesystem
445 | url: "https://pub.dartlang.org"
446 | source: hosted
447 | version: "0.0.3"
448 | mongo_dart:
449 | description:
450 | name: mongo_dart
451 | url: "https://pub.dartlang.org"
452 | source: hosted
453 | version: "0.2.10"
454 | mongo_dart_query:
455 | description:
456 | name: mongo_dart_query
457 | url: "https://pub.dartlang.org"
458 | source: hosted
459 | version: "0.2.2"
460 | more:
461 | description:
462 | name: more
463 | url: "https://pub.dartlang.org"
464 | source: hosted
465 | version: "1.6.0"
466 | mustache4dart:
467 | description:
468 | name: mustache4dart
469 | url: "https://pub.dartlang.org"
470 | source: hosted
471 | version: "1.1.0"
472 | node_preamble:
473 | description:
474 | name: node_preamble
475 | url: "https://pub.dartlang.org"
476 | source: hosted
477 | version: "1.4.0"
478 | package_config:
479 | description:
480 | name: package_config
481 | url: "https://pub.dartlang.org"
482 | source: hosted
483 | version: "1.0.2"
484 | package_resolver:
485 | description:
486 | name: package_resolver
487 | url: "https://pub.dartlang.org"
488 | source: hosted
489 | version: "1.0.2"
490 | path:
491 | description:
492 | name: path
493 | url: "https://pub.dartlang.org"
494 | source: hosted
495 | version: "1.4.2"
496 | plugin:
497 | description:
498 | name: plugin
499 | url: "https://pub.dartlang.org"
500 | source: hosted
501 | version: "0.2.0+1"
502 | pool:
503 | description:
504 | name: pool
505 | url: "https://pub.dartlang.org"
506 | source: hosted
507 | version: "1.3.1"
508 | pub_semver:
509 | description:
510 | name: pub_semver
511 | url: "https://pub.dartlang.org"
512 | source: hosted
513 | version: "1.3.2"
514 | quiver:
515 | description:
516 | name: quiver
517 | url: "https://pub.dartlang.org"
518 | source: hosted
519 | version: "0.22.0"
520 | random_string:
521 | description:
522 | name: random_string
523 | url: "https://pub.dartlang.org"
524 | source: hosted
525 | version: "0.0.1"
526 | redis_client:
527 | description:
528 | name: redis_client
529 | url: "https://pub.dartlang.org"
530 | source: hosted
531 | version: "0.1.16"
532 | shelf:
533 | description:
534 | name: shelf
535 | url: "https://pub.dartlang.org"
536 | source: hosted
537 | version: "0.6.8"
538 | shelf_packages_handler:
539 | description:
540 | name: shelf_packages_handler
541 | url: "https://pub.dartlang.org"
542 | source: hosted
543 | version: "1.0.0"
544 | shelf_static:
545 | description:
546 | name: shelf_static
547 | url: "https://pub.dartlang.org"
548 | source: hosted
549 | version: "0.2.5"
550 | shelf_web_socket:
551 | description:
552 | name: shelf_web_socket
553 | url: "https://pub.dartlang.org"
554 | source: hosted
555 | version: "0.2.1"
556 | source_map_stack_trace:
557 | description:
558 | name: source_map_stack_trace
559 | url: "https://pub.dartlang.org"
560 | source: hosted
561 | version: "1.1.4"
562 | source_maps:
563 | description:
564 | name: source_maps
565 | url: "https://pub.dartlang.org"
566 | source: hosted
567 | version: "0.10.4"
568 | source_span:
569 | description:
570 | name: source_span
571 | url: "https://pub.dartlang.org"
572 | source: hosted
573 | version: "1.4.0"
574 | stack_trace:
575 | description:
576 | name: stack_trace
577 | url: "https://pub.dartlang.org"
578 | source: hosted
579 | version: "1.8.0"
580 | stream_channel:
581 | description:
582 | name: stream_channel
583 | url: "https://pub.dartlang.org"
584 | source: hosted
585 | version: "1.6.1"
586 | string_scanner:
587 | description:
588 | name: string_scanner
589 | url: "https://pub.dartlang.org"
590 | source: hosted
591 | version: "1.0.2"
592 | supports_color:
593 | description:
594 | name: supports_color
595 | url: "https://pub.dartlang.org"
596 | source: hosted
597 | version: "0.1.1"
598 | term_glyph:
599 | description:
600 | name: term_glyph
601 | url: "https://pub.dartlang.org"
602 | source: hosted
603 | version: "1.0.0"
604 | test:
605 | description:
606 | name: test
607 | url: "https://pub.dartlang.org"
608 | source: hosted
609 | version: "0.12.24"
610 | typed_data:
611 | description:
612 | name: typed_data
613 | url: "https://pub.dartlang.org"
614 | source: hosted
615 | version: "1.1.3"
616 | unscripted:
617 | description:
618 | name: unscripted
619 | url: "https://pub.dartlang.org"
620 | source: hosted
621 | version: "0.6.2"
622 | utf:
623 | description:
624 | name: utf
625 | url: "https://pub.dartlang.org"
626 | source: hosted
627 | version: "0.9.0+3"
628 | uuid:
629 | description:
630 | name: uuid
631 | url: "https://pub.dartlang.org"
632 | source: hosted
633 | version: "0.5.3"
634 | vector_math:
635 | description:
636 | name: vector_math
637 | url: "https://pub.dartlang.org"
638 | source: hosted
639 | version: "1.4.7"
640 | vm_service_client:
641 | description:
642 | ref: reload_sources_poc
643 | resolved-ref: f607e69ef7c34e5503ff92719b7a96a390c6cdf2
644 | url: "git://github.com/BlackHC/vm_service_client.git"
645 | source: git
646 | version: "0.2.4"
647 | watcher:
648 | description:
649 | name: watcher
650 | url: "https://pub.dartlang.org"
651 | source: hosted
652 | version: "0.9.7+3"
653 | web_socket_channel:
654 | description:
655 | name: web_socket_channel
656 | url: "https://pub.dartlang.org"
657 | source: hosted
658 | version: "1.0.4"
659 | yaml:
660 | description:
661 | name: yaml
662 | url: "https://pub.dartlang.org"
663 | source: hosted
664 | version: "2.1.12"
665 | sdks:
666 | dart: ">=1.23.0 <2.0.0-dev.infinity"
667 |
--------------------------------------------------------------------------------
/server/pubspec.yaml:
--------------------------------------------------------------------------------
1 | description: "An easily-extensible web server framework in Dart."
2 | homepage: "https://github.com/angel-dart/angel"
3 | name: "server"
4 | publish_to: "none"
5 | dependencies:
6 | angel_auth_google: ^1.0.0
7 | angel_common: "^1.0.0"
8 | angel_configuration: "^1.0.0"
9 | angel_hot: "^1.0.0-rc.1"
10 | angel_multiserver: "^1.0.0"
11 | angel_seeder: ^1.0.0
12 | angel_security: ^1.0.0
13 | angel_websocket: ^1.0.0
14 | common:
15 | path: ../common
16 | dev_dependencies:
17 | grinder: "^0.8.0"
18 | http: "^0.11.3"
19 | test: "^0.12.13"
20 | environment:
21 | sdk: ">=1.19.0"
22 | transformers:
23 | - "angel_configuration"
24 |
--------------------------------------------------------------------------------
/server/server.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/server/test/services/message_test.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'package:server/server.dart';
3 | import 'package:angel_common/angel_common.dart';
4 | import 'package:angel_test/angel_test.dart';
5 | import 'package:test/test.dart';
6 |
7 | main() async {
8 | Angel app;
9 | TestClient client;
10 |
11 | setUp(() async {
12 | app = await createServer();
13 | client = await connectTo(app);
14 | });
15 |
16 | tearDown(() async {
17 | await client.close();
18 | app = null;
19 | });
20 |
21 | test('index via REST', () async {
22 | var response = await client.get('/api/messages');
23 | expect(response, hasStatus(HttpStatus.OK));
24 | });
25 |
26 | test('Index messages', () async {
27 | var messages = await client.service('api/messages').index();
28 | print(messages);
29 | });
30 | }
--------------------------------------------------------------------------------
/server/test/services/todo_test.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'package:server/server.dart';
3 | import 'package:angel_common/angel_common.dart';
4 | import 'package:angel_test/angel_test.dart';
5 | import 'package:test/test.dart';
6 |
7 | main() async {
8 | Angel app;
9 | TestClient client;
10 |
11 | setUp(() async {
12 | app = await createServer();
13 | client = await connectTo(app);
14 | });
15 |
16 | tearDown(() async {
17 | await client.close();
18 | app = null;
19 | });
20 |
21 | test('index via REST', () async {
22 | var response = await client.get('/api/todos');
23 | expect(response, hasStatus(HttpStatus.OK));
24 | });
25 |
26 | test('Index todos', () async {
27 | var todos = await client.service('api/todos').index();
28 | print(todos);
29 | });
30 | }
--------------------------------------------------------------------------------
/server/test/services/users_test.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'package:server/server.dart';
3 | import 'package:angel_test/angel_test.dart';
4 | import 'package:test/test.dart';
5 |
6 | // Angel also includes facilities to make testing easier.
7 | //
8 | // `package:angel_test` ships a client that can test
9 | // both plain HTTP and WebSockets.
10 | //
11 | // Tests do not require your server to actually be mounted on a port,
12 | // so they will run faster than they would in other frameworks, where you
13 | // would have to first bind a socket, and then account for network latency.
14 | //
15 | // See the documentation here:
16 | // https://github.com/angel-dart/test
17 | //
18 | // If you are unfamiliar with Dart's advanced testing library, you can read up
19 | // here:
20 | // https://github.com/dart-lang/test
21 |
22 | main() async {
23 | TestClient client;
24 |
25 | setUp(() async {
26 | var app = await createServer();
27 | client = await connectTo(app);
28 | });
29 |
30 | tearDown(() async {
31 | await client.close();
32 | });
33 |
34 | test('index users', () async {
35 | // Request a resource at the given path.
36 | var response = await client.get('/api/users');
37 |
38 | // By default, we locked this away from the Internet...
39 | // Expect a 403 response.
40 | expect(response, hasStatus(HttpStatus.FORBIDDEN));
41 | });
42 | }
43 |
--------------------------------------------------------------------------------
/server/tool/grind.dart:
--------------------------------------------------------------------------------
1 | // Grinder is not part of Angel, but you may consider using it
2 | // to run tasks, a la Gulp.
3 | //
4 | // See its documentation here:
5 | // https://github.com/google/grinder.dart
6 |
7 | import 'package:grinder/grinder.dart';
8 |
9 | main(args) => grind(args);
10 |
11 | @Task()
12 | test() => new TestRunner().testAsync();
13 |
14 | @DefaultTask()
15 | @Depends(test)
16 | build() {
17 | Pub.build();
18 | }
19 |
20 | @Task()
21 | clean() => defaultClean();
--------------------------------------------------------------------------------
/server/views/error.mustache:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Error
5 |
6 |
7 |
8 |
9 |
42 |
43 |
44 |
49 |
50 |
--------------------------------------------------------------------------------
/server/views/hello.mustache:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Angel
5 |
6 |
7 |
8 |
9 |
38 |
39 |
40 |
45 |
46 |
--------------------------------------------------------------------------------
/server/web/images/dart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/server/web/images/dart.png
--------------------------------------------------------------------------------
/server/web/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/server/web/images/favicon.png
--------------------------------------------------------------------------------
/server/web/images/flutter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/server/web/images/flutter.jpg
--------------------------------------------------------------------------------
/server/web/images/google.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angel-example/flutter/86cf10ae589df74a88d494f2efb901453bca9b29/server/web/images/google.png
--------------------------------------------------------------------------------
/server/web/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /admin
--------------------------------------------------------------------------------