├── server
├── bin
│ ├── src
│ │ └── main
│ │ │ └── resources
│ │ │ └── application.properties
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── .gitignore
│ ├── pom.xml
│ ├── mvnw.cmd
│ └── mvnw
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── .gitignore
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── rowan
│ │ │ │ └── ruber
│ │ │ │ ├── Utils.java
│ │ │ │ ├── RuberApplication.java
│ │ │ │ ├── model
│ │ │ │ ├── SortByDay.java
│ │ │ │ ├── google_maps
│ │ │ │ │ ├── Location.java
│ │ │ │ │ ├── Northeast.java
│ │ │ │ │ ├── Southwest.java
│ │ │ │ │ ├── Viewport.java
│ │ │ │ │ ├── Bounds.java
│ │ │ │ │ ├── GeoencodingResult.java
│ │ │ │ │ ├── AddressComponent.java
│ │ │ │ │ ├── Geometry.java
│ │ │ │ │ └── Result.java
│ │ │ │ ├── Day.java
│ │ │ │ ├── Message.java
│ │ │ │ ├── Chatroom.java
│ │ │ │ ├── Address.java
│ │ │ │ ├── Profile.java
│ │ │ │ └── Schedule.java
│ │ │ │ ├── repository
│ │ │ │ ├── AddressRepository.java
│ │ │ │ ├── MessageRepository.java
│ │ │ │ ├── ChatroomRepository.java
│ │ │ │ ├── ScheduleRepository.java
│ │ │ │ └── ProfileRepository.java
│ │ │ │ ├── io
│ │ │ │ └── HelloController.java
│ │ │ │ ├── MapsManager.java
│ │ │ │ ├── Authenticator.java
│ │ │ │ ├── Ids.java
│ │ │ │ └── Search.java
│ │ └── resources
│ │ │ └── application.properties
│ └── test
│ │ └── java
│ │ └── com
│ │ └── rowan
│ │ └── ruber
│ │ └── RuberApplicationTests.java
├── pom.xml
├── mvnw.cmd
└── mvnw
├── ruber
├── android
│ ├── gradle.properties
│ ├── app
│ │ ├── src
│ │ │ └── main
│ │ │ │ ├── web_hi_res_512.png
│ │ │ │ ├── res
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── rowanuniversity.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── rowanuniversity.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── rowanuniversity.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── rowanuniversity.png
│ │ │ │ ├── values
│ │ │ │ │ └── styles.xml
│ │ │ │ └── drawable
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── gen
│ │ │ │ └── com
│ │ │ │ │ └── ruber
│ │ │ │ │ └── ruber
│ │ │ │ │ ├── R.java
│ │ │ │ │ ├── Manifest.java
│ │ │ │ │ └── BuildConfig.java
│ │ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── ruber
│ │ │ │ │ └── ruber
│ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── AndroidManifest.xml
│ │ ├── google-services.json
│ │ └── build.gradle
│ ├── .gitignore
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ ├── settings.gradle
│ └── build.gradle
├── ios
│ ├── Flutter
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ └── AppFrameworkInfo.plist
│ ├── Runner
│ │ ├── Runner-Bridging-Header.h
│ │ ├── Assets.xcassets
│ │ │ ├── LaunchImage.imageset
│ │ │ │ ├── LaunchImage.png
│ │ │ │ ├── LaunchImage@2x.png
│ │ │ │ ├── LaunchImage@3x.png
│ │ │ │ ├── README.md
│ │ │ │ └── Contents.json
│ │ │ └── AppIcon.appiconset
│ │ │ │ ├── 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-1024x1024@1x.png
│ │ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ │ └── Contents.json
│ │ ├── AppDelegate.swift
│ │ ├── Base.lproj
│ │ │ ├── Main.storyboard
│ │ │ └── LaunchScreen.storyboard
│ │ └── Info.plist
│ ├── Runner.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── Runner.xcodeproj
│ │ ├── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ └── .gitignore
├── assets
│ ├── RowanCampus.jpg
│ ├── fonts
│ │ ├── Bungee-Regular.ttf
│ │ ├── Heebo-Regular.ttf
│ │ ├── Roboto-Regular.ttf
│ │ ├── Audiowide-Regular.ttf
│ │ ├── BungeeShade-Regular.ttf
│ │ └── BungeeInline-Regular.ttf
│ └── User_Structure.json
├── .gitignore
├── images
│ └── rowanuniversity.png
├── README.md
├── .metadata
├── lib
│ ├── Constants.dart
│ ├── UserModel.dart
│ ├── AddressPostModel.dart
│ ├── MessageModel.dart
│ ├── GoingToRowan.dart
│ ├── ScheduleModel.dart
│ ├── AddressModel.dart
│ ├── RideScreen.dart
│ ├── AppDrawer.dart
│ ├── ProfileModel.dart
│ ├── ChatroomModel.dart
│ ├── Main.dart
│ ├── matches_screen.dart
│ ├── AuthScreen.dart
│ ├── initialaddaddress.dart
│ └── ChatRoomScreen.dart
└── pubspec.yaml
├── Ryde.mp4
├── Design Document.pdf
├── Ryde User Manual.pdf
├── Fall 2018 Senior Project Final Presentation - Ryde.pdf
├── ISSUES.txt
├── README.md
└── .gitignore
/server/bin/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ruber/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/ruber/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ruber/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ruber/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
--------------------------------------------------------------------------------
/Ryde.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/Ryde.mp4
--------------------------------------------------------------------------------
/Design Document.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/Design Document.pdf
--------------------------------------------------------------------------------
/Ryde User Manual.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/Ryde User Manual.pdf
--------------------------------------------------------------------------------
/ruber/assets/RowanCampus.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/assets/RowanCampus.jpg
--------------------------------------------------------------------------------
/ruber/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 |
9 | .flutter-plugins
10 |
--------------------------------------------------------------------------------
/ruber/images/rowanuniversity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/images/rowanuniversity.png
--------------------------------------------------------------------------------
/ruber/assets/fonts/Bungee-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/assets/fonts/Bungee-Regular.ttf
--------------------------------------------------------------------------------
/ruber/assets/fonts/Heebo-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/assets/fonts/Heebo-Regular.ttf
--------------------------------------------------------------------------------
/ruber/assets/fonts/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/assets/fonts/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/server/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/server/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/ruber/assets/fonts/Audiowide-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/assets/fonts/Audiowide-Regular.ttf
--------------------------------------------------------------------------------
/ruber/assets/fonts/BungeeShade-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/assets/fonts/BungeeShade-Regular.ttf
--------------------------------------------------------------------------------
/server/bin/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/server/bin/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/ruber/assets/fonts/BungeeInline-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/assets/fonts/BungeeInline-Regular.ttf
--------------------------------------------------------------------------------
/ruber/android/app/src/main/web_hi_res_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/android/app/src/main/web_hi_res_512.png
--------------------------------------------------------------------------------
/server/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
2 |
--------------------------------------------------------------------------------
/server/bin/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
2 |
--------------------------------------------------------------------------------
/Fall 2018 Senior Project Final Presentation - Ryde.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/Fall 2018 Senior Project Final Presentation - Ryde.pdf
--------------------------------------------------------------------------------
/ruber/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ruber/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ruber/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ruber/README.md:
--------------------------------------------------------------------------------
1 | # ruber
2 |
3 | Rowan Carpool
4 |
5 | ## Getting Started
6 |
7 | For help getting started with Flutter, view our online
8 | [documentation](https://flutter.io/).
9 |
--------------------------------------------------------------------------------
/ruber/android/app/src/main/res/mipmap-hdpi/rowanuniversity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/android/app/src/main/res/mipmap-hdpi/rowanuniversity.png
--------------------------------------------------------------------------------
/ruber/android/app/src/main/res/mipmap-mdpi/rowanuniversity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/android/app/src/main/res/mipmap-mdpi/rowanuniversity.png
--------------------------------------------------------------------------------
/ruber/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ruber/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ruber/android/app/src/main/res/mipmap-xxhdpi/rowanuniversity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/android/app/src/main/res/mipmap-xxhdpi/rowanuniversity.png
--------------------------------------------------------------------------------
/ruber/android/app/src/main/res/mipmap-xxxhdpi/rowanuniversity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/android/app/src/main/res/mipmap-xxxhdpi/rowanuniversity.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ruber/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | *.class
3 | .gradle
4 | /local.properties
5 | /.idea/workspace.xml
6 | /.idea/libraries
7 | .DS_Store
8 | /build
9 | /captures
10 | GeneratedPluginRegistrant.java
11 |
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TylerCarberry/RowanRideshare/HEAD/ruber/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ruber/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ruber/android/app/src/main/gen/com/ruber/ruber/R.java:
--------------------------------------------------------------------------------
1 | /*___Generated_by_IDEA___*/
2 |
3 | package com.ruber.ruber;
4 |
5 | /* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
6 | public final class R {
7 | }
--------------------------------------------------------------------------------
/ruber/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ruber/android/app/src/main/gen/com/ruber/ruber/Manifest.java:
--------------------------------------------------------------------------------
1 | /*___Generated_by_IDEA___*/
2 |
3 | package com.ruber.ruber;
4 |
5 | /* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
6 | public final class Manifest {
7 | }
--------------------------------------------------------------------------------
/ruber/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/ruber/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 5ab9e70727d858def3a586db7fb98ee580352957
8 | channel: beta
9 |
--------------------------------------------------------------------------------
/ISSUES.txt:
--------------------------------------------------------------------------------
1 | Here are a list of existing bugs/issues:
2 |
3 | 1.The Schedule button on the home screen does not show the current schedule.
4 | -Ideally we show the schedule itself much like we show the address in Edit Address (with hint text).
5 | -Or we can show the schedule in another format with a brand new widget (not recommended).
6 |
--------------------------------------------------------------------------------
/ruber/android/app/src/main/gen/com/ruber/ruber/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /*___Generated_by_IDEA___*/
2 |
3 | package com.ruber.ruber;
4 |
5 | /* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
6 | public final class BuildConfig {
7 | public final static boolean DEBUG = Boolean.parseBoolean(null);
8 | }
--------------------------------------------------------------------------------
/ruber/assets/User_Structure.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 1,
3 | "name": "Firstname Lastname",
4 | "email": "firstnamel0@students.rowan.edu",
5 | "address": {
6 | "id": 1,
7 | "streetAddress": "201 Mullica Hill Road",
8 | "city": "Glassboro",
9 | "zipCode": "08028",
10 | "state": "NJ",
11 | "latitude": 39.70779,
12 | "longitude": -75.11383
13 | },
14 | "createdDate": "2018-10-28",
15 | "schedules": []
16 | }
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/server/bin/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/Utils.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.InputStream;
5 | import java.nio.charset.Charset;
6 |
7 | public class Utils {
8 |
9 | public static InputStream convertStringToStream(String str) {
10 | return new ByteArrayInputStream(str.getBytes(Charset.defaultCharset()));
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/RuberApplication.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class RuberApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(RuberApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ruber/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/SortByDay.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.model;
2 |
3 | import java.util.Comparator;
4 |
5 | public class SortByDay implements Comparator {
6 | // Used for sorting in ascending order of
7 | // roll number
8 | public int compare(Schedule a, Schedule b)
9 | {
10 | return a.getDay().compareTo(b.getDay());
11 | }
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/repository/AddressRepository.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.repository;
2 |
3 | import org.springframework.data.repository.CrudRepository;
4 |
5 | import com.rowan.ruber.model.Address;
6 |
7 | // This will be AUTO IMPLEMENTED by Spring into a Bean called addressRepository
8 | // CRUD refers Create, Read, Update, Delete
9 | public interface AddressRepository extends CrudRepository {
10 | }
--------------------------------------------------------------------------------
/ruber/android/app/src/main/kotlin/com/ruber/ruber/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.ruber.ruber
2 |
3 | import android.os.Bundle
4 |
5 | import io.flutter.app.FlutterActivity
6 | import io.flutter.plugins.GeneratedPluginRegistrant
7 |
8 | class MainActivity(): FlutterActivity() {
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | GeneratedPluginRegistrant.registerWith(this)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/repository/MessageRepository.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.repository;
2 |
3 | import org.springframework.data.repository.CrudRepository;
4 | import com.rowan.ruber.model.Message;
5 |
6 | // This will be AUTO IMPLEMENTED by Spring into a Bean called messageRepository in the RuberController
7 | // CRUD refers Create, Read, Update, Delete
8 | public interface MessageRepository extends CrudRepository {
9 |
10 | }
--------------------------------------------------------------------------------
/server/src/test/java/com/rowan/ruber/RuberApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class RuberApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/repository/ChatroomRepository.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.repository;
2 |
3 | import org.springframework.data.repository.CrudRepository;
4 | import com.rowan.ruber.model.Chatroom;
5 |
6 | // This will be AUTO IMPLEMENTED by Spring into a Bean called chatroomRepository in the RuberController
7 | // CRUD refers Create, Read, Update, Delete
8 | public interface ChatroomRepository extends CrudRepository {
9 |
10 | }
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/repository/ScheduleRepository.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.repository;
2 |
3 | import org.springframework.data.repository.CrudRepository;
4 | import com.rowan.ruber.model.Schedule;
5 |
6 | // This will be AUTO IMPLEMENTED by Spring into a Bean called scheduleRepository in the RuberController
7 | // CRUD refers Create, Read, Update, Delete
8 | public interface ScheduleRepository extends CrudRepository {
9 |
10 | }
--------------------------------------------------------------------------------
/ruber/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/server/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.jpa.hibernate.ddl-auto=none
2 | spring.datasource.url=jdbc:mysql://ec2-34-230-33-210.compute-1.amazonaws.com:3306/rideshare
3 | spring.datasource.username=user
4 | spring.datasource.password=Rideshare@2018
5 | spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
6 | spring.jackson.serialization.indent_output=true
7 | spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/io/HelloController.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.io;
2 |
3 | import org.springframework.web.bind.annotation.*;
4 |
5 | /**
6 | * A test controller to make sure the server is running
7 | */
8 | @RequestMapping("/hello")
9 | @RestController
10 | public class HelloController {
11 |
12 | @GetMapping("/greeting")
13 | public String index(@RequestParam(name="name", required=false, defaultValue="World") String name) {
14 | return "Hello, " + name + "!";
15 | }
16 | }
--------------------------------------------------------------------------------
/ruber/lib/Constants.dart:
--------------------------------------------------------------------------------
1 | /// Constants.dart
2 | ///
3 | /// Purpose:
4 | /// This file is used to define the URL for the back end server -- AWS's URL
5 | /// Additional URLs are provided for testing and ngrok
6 |
7 |
8 | // If you want to use your AWS instead of your local server, uncomment this line
9 | final String BASE_URL = "http://ec2-34-230-33-210.compute-1.amazonaws.com:8080";
10 |
11 | //final String BASE_URL = "http://10.0.2.2:8080";
12 |
13 | //if you need ngrok
14 | //final String BASE_URL = "http://61b5267a.ngrok.io";
15 |
--------------------------------------------------------------------------------
/ruber/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/google_maps/Location.java:
--------------------------------------------------------------------------------
1 |
2 | package com.rowan.ruber.model.google_maps;
3 |
4 | public class Location {
5 |
6 | private Double lat;
7 | private Double lng;
8 |
9 | public Double getLat() {
10 | return lat;
11 | }
12 |
13 | public void setLat(Double lat) {
14 | this.lat = lat;
15 | }
16 |
17 | public Double getLng() {
18 | return lng;
19 | }
20 |
21 | public void setLng(Double lng) {
22 | this.lng = lng;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/google_maps/Northeast.java:
--------------------------------------------------------------------------------
1 |
2 | package com.rowan.ruber.model.google_maps;
3 |
4 | public class Northeast {
5 |
6 | private Double lat;
7 | private Double lng;
8 |
9 | public Double getLat() {
10 | return lat;
11 | }
12 |
13 | public void setLat(Double lat) {
14 | this.lat = lat;
15 | }
16 |
17 | public Double getLng() {
18 | return lng;
19 | }
20 |
21 | public void setLng(Double lng) {
22 | this.lng = lng;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/google_maps/Southwest.java:
--------------------------------------------------------------------------------
1 |
2 | package com.rowan.ruber.model.google_maps;
3 |
4 | public class Southwest {
5 |
6 | private Double lat;
7 | private Double lng;
8 |
9 | public Double getLat() {
10 | return lat;
11 | }
12 |
13 | public void setLat(Double lat) {
14 | this.lat = lat;
15 | }
16 |
17 | public Double getLng() {
18 | return lng;
19 | }
20 |
21 | public void setLng(Double lng) {
22 | this.lng = lng;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/ruber/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ruber/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.withReader('UTF-8') { reader -> plugins.load(reader) }
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 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/google_maps/Viewport.java:
--------------------------------------------------------------------------------
1 |
2 | package com.rowan.ruber.model.google_maps;
3 |
4 | public class Viewport {
5 |
6 | private Northeast northeast;
7 | private Southwest southwest;
8 |
9 | public Northeast getNortheast() {
10 | return northeast;
11 | }
12 |
13 | public void setNortheast(Northeast northeast) {
14 | this.northeast = northeast;
15 | }
16 |
17 | public Southwest getSouthwest() {
18 | return southwest;
19 | }
20 |
21 | public void setSouthwest(Southwest southwest) {
22 | this.southwest = southwest;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/repository/ProfileRepository.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.repository;
2 |
3 | import org.jboss.logging.Param;
4 | import org.springframework.data.jpa.repository.Query;
5 | import org.springframework.data.repository.CrudRepository;
6 |
7 | import java.util.Optional;
8 |
9 | import com.rowan.ruber.model.Profile;
10 |
11 | // This will be AUTO IMPLEMENTED by Spring into a Bean called profileRepository in the RuberController
12 | // CRUD refers Create, Read, Update, Delete
13 | public interface ProfileRepository extends CrudRepository {
14 |
15 | public Optional findByEmailAddress(String emailAddress);
16 | }
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/google_maps/Bounds.java:
--------------------------------------------------------------------------------
1 |
2 | package com.rowan.ruber.model.google_maps;
3 |
4 | public class Bounds {
5 |
6 | private Northeast northeast;
7 | private Southwest southwest;
8 |
9 | public Bounds() {
10 | }
11 |
12 | public Northeast getNortheast() {
13 | return northeast;
14 | }
15 |
16 | public void setNortheast(Northeast northeast) {
17 | this.northeast = northeast;
18 | }
19 |
20 | public Southwest getSouthwest() {
21 | return southwest;
22 | }
23 |
24 | public void setSouthwest(Southwest southwest) {
25 | this.southwest = southwest;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/ruber/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 | .generated/
16 |
17 | *.pbxuser
18 | *.mode1v3
19 | *.mode2v3
20 | *.perspectivev3
21 |
22 | !default.pbxuser
23 | !default.mode1v3
24 | !default.mode2v3
25 | !default.perspectivev3
26 |
27 | xcuserdata
28 |
29 | *.moved-aside
30 |
31 | *.pyc
32 | *sync/
33 | Icon?
34 | .tags*
35 |
36 | /Flutter/app.flx
37 | /Flutter/app.zip
38 | /Flutter/flutter_assets/
39 | /Flutter/App.framework
40 | /Flutter/Flutter.framework
41 | /Flutter/Generated.xcconfig
42 | /ServiceDefinitions.json
43 |
44 | Pods/
45 | .symlinks/
46 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/google_maps/GeoencodingResult.java:
--------------------------------------------------------------------------------
1 |
2 | package com.rowan.ruber.model.google_maps;
3 |
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | /**
8 | * Result from the Google Maps Geoencoding API that converts a string address to latitude and longitude
9 | */
10 | public class GeoencodingResult {
11 |
12 | private List results;
13 | private String status;
14 |
15 | public GeoencodingResult() {
16 | results = new ArrayList<>();
17 | }
18 |
19 | public List getResults() {
20 | return results;
21 | }
22 |
23 | public void setResults(List results) {
24 | this.results = results;
25 | }
26 |
27 | public String getStatus() {
28 | return status;
29 | }
30 |
31 | public void setStatus(String status) {
32 | this.status = status;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/ruber/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 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/google_maps/AddressComponent.java:
--------------------------------------------------------------------------------
1 |
2 | package com.rowan.ruber.model.google_maps;
3 |
4 | import java.util.List;
5 |
6 | public class AddressComponent {
7 |
8 | private String longName;
9 | private String shortName;
10 | private List types;
11 |
12 | public AddressComponent() {
13 | }
14 |
15 | public String getLongName() {
16 | return longName;
17 | }
18 |
19 | public void setLongName(String longName) {
20 | this.longName = longName;
21 | }
22 |
23 | public String getShortName() {
24 | return shortName;
25 | }
26 |
27 | public void setShortName(String shortName) {
28 | this.shortName = shortName;
29 | }
30 |
31 | public List getTypes() {
32 | return types;
33 | }
34 |
35 | public void setTypes(List types) {
36 | this.types = types;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/ruber/lib/UserModel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | //Takes in a NewUser object and returns a JSON String
4 | String userToJson(NewUser data) {
5 | final dyn = data.toJson();
6 | return json.encode(dyn);
7 | }
8 |
9 | //Takes in a JSON String and converts it to a NewUser object
10 | NewUser userFromJson(String str) {
11 | final jsonData = json.decode(str);
12 | return NewUser.fromJson(jsonData);
13 | }
14 |
15 | //Class that handles the creation of a new user
16 | class NewUser {
17 | String name;
18 | String email;
19 |
20 | //Constructor for NewUser has a name and email
21 | NewUser({
22 | this.name,
23 | this.email,
24 | });
25 |
26 | //Converts the JSON to a NewUser
27 | factory NewUser.fromJson(Map parsedJson) {
28 | return NewUser(
29 | name: parsedJson["name"],
30 | email: parsedJson["email"],
31 | );
32 | }
33 |
34 | //Converts the data to JSON
35 | Map toJson() => {
36 | "name": name,
37 | "email": email,
38 | };
39 | }
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/google_maps/Geometry.java:
--------------------------------------------------------------------------------
1 |
2 | package com.rowan.ruber.model.google_maps;
3 |
4 | public class Geometry {
5 |
6 | private Bounds bounds;
7 | private Location location;
8 | private String locationType;
9 | private Viewport viewport;
10 |
11 | public Bounds getBounds() {
12 | return bounds;
13 | }
14 |
15 | public void setBounds(Bounds bounds) {
16 | this.bounds = bounds;
17 | }
18 |
19 | public Location getLocation() {
20 | return location;
21 | }
22 |
23 | public void setLocation(Location location) {
24 | this.location = location;
25 | }
26 |
27 | public String getLocationType() {
28 | return locationType;
29 | }
30 |
31 | public void setLocationType(String locationType) {
32 | this.locationType = locationType;
33 | }
34 |
35 | public Viewport getViewport() {
36 | return viewport;
37 | }
38 |
39 | public void setViewport(Viewport viewport) {
40 | this.viewport = viewport;
41 | }
42 |
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/MapsManager.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber;
2 |
3 | import com.rowan.ruber.model.google_maps.GeoencodingResult;
4 | import com.rowan.ruber.model.google_maps.Location;
5 | import org.springframework.web.client.RestTemplate;
6 |
7 | public class MapsManager {
8 |
9 | // If you are reading this after December 2018, our API key has been deactivated
10 | // To reactivate this API key, please send me your credit card info 🙂
11 | private static String API_KEY = "AIzaSyBUWTvOdjkdIur2IFzkEPCVTodoL7xUzJk";
12 |
13 | /**
14 | * Use the geoencoding api from google to convert the user's address in to latitude and longitude
15 | */
16 | public static Location getCoordinatesFromAddress(String address) {
17 | String url = "https://maps.googleapis.com/maps/api/geocode/json?key=" + API_KEY + "&address=" + address;
18 |
19 | RestTemplate restTemplate = new RestTemplate();
20 | GeoencodingResult geoencodingResult = restTemplate.getForObject(url, GeoencodingResult.class);
21 |
22 | return geoencodingResult.getResults().get(0).getGeometry().getLocation();
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/ruber/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.2.51'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.1.0'
10 | classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.50'
11 | classpath 'com.google.gms:google-services:3.1.2'
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | google()
18 | maven { url 'http://repo1.maven.org/maven2' }
19 | }
20 | }
21 |
22 | rootProject.buildDir = '../build'
23 | subprojects {
24 | project.buildDir = "${rootProject.buildDir}/${project.name}"
25 | }
26 | subprojects {
27 | project.evaluationDependsOn(':app')
28 | }
29 | subprojects {
30 | project.configurations.all {
31 | resolutionStrategy.eachDependency { details ->
32 | if (details.requested.group == 'com.android.support'
33 | && !details.requested.name.contains('multidex') ) {
34 | details.useVersion "26.1.0"
35 | }
36 | }
37 | }
38 | }
39 |
40 | task clean(type: Delete) {
41 | delete rootProject.buildDir
42 | }
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/Authenticator.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber;
2 |
3 | import com.google.auth.oauth2.GoogleCredentials;
4 | import com.google.firebase.FirebaseApp;
5 | import com.google.firebase.FirebaseOptions;
6 | import com.google.firebase.auth.FirebaseAuth;
7 | import com.google.firebase.auth.FirebaseAuthException;
8 | import com.google.firebase.auth.FirebaseToken;
9 |
10 | import java.io.IOException;
11 |
12 | public class Authenticator {
13 |
14 | /**
15 | * Sign a user in to the app given their auth token
16 | */
17 | public String authenticate(String authToken) {
18 | try {
19 | FirebaseOptions options = new FirebaseOptions.Builder()
20 | .setCredentials(GoogleCredentials.fromStream(Utils.convertStringToStream(Ids.FIREBASE_AUTH_KEY)))
21 | .setDatabaseUrl("https://rowan-carpool.firebaseio.com")
22 | .build();
23 |
24 | FirebaseApp.initializeApp(options);
25 |
26 | FirebaseToken decodedToken = FirebaseAuth.getInstance().verifyIdToken(authToken);
27 | //String uid = decodedToken.getUid();
28 |
29 | return decodedToken.getName();
30 | } catch (FirebaseAuthException | IOException e) {
31 | // Invalid auth token
32 | return null;
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/Day.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.model;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Enumerated Type to represent the days of the week. Used for Schedule.
7 | */
8 | public enum Day implements Serializable {
9 | MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
10 |
11 | public static Day fromInteger(int x) {
12 | switch(x) {
13 | case 0:
14 | return MONDAY;
15 | case 1:
16 | return TUESDAY;
17 | case 2:
18 | return WEDNESDAY;
19 | case 3:
20 | return THURSDAY;
21 | case 4:
22 | return FRIDAY;
23 | case 5:
24 | return SATURDAY;
25 | case 6:
26 | return SUNDAY;
27 | default:
28 | return null;
29 | }
30 | }
31 |
32 | public static char toCharacter(Day d)
33 | {
34 | switch(d){
35 | case MONDAY:
36 | return 'M';
37 | case TUESDAY:
38 | return 'T';
39 | case WEDNESDAY:
40 | return 'W';
41 | case THURSDAY:
42 | return 'R';
43 | case FRIDAY:
44 | return 'F';
45 | case SATURDAY:
46 | return 'S';
47 | case SUNDAY:
48 | return 'U';
49 | default:
50 | return ' ';
51 |
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/ruber/lib/AddressPostModel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | //Takes in a JSON String and converts it an AddressPost object
4 | AddressPost addressFromJson(String str) {
5 | final jsonData = json.decode(str);
6 | return AddressPost.fromJson(jsonData);
7 | }
8 |
9 | //Takes in an AddressPost object and returns a JSON String
10 | String addressPostToJson(AddressPost data) {
11 | final dyn = data.toJson();
12 | return json.encode(dyn);
13 | }
14 |
15 | //Returns a list of all AddressPost's from a JSON String
16 | List allAddressesFromJson(String str) {
17 | final jsonData = json.decode(str);
18 | return new List.from(
19 | jsonData.map((x) => AddressPost.fromJson(x)));
20 | }
21 |
22 | //Class that makes up what is required to post an Address
23 | class AddressPost {
24 | String streetAddress;
25 | String city;
26 | String zipCode;
27 | String state;
28 |
29 | //Constructor for an AddressPost object
30 | AddressPost({
31 | this.streetAddress,
32 | this.city,
33 | this.zipCode,
34 | this.state,
35 | });
36 |
37 | //Converts the JSON to an AddressPost
38 | factory AddressPost.fromJson(Map parsedJson) {
39 | return AddressPost(
40 | streetAddress: parsedJson["streetAddress"],
41 | city: parsedJson["city"],
42 | zipCode: parsedJson["zipCode"],
43 | state: parsedJson["state"],
44 | );
45 | }
46 |
47 | //Converts the data to JSON
48 | Map toJson() => {
49 | "streetAddress": streetAddress,
50 | "city": city,
51 | "zipCode": zipCode,
52 | "state": state,
53 | };
54 | }
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/google_maps/Result.java:
--------------------------------------------------------------------------------
1 |
2 | package com.rowan.ruber.model.google_maps;
3 |
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | public class Result {
8 |
9 | private List addressComponents;
10 | private String formattedAddress;
11 | private Geometry geometry;
12 | private String placeId;
13 | private List types;
14 |
15 | public Result() {
16 | addressComponents = new ArrayList<>();
17 | types = new ArrayList<>();
18 | }
19 |
20 | public List getAddressComponents() {
21 | return addressComponents;
22 | }
23 |
24 | public void setAddressComponents(List addressComponents) {
25 | this.addressComponents = addressComponents;
26 | }
27 |
28 | public String getFormattedAddress() {
29 | return formattedAddress;
30 | }
31 |
32 | public void setFormattedAddress(String formattedAddress) {
33 | this.formattedAddress = formattedAddress;
34 | }
35 |
36 | public Geometry getGeometry() {
37 | return geometry;
38 | }
39 |
40 | public void setGeometry(Geometry geometry) {
41 | this.geometry = geometry;
42 | }
43 |
44 | public String getPlaceId() {
45 | return placeId;
46 | }
47 |
48 | public void setPlaceId(String placeId) {
49 | this.placeId = placeId;
50 | }
51 |
52 | public List getTypes() {
53 | return types;
54 | }
55 |
56 | public void setTypes(List types) {
57 | this.types = types;
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/ruber/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 |
--------------------------------------------------------------------------------
/ruber/android/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "595426910927",
4 | "firebase_url": "https://rowan-carpool.firebaseio.com",
5 | "project_id": "rowan-carpool",
6 | "storage_bucket": "rowan-carpool.appspot.com"
7 | },
8 | "client": [
9 | {
10 | "client_info": {
11 | "mobilesdk_app_id": "1:595426910927:android:135ac0c60058b625",
12 | "android_client_info": {
13 | "package_name": "com.ruber.ruber"
14 | }
15 | },
16 | "oauth_client": [
17 | {
18 | "client_id": "595426910927-pvceg8im0ptob1vdg8f4bcf3k36g13sa.apps.googleusercontent.com",
19 | "client_type": 1,
20 | "android_info": {
21 | "package_name": "com.ruber.ruber",
22 | "certificate_hash": "d428766354982cbbec770baab9bfcc2db1162ac7"
23 | }
24 | },
25 | {
26 | "client_id": "595426910927-5u3ojfnkcb9gigj5n78temrrij09rdug.apps.googleusercontent.com",
27 | "client_type": 3
28 | }
29 | ],
30 | "api_key": [
31 | {
32 | "current_key": "AIzaSyDtlp3t9GtTVaIqWup2fCltMNrX3yeN2uo"
33 | }
34 | ],
35 | "services": {
36 | "analytics_service": {
37 | "status": 1
38 | },
39 | "appinvite_service": {
40 | "status": 2,
41 | "other_platform_oauth_client": [
42 | {
43 | "client_id": "595426910927-5u3ojfnkcb9gigj5n78temrrij09rdug.apps.googleusercontent.com",
44 | "client_type": 3
45 | }
46 | ]
47 | },
48 | "ads_service": {
49 | "status": 2
50 | }
51 | }
52 | }
53 | ],
54 | "configuration_version": "1"
55 | }
--------------------------------------------------------------------------------
/ruber/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSLocationWhenInUseUsageDescription
6 | Using location to display on a map
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ruber
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ryde
2 |
3 | The purpose of our app is to help students find other students who also commute to Rowan and live in the same general area as they do. This is done by showing how many Rowan students live in the user's specified radius and what their schedules are. From there, either person can contact the other to set up a carpooling schedule.
4 |
5 | Made using Flutter, Spring Boot (Java), and MySQL
6 |
7 | Authors: [Nicholas La Sala](https://github.com/ncklasala), [Wen Cao](https://github.com/caow2), [Michael Matthews](https://github.com/pro452), [Benny Chen](https://github.com/chenb7), [Tapan Soni](https://github.com/TapanSoni), [Tyler Carberry](https://github.com/TylerCarberry), [Benny Liang](https://github.com/liangb6), and [John Stranahan](https://github.com/JohnStranahan)
8 | Scrum Master: [John Stranahan](https://github.com/JohnStranahan)
9 |
10 | ### Documents
11 | [Project Specification Document](https://github.com/TylerCarberry/RowanRideshare/files/2573418/Project.Spec.pdf)
12 | [Design Document](https://github.com/TylerCarberry/RowanRideshare/files/2573413/Design.Document.1.pdf)
13 |
14 | ### Screenshots
15 |
16 |
17 |
18 |
19 | ### [Demo Video](https://drive.google.com/file/d/1miveKWpqok4fH83gyjjVsXeti8FP_TRW/view?usp=sharing)
20 | [](https://drive.google.com/file/d/1miveKWpqok4fH83gyjjVsXeti8FP_TRW/view?usp=sharing)
21 |
--------------------------------------------------------------------------------
/ruber/lib/MessageModel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | //Takes in a JSON string and converts it to a Message object
4 | Message messageFromJson(String str) {
5 | final jsonData = json.decode(str);
6 | return Message.fromJson(jsonData);
7 | }
8 |
9 | //Takes in a Message object and returns a JSON String
10 | String messageToJson(Message data) {
11 | final dyn = data.toJson();
12 | return json.encode(dyn);
13 | }
14 |
15 | //Returns a list of all Messages from a JSON String
16 | List allMessagesFromJson(String str) {
17 | final jsonData = json.decode(str);
18 | return new List.from(jsonData.map((x) => Message.fromJson(x)));
19 | }
20 |
21 | //Converts a List of Messages to a Json String
22 | String allMessagessToJson(List data) {
23 | final dyn = new List.from(data.map((x) => x.toJson()));
24 | return json.encode(dyn);
25 | }
26 |
27 | //Class that creates a Message object that allows users to communicate
28 | class Message {
29 | int id;
30 | var chatroom;
31 | int senderID;
32 | String text;
33 | var timeSent;
34 |
35 | //Constructor for a Message that has id, chatroom, senderID, text, and timeSent
36 | Message({
37 | this.id,
38 | this.chatroom,
39 | this.senderID,
40 | this.text,
41 | this.timeSent,
42 | });
43 |
44 | //Converts a JSON to a Message
45 | factory Message.fromJson(Map parsedJson) {
46 | return Message(
47 | id: parsedJson["id"],
48 | chatroom: parsedJson["chatroom"],
49 | senderID: parsedJson["senderID"],
50 | text: parsedJson["text"],
51 | timeSent: parsedJson["timeSent"],
52 | );
53 | }
54 |
55 | //Converts the data to JSON
56 | Map toJson() => {
57 | "id": id,
58 | "chatroom": chatroom,
59 | "senderID": senderID,
60 | "text": text,
61 | "timeSent": timeSent,
62 | };
63 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .DS_Store
3 |
4 | ruber/\.idea/workspace\.xml
5 |
6 | ruber/ios/Podfile
7 |
8 | # Miscellaneous
9 | *.class
10 | *.lock
11 | *.log
12 | *.pyc
13 | *.swp
14 | .DS_Store
15 | .atom/
16 | .buildlog/
17 | .history
18 | .svn/
19 |
20 | # IntelliJ related
21 | *.iml
22 | *.ipr
23 | *.iws
24 | .idea/
25 |
26 | # Visual Studio Code related
27 | .vscode/
28 |
29 | # Flutter repo-specific
30 | /bin/cache/
31 | /bin/mingit/
32 | /dev/benchmarks/mega_gallery/
33 | /dev/bots/.recipe_deps
34 | /dev/bots/android_tools/
35 | /dev/docs/doc/
36 | /dev/docs/lib/
37 | /dev/docs/pubspec.yaml
38 | /packages/flutter/coverage/
39 | version
40 |
41 | # Flutter/Dart/Pub related
42 | **/doc/api/
43 | .dart_tool/
44 | .flutter-plugins
45 | .packages
46 | .pub-cache/
47 | .pub/
48 | build/
49 | flutter_*.png
50 | linked_*.ds
51 | unlinked.ds
52 | unlinked_spec.ds
53 |
54 | # Android related
55 | **/android/**/gradle-wrapper.jar
56 | **/android/.gradle
57 | **/android/captures/
58 | **/android/gradlew
59 | **/android/gradlew.bat
60 | **/android/local.properties
61 | **/android/**/GeneratedPluginRegistrant.java
62 |
63 | # iOS/XCode related
64 | **/ios/**/*.mode1v3
65 | **/ios/**/*.mode2v3
66 | **/ios/**/*.moved-aside
67 | **/ios/**/*.pbxuser
68 | **/ios/**/*.perspectivev3
69 | **/ios/**/*sync/
70 | **/ios/**/.sconsign.dblite
71 | **/ios/**/.tags*
72 | **/ios/**/.vagrant/
73 | **/ios/**/DerivedData/
74 | **/ios/**/Icon?
75 | **/ios/**/Pods/
76 | **/ios/**/.symlinks/
77 | **/ios/**/profile
78 | **/ios/**/xcuserdata
79 | **/ios/.generated/
80 | **/ios/Flutter/App.framework
81 | **/ios/Flutter/Flutter.framework
82 | **/ios/Flutter/Generated.xcconfig
83 | **/ios/Flutter/app.flx
84 | **/ios/Flutter/app.zip
85 | **/ios/Flutter/flutter_assets/
86 | **/ios/ServiceDefinitions.json
87 | **/ios/Runner/GeneratedPluginRegistrant.*
88 |
89 | # Exceptions to above rules.
90 | !**/ios/**/default.mode1v3
91 | !**/ios/**/default.mode2v3
92 | !**/ios/**/default.pbxuser
93 | !**/ios/**/default.perspectivev3
94 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
95 | /bin/
96 |
--------------------------------------------------------------------------------
/ruber/lib/GoingToRowan.dart:
--------------------------------------------------------------------------------
1 | /// GoingToRowan.dart
2 | ///
3 | /// Purpose:
4 | /// The purpose of this file is to provide the radius
5 | /// variables to the screen where the user selects the
6 | /// radius for searching.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:shared_preferences/shared_preferences.dart';
10 | import 'AppDrawer.dart';
11 |
12 | double radius = 0;
13 |
14 | getRadius() {
15 | return radius.toInt();
16 | }
17 |
18 | class goingtorowan extends StatefulWidget {
19 | @override
20 | _gtr createState() => new _gtr();
21 | }
22 |
23 | setRadius(int radius) async {
24 | SharedPreferences prefs = await SharedPreferences.getInstance();
25 | prefs.setInt("radius", radius);
26 | }
27 |
28 | class _gtr extends State {
29 | void _setRadius(double newValue) => setState(() => radius = newValue);
30 |
31 | @override
32 | Widget build(BuildContext context) {
33 | return Scaffold(
34 | appBar: AppBar(
35 | title: Text("Going to Rowan"),
36 | centerTitle: true,
37 | ),
38 | drawer: launchAppDrawer(context),
39 | body: Column(
40 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
41 | children: [
42 | Text('Select the radius for searching',
43 | style: TextStyle(
44 | color: Colors.lightBlueAccent,
45 | fontSize: 23.0,
46 | fontWeight: FontWeight.bold)),
47 | Text(
48 | 'Radius: ${radius.toInt()} miles',
49 | style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
50 | ),
51 | Slider(
52 | value: radius,
53 | min: 0,
54 | max: 20,
55 | onChanged: _setRadius,
56 | ),
57 | RaisedButton(
58 | child: Text('Find Rides!'),
59 | onPressed: () {
60 | print("Hello");
61 | },
62 | )
63 | ],
64 | ));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/ruber/lib/ScheduleModel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | //Takes in a JSON string and converts it to a NewUser object
4 | Schedule scheduleFromJson(String str) {
5 | final jsonData = json.decode(str);
6 | return Schedule.fromJson(jsonData);
7 | }
8 |
9 | //Takes in a Schedule object and returns a JSON String
10 | String scheduleToJson(Schedule data) {
11 | final dyn = data.toJson();
12 | return json.encode(dyn);
13 | }
14 |
15 | //Returns a list of all Schedules from a JSON String
16 | List allSchedulesFromJson(String str) {
17 | final jsonData = json.decode(str);
18 | return new List.from(jsonData.map((x) => Schedule.fromJson(x)));
19 | }
20 |
21 | //Converts a List of schedules to a JSON String
22 | String allScheduleToJson(List data) {
23 | final dyn = new List.from(data.map((x) => x.toJson()));
24 | return json.encode(dyn);
25 | }
26 |
27 | //Class that creates a Schedule object and allows converting and parsing the data
28 | class Schedule {
29 | int id;
30 | int profile;
31 | String monday;
32 | String tuesday;
33 | String wednesday;
34 | String thursday;
35 | String friday;
36 |
37 | //Constructor for Schedule has id, profile, and days of the week
38 | Schedule({
39 | this.id,
40 | this.profile,
41 | this.monday,
42 | this.tuesday,
43 | this.wednesday,
44 | this.thursday,
45 | this.friday,
46 | });
47 |
48 | //Converts the JSON to a NewUser
49 | factory Schedule.fromJson(Map parsedJson) {
50 | return Schedule(
51 | id: parsedJson["id"],
52 | profile: parsedJson["profile"],
53 | monday: parsedJson["monday"],
54 | tuesday: parsedJson["tuesday"],
55 | wednesday: parsedJson["wednesday"],
56 | thursday: parsedJson["thursday"],
57 | friday: parsedJson["friday"],
58 | );
59 | }
60 |
61 | //Converts the data to JSON
62 | Map toJson() => {
63 | "id": id,
64 | "profile": profile,
65 | "monday": monday,
66 | "tuesday": tuesday,
67 | "wednesday": wednesday,
68 | "thursday": thursday,
69 | "friday": friday
70 | };
71 | }
--------------------------------------------------------------------------------
/server/bin/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.rowan
7 | ruber
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | ruber
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.5.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter
31 |
32 |
33 |
34 | mysql
35 | mysql-connector-java
36 | runtime
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter-test
41 | test
42 |
43 |
44 | org.springframework.boot
45 | spring-boot-starter-web
46 | RELEASE
47 | compile
48 |
49 |
50 | com.google.firebase
51 | firebase-admin
52 | 6.5.0
53 |
54 |
55 |
56 |
57 |
58 |
59 | org.springframework.boot
60 | spring-boot-maven-plugin
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/ruber/lib/AddressModel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | /*
4 | The address model holds the information of a persons address
5 | This includes the following information:
6 | street address, city, zip, state, longitude, latitude
7 | */
8 |
9 | // Returns an address object
10 | Address addressFromJson(String str) {
11 | final jsonData = json.decode(str);
12 | return Address.fromJson(jsonData);
13 | }
14 |
15 | // Returns a String
16 | String addressToJson(Address data) {
17 | final dyn = data.toJson();
18 | return json.encode(dyn);
19 | }
20 |
21 | //Returns a List of Address objects from JSON String
22 | List allAddressesFromJson(String str) {
23 | final jsonData = json.decode(str);
24 | return new List.from(jsonData.map((x) => Address.fromJson(x)));
25 | }
26 |
27 | String allAddressesToJson(List data) {
28 | final dyn = new List.from(data.map((x) => x.toJson()));
29 | return json.encode(dyn);
30 | }
31 |
32 | //Class that makes up what is required to get an Address
33 | class Address {
34 | int id;
35 | String streetAddress;
36 | String city;
37 | String zipCode;
38 | String state;
39 | double latitude;
40 | double longitude;
41 |
42 | //Constructor for an Address object
43 | Address({
44 | this.id,
45 | this.streetAddress,
46 | this.city,
47 | this.zipCode,
48 | this.state,
49 | this.latitude,
50 | this.longitude,
51 | });
52 |
53 | //Converts the JSON to an Address
54 | factory Address.fromJson(Map parsedJson) {
55 | return Address(
56 | id: parsedJson["id"],
57 | streetAddress: parsedJson["streetAddress"],
58 | city: parsedJson["city"],
59 | zipCode: parsedJson["zipCode"],
60 | state: parsedJson["state"],
61 | latitude: parsedJson["latitude"],
62 | longitude: parsedJson["longitude"],
63 | );
64 | }
65 |
66 | //Converts the data to JSON
67 | Map toJson() => {
68 | "id": id,
69 | "streetAddress": streetAddress,
70 | "city": city,
71 | "zipCode": zipCode,
72 | "state": state,
73 | "latitude": latitude,
74 | "longitude": longitude,
75 | };
76 |
77 | @override
78 | String toString() {
79 | return id.toString() + streetAddress.toString() + city + zipCode + state;
80 | }
81 | }
--------------------------------------------------------------------------------
/ruber/lib/RideScreen.dart:
--------------------------------------------------------------------------------
1 | /// RideScreen.dart
2 | ///
3 | /// Purpose:
4 | /// The purpose of this file is to provide the user with a radius slider
5 | /// which is used to select the search radius for ride matching. It is
6 | /// preset to 20 miles, but we can change that. From this screen, it takes
7 | /// the user to the matches screen.
8 |
9 | /// Imports
10 | import 'package:flutter/material.dart';
11 | import 'package:shared_preferences/shared_preferences.dart';
12 |
13 | import 'AppDrawer.dart';
14 | import 'GoingToRowan.dart';
15 | import 'matches_screen.dart';
16 |
17 | class launchRideScreen extends StatefulWidget {
18 | @override
19 | _gtr createState() => new _gtr();
20 | }
21 |
22 | saveRadius(double radius) async {
23 | SharedPreferences prefs = await SharedPreferences.getInstance();
24 | prefs.setInt("radius", radius.toInt());
25 | }
26 |
27 | class _gtr extends State {
28 | void _setRadius(double newValue) => setState(() => radius = newValue);
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return Scaffold(
33 | appBar: AppBar(
34 | title: Text("New Ride"),
35 | centerTitle: true,
36 | ),
37 | drawer: launchAppDrawer(context),
38 | body: Column(
39 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
40 | children: [
41 | Text('Select the radius for searching',
42 | style: TextStyle(
43 | color: Colors.blue,
44 | fontSize: 23.0,
45 | fontWeight: FontWeight.bold)),
46 | Text(
47 | 'Radius: ${radius.toInt()} miles',
48 | style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
49 | ),
50 | Slider(
51 | value: radius,
52 | min: 0, // Set the min to 0 miles
53 | max: 20, // Set the max to 20 miles
54 | onChanged: _setRadius,
55 | ),
56 | RaisedButton(
57 | child: Text('Find Rides!'),
58 | color: Colors.blue,
59 | textColor: Colors.white,
60 | onPressed: () {
61 | saveRadius(radius);
62 | Navigator.push(context,
63 | MaterialPageRoute(builder: (context) => matchesScreen()));
64 | },
65 | )
66 | ],
67 | ));
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/ruber/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
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 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 27
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 |
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "com.ruber.ruber"
42 | minSdkVersion 16
43 | targetSdkVersion 27
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
47 | }
48 |
49 | buildTypes {
50 | release {
51 | // TODO: Add your own signing config for the release build.
52 | // Signing with the debug keys for now, so `flutter run --release` works.
53 | signingConfig signingConfigs.debug
54 | }
55 | }
56 | }
57 |
58 | flutter {
59 | source '../..'
60 | }
61 |
62 | dependencies {
63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
64 | testImplementation 'junit:junit:4.12'
65 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
66 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
67 | implementation 'com.google.firebase:firebase-core:16.0.4'
68 | }
69 |
70 | apply plugin: 'com.google.gms.google-services'
--------------------------------------------------------------------------------
/server/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.rowan
7 | ruber
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | ruber
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.5.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter
31 |
32 |
33 |
34 | mysql
35 | mysql-connector-java
36 | runtime
37 |
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-starter-test
42 | test
43 |
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-starter-web
48 | RELEASE
49 | compile
50 |
51 |
52 |
53 | com.google.firebase
54 | firebase-admin
55 | 6.5.0
56 |
57 |
58 |
59 | javax.xml.bind
60 | jaxb-api
61 | 2.3.0
62 |
63 |
64 |
65 | org.springframework.boot
66 | spring-boot-starter-data-jpa
67 | 2.0.6.RELEASE
68 |
69 |
70 |
71 |
72 |
73 |
74 | org.springframework.boot
75 | spring-boot-maven-plugin
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/ruber/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 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ruber/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
17 |
21 |
22 |
23 |
30 |
34 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/Ids.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber;
2 |
3 | public class Ids {
4 |
5 | public static final String FIREBASE_AUTH_KEY = "{\n" +
6 | " \"type\": \"service_account\",\n" +
7 | " \"project_id\": \"rowan-carpool\",\n" +
8 | " \"private_key_id\": \"e81b414d7cee3c3d6989cd77ca7957482e0b92c0\",\n" +
9 | " \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCx9MIafuOcrZvn\\nBJ6/dXuPag5vTjjnkeeUlHk3BWBVVF/tBHOneaL/dRK7uySBIlsPet5+Ki8peFqO\\n1F1wgQaBoUEPhbfniSjmpEekoCND127DVXD1gg3pNx/8XJimgVxOWxAnQx6jGQbw\\n+lhKcCb2i1mRTqLL/7DAffOJyBMIKW4uIMrNixQtr7xFFW+2V6smtVmtEDKxTJpm\\nrQQWbOz62fmxZgIsEqQyBQqlwp7XNvr1yvx4lhf73bdSHgSWKKqB1Ftt7pDPCqbt\\n/2Bq93bQzKTt3rK85SmcnS7O3wtqd+NvMOjQHkdqZbokxBT2Ubj8WbG9hhl5woPw\\nVk1B0KP1AgMBAAECggEADiWDaADN+PlnddoiVoexLrRDI9UHkAfDbZvPS7Dujgn6\\n5YgfkODfX3MVQ1LmstSiLDJbzT1u6gXfyQ/tF6b3d0b0OZbV3kmYifE6+BrPgt1K\\n4wCqo1Gskm1n6l4Kt93REoeJsAgAFP4bKlKfFy0gOSQtwW/gtYUvg2CKg4RMra7J\\n7MTZliXfYJMclubaiKnOLxEaAtvM31tzgi8hUspIHGYzudiOkVbht9yKuJpjXsJg\\ndTZSHs1TtARxqteBhk/KcHC+aeAw6yzH8jmatEN78EyXHcLOzJbcYBHvLW+Ep6Tl\\nem74dhxK48fOcn4QqWFUMIGHspsJbbm91S8EAvXP5wKBgQDyHp2sxYJAwEKZVWGS\\ntBM3596gy1cCe/YSLqYIgvxOG+Kd+oogUvHdrxP3mDvnNZOjkeMDvIQtmkjlQYo5\\nHoqEJOvbyrkJwopn3uKGG65lqGmYXaZfkYeeoxdxrvyRiwmPQwtlGLT7H8Ci5KuC\\nWZswIAn0wJE2Ijj6zG34r49YnwKBgQC8KHgJH5LR8p1waOEbJqlvm3t6QeuEyIGf\\n2PaaYputqz/pjnhXZBekIsQiQP4l7jDdNGJj8oifx/xN0h1Wk8hnffHEq5tE9PIo\\nhVX8uIu6nLHctd0D/ztUCr8UIz/K5rvOE09T6u+ujByGioXZA1RnJM23uUQQVt2T\\nLzd5QP926wKBgCFUsaQdNIcxcHmnVV1ayOKDWxSLqZi/8+og3d6CGbWvBQ12dhlp\\nEb7Q4VDOdkCoEYENDlFvXEri2HInCZ4/ZBY49vc0+zAqxd7ywgBwQxvfiVneWo8B\\ne8gM76dIzaBDobdFJYZvVkrT3jMOg8XYDBMd9gDpmZP4NhvglKsNkBBFAoGAIKQA\\nlsyUYrls2HhJPLWLRSI63G2dFs7Vtc4kkYmzqgAAOVsOw1JIy5+AWNTfgeL9NRKG\\nUwJa8yT1PubJUiCW7mUp0M1YRTEc5SykSxAUpU3TiQ8/hRb8ysqGdU7cHS3DvK8a\\n3trts2D4/dn/+DKcrLv0t/96sD7xdzwEqpM8/fsCgYArxO8bUOo3KuZ8MpbT4eeW\\nulSYkH4YtAMjWOiLkaamzzg46Nh5TRV0IDCHQPlib7tH2+e+AHtvC51DoB1WF9Hx\\nW9C+L8EI9mqqWxpu4Y/F0Nwc7PK+FnEyMyQgVu34Sk97zwoMHk9DTTcy6xTJXRQl\\nozm7NLx8rrCwA4MwqhR5Jw==\\n-----END PRIVATE KEY-----\\n\",\n" +
10 | " \"client_email\": \"firebase-adminsdk-jy4h4@rowan-carpool.iam.gserviceaccount.com\",\n" +
11 | " \"client_id\": \"106417927546032867975\",\n" +
12 | " \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\n" +
13 | " \"token_uri\": \"https://oauth2.googleapis.com/token\",\n" +
14 | " \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\",\n" +
15 | " \"client_x509_cert_url\": \"https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-jy4h4%40rowan-carpool.iam.gserviceaccount.com\"\n" +
16 | "}\n";
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/ruber/lib/AppDrawer.dart:
--------------------------------------------------------------------------------
1 | /// AppDrawer.dart
2 | ///
3 | /// Purpose:
4 | /// This file is used for the app drawer in flutter
5 | /// It shows a menu whenever the user clicks on the app drawer icon
6 | /// on the top left hand side of the app.
7 |
8 | /// Imports
9 | import 'package:flutter/material.dart';
10 |
11 | import 'ChatRoomScreen.dart';
12 | import 'RideScreen.dart';
13 | import 'editschedule.dart';
14 | import 'main.dart';
15 | import 'profile.dart';
16 |
17 | /// Drawer Widget which holds all the drawer options
18 | /// Drawer Options:
19 | /// 1) Main Screen - MainScreen()
20 | /// 2) New Ryde Screen - launchRideScreen()
21 | /// 3) Messages Screen - ChatRoomScreen()
22 | /// 4) Profile Screen - ProfileScreen()
23 | /// 5) Schedule Screen - ScheduleForm()
24 | Drawer launchAppDrawer(context) {
25 | return Drawer(
26 | child: ListView(
27 | children: [
28 | DrawerHeader(
29 | child: Image.network(
30 | 'https://www.tlcrentalmarketplace.com/wp-content/uploads/2018/03/rideshare.png',
31 | height: 150,
32 | ),
33 | ),
34 |
35 | /// Main Screen option
36 |
37 | ListTile(
38 | leading: Icon(Icons.home),
39 | title: Text('Main Menu'),
40 | onTap: () {
41 | Navigator.push(
42 | context,
43 | MaterialPageRoute(builder: (context) => MainScreen()),
44 | );
45 | },
46 | ),
47 |
48 | /// New Ryde screen option
49 |
50 | ListTile(
51 | leading: Icon(Icons.directions_car),
52 | title: Text('New Ride'),
53 | onTap: () {
54 | Navigator.push(context,
55 | MaterialPageRoute(builder: (context) => launchRideScreen()));
56 | }),
57 |
58 | /// Messages screen option
59 |
60 | ListTile(
61 | leading: Icon(Icons.message),
62 | title: Text('Messages'),
63 | onTap: () {
64 | Navigator.push(
65 | context,
66 | MaterialPageRoute(builder: (context) => ChatRoomScreen()),
67 | );
68 | },
69 | ),
70 |
71 | /// Profile screen option
72 |
73 | ListTile(
74 | leading: Icon(Icons.account_box),
75 | title: Text('Profile'),
76 | onTap: () {
77 | Navigator.push(
78 | context,
79 | MaterialPageRoute(builder: (context) => ProfileScreen()),
80 | );
81 | },
82 | ),
83 |
84 | /// Schedule screen option
85 |
86 | ListTile(
87 | leading: Icon(Icons.schedule),
88 | title: Text('Schedule'),
89 | onTap: () {
90 | Navigator.push(
91 | context, MaterialPageRoute(builder: (context) => ScheduleForm()));
92 | },
93 | ),
94 | ],
95 | ));
96 | }
97 |
--------------------------------------------------------------------------------
/ruber/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 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ruber/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: ruber
2 | description: Rowan Carpool
3 |
4 | # The following defines the version and build number for your application.
5 | # A version number is three numbers separated by dots, like 1.2.43
6 | # followed by an optional build number separated by a +.
7 | # Both the version and the builder number may be overridden in flutter
8 | # build by specifying --build-name and --build-number, respectively.
9 | # Read more about versioning at semver.org.
10 | version: 1.0.0+1
11 |
12 | environment:
13 | sdk: ">=2.0.0-dev.68.0 <3.0.0"
14 |
15 | dependencies:
16 | flutter:
17 | sdk: flutter
18 |
19 | # The following adds the Cupertino Icons font to your application.
20 | # Use with the CupertinoIcons class for iOS style icons.
21 | cupertino_icons: ^0.1.2
22 | map_view:
23 | git:
24 | url: git://github.com/Eimji/flutter_google_map_view.git
25 |
26 | http: ^0.12.0
27 | shared_preferences: ^0.4.3
28 |
29 | path_provider: ^0.4.0
30 |
31 | google_sign_in: ^3.2.1
32 | firebase_auth: ^0.6.2+1
33 |
34 |
35 | # For information on the generic Dart part of this file, see the
36 | # following page: https://www.dartlang.org/tools/pub/pubspec
37 |
38 | # The following section is specific to Flutter.
39 | flutter:
40 | assets:
41 | - assets/RowanCampus.jpg
42 |
43 | # The following line ensures that the Material Icons font is
44 | # included with your application, so that you can use the icons in
45 | # the material Icons class.
46 | uses-material-design: true
47 |
48 | # To add assets to your application, add an assets section, like this:
49 | # assets:
50 | # - images/a_dot_burr.jpeg
51 | # - images/a_dot_ham.jpeg
52 |
53 | # An image asset can refer to one or more resolution-specific "variants", see
54 | # https://flutter.io/assets-and-images/#resolution-aware.
55 |
56 | # For details regarding adding assets from package dependencies, see
57 | # https://flutter.io/assets-and-images/#from-packages
58 |
59 | # To add custom fonts to your application, add a fonts section here,
60 | # in this "flutter" section. Each entry in this list should have a
61 | # "family" key with the font family name, and a "fonts" key with a
62 | # list giving the asset and other descriptors for the font. For
63 | # example:
64 | # fonts:
65 | # - family: Schyler
66 | # fonts:
67 | # - asset: fonts/Schyler-Regular.ttf
68 | # - asset: fonts/Schyler-Italic.ttf
69 | # style: italic
70 | # - family: Trajan Pro
71 | # fonts:
72 | # - asset: fonts/TrajanPro.ttf
73 | # - asset: fonts/TrajanPro_Bold.ttf
74 | # weight: 700
75 | #
76 | # For details regarding fonts from package dependencies,
77 | # see https://flutter.io/custom-fonts/#from-packages
78 |
79 | fonts:
80 | - family: Bungee
81 | fonts:
82 | - asset: assets/fonts/Bungee-Regular.ttf
83 | - family: Bungee2
84 | fonts:
85 | - asset: assets/fonts/BungeeInline-Regular.ttf
86 | - family: Bungee3
87 | fonts:
88 | - asset: assets/fonts/BungeeShade-Regular.ttf
89 | - family: Heebo
90 | fonts:
91 | - asset: assets/fonts/Heebo-Regular.ttf
92 | - family: Roboto
93 | fonts:
94 | - asset: assets/fonts/Roboto-Regular.ttf
95 | - family: Audiowide
96 | fonts:
97 | - asset: assets/fonts/Audiowide-Regular.ttf
--------------------------------------------------------------------------------
/ruber/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/Message.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.model;
2 |
3 | import java.io.Serializable;
4 | import javax.persistence.Column;
5 | import javax.persistence.Entity;
6 | import javax.persistence.GeneratedValue;
7 | import javax.persistence.GenerationType;
8 | import javax.persistence.Id;
9 | import javax.persistence.JoinColumn;
10 | import javax.persistence.ManyToOne;
11 | import javax.persistence.Table;
12 |
13 | import com.fasterxml.jackson.annotation.JsonBackReference;
14 |
15 | //import java.sql.Date;
16 | import java.util.Date;
17 |
18 |
19 |
20 | /** Class to set up the JPA Entity for the Message table in the DB. */
21 | @Entity
22 | @Table(name="message")
23 | public class Message implements Serializable, Comparable {
24 | @Id
25 | @Column(name="MessageID")
26 | @GeneratedValue(strategy=GenerationType.IDENTITY) //Identity strategy for MySQL is auto increment
27 | private int id;
28 |
29 | @ManyToOne
30 | @JsonBackReference
31 | @JoinColumn(name = "ChatroomID")
32 | private Chatroom chatroom;
33 |
34 | @Column(name="senderID")
35 | private int senderID;
36 |
37 | @Column(name="text")
38 | private String text;
39 |
40 | @Column(name="timeSent")
41 | private Date timeSent;
42 |
43 | /**
44 | * Default constructor for JPA.
45 | * It should not be used directly as no values will be initialized.
46 | */
47 | public Message(){}
48 |
49 | public Message(Chatroom chatroom, int senderID, String text, Date timeSent){
50 | this.chatroom = chatroom;
51 | this.senderID = senderID;
52 | this.text = text;
53 | this.timeSent = timeSent; // SQL date or util date?
54 | }
55 |
56 |
57 | /**
58 | * Get the message id.
59 | * @return the id
60 | */
61 | public int getId() {
62 | return id;
63 | }
64 |
65 | /**
66 | * Get the chatroom.
67 | * @return the chatroom
68 | */
69 | public Chatroom getChatroom() {
70 | return chatroom;
71 | }
72 |
73 | /**
74 | * Get the sender.
75 | * @return a profile
76 | */
77 | public int getSenderID() {
78 | return senderID;
79 | }
80 |
81 | /**
82 | * Get the message text. Limit of 200 characters.
83 | * @return the text
84 | */
85 | public String getText() {
86 | return text;
87 | }
88 |
89 | /**
90 | * Get the formatted date and time this message was sent.
91 | * Avoid using SimpleDateFormat as it is not thread-safe.
92 | * @return the timeSent as a formatted String.
93 | */
94 | public String getTimeSent() {
95 | return String.format("%1$TD %1$TT", timeSent);
96 | }
97 |
98 | /**
99 | * Set the message id
100 | * @param id the id to set
101 | */
102 | public void setId(int id) {
103 | this.id = id;
104 | }
105 |
106 | /**
107 | * Set the chatroom.
108 | * @param chatroom the chatroom to set
109 | */
110 | public void setChatroom(Chatroom chatroom) {
111 | this.chatroom = chatroom;
112 | }
113 |
114 | /**
115 | * Set the sender for this message.
116 | * @param sender the sender's profile
117 | */
118 | public void setSender(int senderID) {
119 | this.senderID = senderID;
120 | }
121 |
122 | /**
123 | * Set the text for this message.
124 | * @param text the text to set
125 | */
126 | public void setText(String text) {
127 | this.text = text;
128 | }
129 |
130 | /**
131 | * Set the date and time for this message.
132 | * @param timeSent the timeSent to set
133 | */
134 | public void setTimeSent(Date timeSent) {
135 | this.timeSent = timeSent;
136 | }
137 |
138 | @Override
139 | public int compareTo(Message o) {
140 | return o.timeSent.compareTo(timeSent);
141 | }
142 | }
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/Chatroom.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonBackReference;
4 | import com.fasterxml.jackson.annotation.JsonManagedReference;
5 |
6 | import javax.persistence.*;
7 | import java.io.Serializable;
8 | import java.util.*;
9 |
10 | @Entity
11 | @Table(name="chatroom")
12 | public class Chatroom implements Serializable{
13 | @Id
14 | @Column(name="ChatroomID")
15 | @GeneratedValue(strategy=GenerationType.IDENTITY) //Identity strategy for MySQL is auto increment
16 | private int chatRoomId;
17 |
18 | @Column(name="CreatedDate")
19 | private Date createdDate;
20 |
21 | @OneToOne
22 | @JoinColumn(name="LastMessageID")
23 | private Message lastMessage;
24 |
25 | @JsonBackReference
26 | @ManyToMany(mappedBy="chatrooms")
27 | private List profiles = new ArrayList();
28 |
29 | @JsonManagedReference
30 | @OneToMany(mappedBy = "chatroom", cascade=CascadeType.REMOVE)
31 | @OrderBy("timeSent asc ")
32 | private List messages = new ArrayList();
33 |
34 | @Transient
35 | private HashMap emails = new HashMap(); // use this instead of profiles to stop infinite recursion
36 |
37 | @Transient
38 | private HashMap profileIDs = new HashMap();
39 |
40 | @Transient
41 | private HashMap profileNames = new HashMap();
42 |
43 | /**
44 | * Default constructor for JPA.
45 | * It should not be used directly as no values will be initialized.
46 | */
47 | public Chatroom(){
48 | }
49 |
50 | /**
51 | * When chat room is first created, there can't be a message sent yet.
52 | * A message has to belong to a chatroom, so lastMessage is initially null.
53 | *
54 | * LastMessageId is nullable on database
55 | * @param createdDate
56 | */
57 | public Chatroom(Date createdDate){
58 | this.createdDate = createdDate;
59 | lastMessage = null;
60 | }
61 |
62 | /**
63 | * Gets the chat room id
64 | * @return the chatRoomId
65 | */
66 | public int getChatRoomId() {
67 | return chatRoomId;
68 | }
69 |
70 | /**
71 | * Get the formatted date and time this profile was created.
72 | * Avoid using SimpleDateFormat as it is not thread-safe.
73 | * @return the createdDate as a formatted String.
74 | */
75 | public String getCreatedDate() {
76 | return String.format("%1$TD %1$TT", createdDate);
77 | }
78 |
79 | /**
80 | * Gets the very recent message id
81 | * @return the lastMessageId
82 | */
83 | public Message getLastMessageId() {
84 | return lastMessage;
85 | }
86 |
87 | /**
88 | * Gets the messages for this chatroom.
89 | * @return a list of messages
90 | */
91 | public List getMessages() {
92 | Collections.sort(messages);
93 | return messages;
94 | }
95 |
96 | /**
97 | * Gets the profiles in this chatroom.
98 | * @return a list of profiles
99 | */
100 | public List getProfiles() {
101 | return profiles;
102 | }
103 |
104 | /**
105 | * Gets the profileIDs in this chatroom.
106 | * @return a list of profileID
107 | */
108 | public HashMap getEmails() {
109 | return emails;
110 | }
111 |
112 | public HashMap getProfileNames() {
113 | return profileNames;
114 | }
115 |
116 | public HashMap getProfileIDs() {
117 | return profileIDs;
118 | }
119 |
120 | /**
121 | * Sets the last message.
122 | */
123 | public void setLastMessage(Message message) {
124 | lastMessage = message;
125 | }
126 |
127 | @PostLoad
128 | public void populateTransient() {
129 | for(int i = 0; i < profiles.size(); i++) {
130 | Profile p = profiles.get(i);
131 | String current = Integer.toString(i + 1);
132 | emails.put("Profile " + current, p.getEmail());
133 | profileNames.put("Profile " + current , p.getName());
134 | profileIDs.put("Profile " + current, p.getId());
135 | }
136 |
137 |
138 | }
139 |
140 |
141 |
142 |
143 | }
--------------------------------------------------------------------------------
/ruber/lib/ProfileModel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | //Takes in a JSON string and converts it to a Post object
4 | Post postFromJson(String str) {
5 | final jsonData = json.decode(str);
6 | return Post.fromJson(jsonData);
7 | }
8 |
9 | //Takes in a Post object and returns a JSON String
10 | String postToJson(Post data) {
11 | final dyn = data.toJson();
12 | return json.encode(dyn);
13 | }
14 |
15 | //Returns a list of all Posts from a JSON String
16 | List allPostsFromJson(String str) {
17 | final jsonData = json.decode(str);
18 | return new List.from(jsonData.map((x) => Post.fromJson(x)));
19 | }
20 |
21 | //Converts a List of Posts to a Json String
22 | String allPostsToJson(List data) {
23 | final dyn = new List.from(data.map((x) => x.toJson()));
24 | return json.encode(dyn);
25 | }
26 |
27 | //Class that creates a Post object
28 | class Post {
29 | int id;
30 | String name;
31 | String email;
32 | String createdDate;
33 | Address2 address;
34 | List schedules;
35 | double distanceRounded;
36 |
37 | //Class that creates a Post
38 | Post(
39 | {this.id,
40 | this.name,
41 | this.email,
42 | this.createdDate,
43 | this.address,
44 | this.schedules,
45 | this.distanceRounded});
46 |
47 | //Converts JSON to a Post object
48 | factory Post.fromJson(Map parsedJson) {
49 | var list = parsedJson['schedules'] as List;
50 | List scheduleList =
51 | list.map((i) => Schedule2.fromJsonSchedule(i)).toList();
52 | return Post(
53 | id: parsedJson["id"],
54 | name: parsedJson["name"],
55 | email: parsedJson["email"],
56 | createdDate: parsedJson["createdDate"],
57 | address: Address2.fromJsonAddress(parsedJson["address"]),
58 | schedules: scheduleList,
59 | distanceRounded: parsedJson["distanceRounded"],
60 | );
61 | }
62 |
63 | //Converts the data to JSON
64 | Map toJson() => {
65 | "id": id,
66 | "name": name,
67 | "email": email,
68 | "createdDate": createdDate,
69 | "address": address,
70 | "schedules": schedules,
71 | "distanceRounded": distanceRounded
72 | };
73 | }
74 |
75 | //Class used to parse the nested Address objects
76 | class Address2 {String streetAddress;
77 | String city;
78 | String zipCode;
79 | String state;
80 | double latitude;
81 | double longitude;
82 |
83 | Address2({
84 | this.streetAddress,
85 | this.city,
86 | this.zipCode,
87 | this.state,
88 | this.latitude,
89 | this.longitude,
90 | });
91 |
92 | factory Address2.fromJsonAddress(Map json) {
93 | return Address2(
94 | streetAddress: json["streetAddress"],
95 | city: json["city"],
96 | zipCode: json["zipCode"],
97 | state: json["state"],
98 | latitude: json["latitude"],
99 | longitude: json["longitude"],
100 | );
101 | }
102 |
103 | Map toJsonAddress() => {
104 | "streetAddress": streetAddress,
105 | "city": city,
106 | "zipCode": zipCode,
107 | "state": state,
108 | "latitude": latitude,
109 | "longitude": longitude,
110 | };
111 | }
112 |
113 | //Class used to parse the nested Schedule objects
114 | class Schedule2 {
115 | int id;
116 | int profile;
117 | String day;
118 | String goingToRangeStart;
119 | String goingToRangeEnd;
120 | String leavingRangeStart;
121 | String leavingRangeEnd;
122 |
123 | Schedule2({
124 | this.id,
125 | this.profile,
126 | this.day,
127 | this.goingToRangeStart,
128 | this.goingToRangeEnd,
129 | this.leavingRangeStart,
130 | this.leavingRangeEnd,
131 | });
132 |
133 | factory Schedule2.fromJsonSchedule(Map parsedJson) {
134 | return Schedule2(
135 | id: parsedJson['id'],
136 | profile: parsedJson['profile'],
137 | day: parsedJson['day'],
138 | goingToRangeStart: parsedJson['goingToRangeStart'],
139 | goingToRangeEnd: parsedJson['goingToRangeEnd'],
140 | leavingRangeStart: parsedJson['leavingRangeStart'],
141 | leavingRangeEnd: parsedJson['leavingRangeEnd'],
142 | );
143 | }
144 |
145 | Map toJson() => {
146 | "id": id,
147 | "profile": profile,
148 | "day": day,
149 | "goingToRangeStart": goingToRangeStart,
150 | "goingToRangeEnd": goingToRangeEnd,
151 | "leavingRangeStart": leavingRangeStart,
152 | "leavingRangeEnd": leavingRangeEnd,
153 | };
154 | }
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/Address.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.model;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.persistence.Column;
6 | import javax.persistence.Entity;
7 | import javax.persistence.GeneratedValue;
8 | import javax.persistence.GenerationType;
9 | import javax.persistence.Table;
10 | import javax.persistence.Id;
11 |
12 | /** Class to set up the JPA Entity for the Address table in the DB. */
13 | @Entity
14 | @Table(name="address")
15 | public class Address implements Serializable{
16 | @Id
17 | @Column(name="AddressID")
18 | @GeneratedValue(strategy=GenerationType.IDENTITY) //Identity strategy for MySQL is auto increment
19 | private int id;
20 |
21 | @Column(name="StreetAddress")
22 | private String streetAddress;
23 |
24 | @Column(name="City")
25 | private String city;
26 |
27 | @Column(name="ZipCode")
28 | private String zipCode;
29 |
30 | @Column(name="State")
31 | private String state;
32 |
33 | private double latitude;
34 |
35 | private double longitude;
36 |
37 |
38 | /** Default constructor for JPA.
39 | * It should not be used directly as no values will be initialized.
40 | */
41 | protected Address() {}
42 |
43 | /** Constructor that takes all parameters. */
44 | public Address(String streetAddress, String city, String state, String zipCode, double latitude, double longitude) {
45 | this.streetAddress = streetAddress;
46 | this.city = city;
47 | this.state = state;
48 | this.zipCode = zipCode;
49 | this.latitude = latitude;
50 | this.longitude = longitude;
51 | }
52 |
53 | /**
54 | * Gets the AddressID.
55 | * @return the id
56 | */
57 | public int getId() {
58 | return id;
59 | }
60 |
61 | /**
62 | * Gets the street address.
63 | * @return the streetAddress
64 | */
65 | public String getStreetAddress() {
66 | return streetAddress;
67 | }
68 |
69 | /**
70 | * Gets the city.
71 | * @return the city
72 | */
73 | public String getCity() {
74 | return city;
75 | }
76 |
77 | /**
78 | * Gets the state.
79 | * @return the state
80 | */
81 | public String getState() {
82 | return state;
83 | }
84 |
85 | /**
86 | * Gets the zip code.
87 | * @return the zipCode
88 | */
89 | public String getZipCode() {
90 | return zipCode;
91 | }
92 |
93 | /**
94 | * Gets the latitude.
95 | * @return the latitude
96 | */
97 | public double getLatitude() {
98 | return latitude;
99 | }
100 |
101 | /**
102 | * Gets the longitude.
103 | * @return the longitude
104 | */
105 | public double getLongitude() {
106 | return longitude;
107 | }
108 |
109 | /**
110 | * Return the String representation for an address.
111 | * @return a String for this address
112 | */
113 | @Override
114 | public String toString() {
115 | return String.format("%s , %s , %s %s", streetAddress, city, state, zipCode);
116 | }
117 |
118 | /**
119 | * Sets the street address. Limit of 45 characters.
120 | * @param streetAddress the streetAddress to set
121 | */
122 | public void setStreetAddress(String streetAddress) {
123 | this.streetAddress = streetAddress;
124 | }
125 |
126 | /**
127 | * Sets the city. Limit of 45 characters.
128 | * @param city the city to set
129 | */
130 | public void setCity(String city) {
131 | this.city = city;
132 | }
133 |
134 | /**
135 | * Sets the state. Limit of 2 characters. For example, NY for New York.
136 | * @param state the state to set
137 | */
138 | public void setState(String state) {
139 | this.state = state.toUpperCase();
140 | }
141 |
142 | /**
143 | * Sets the zip code. Limit of 5 characters.
144 | * @param zipCode the zipCode to set
145 | */
146 | public void setZipCode(String zipCode) {
147 | this.zipCode = zipCode;
148 | }
149 |
150 | /**
151 | * Sets the latitude.
152 | * @param latitude the latitude to set
153 | */
154 | public void setLatitude(double latitude) {
155 | this.latitude = latitude;
156 | }
157 |
158 | /**
159 | * Sets the longitude.
160 | * @param longitude the longitude to set
161 | */
162 | public void setLongitude(double longitude) {
163 | this.longitude = longitude;
164 | }
165 |
166 | }
--------------------------------------------------------------------------------
/server/bin/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/server/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/ruber/lib/ChatroomModel.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | //Takes in a JSON string and converts it to a ChatList object
4 | ChatList listFromJsonChat(String str) {
5 | final jsonData = json.decode(str);
6 | //print(jsonData);
7 | //print(ChatList.fromJson(jsonData));
8 | return ChatList.fromJsonChat(jsonData);
9 | }
10 |
11 | //Takes in a ChatList object and returns a JSON String
12 | String listToJsonChat(ChatList data) {
13 | final dyn = data.toJson();
14 | return json.encode(dyn);
15 | }
16 |
17 | //Takes in a Messages object and returns a JSON String
18 | String messagePostToJson(Messages data) {
19 | final dyn = data.toJson();
20 | return json.encode(dyn);
21 | }
22 |
23 | //Takes in a Chatroom object and returns a JSON String
24 | String chatroomPostToJson(ChatRoom data) {
25 | final dyn = data.toJson();
26 | return json.encode(dyn);
27 | }
28 |
29 | //Returns a list of all ChatList objects from a JSON String
30 | List allChatsFromJson(String str) {
31 | final jsonData = json.decode(str);
32 | return new List.from(jsonData.map((x) => ChatList.fromJsonChat(x)));
33 | }
34 |
35 | //Converts a List of ChatList objects to a JSON String
36 | String allPostsToJson(List data) {
37 | final dyn = new List.from(data.map((x) => x.toJson()));
38 | return json.encode(dyn);
39 | }
40 |
41 | //Class that shows all Chats
42 | class ChatList {
43 | List chatrooms;
44 | ChatList(
45 | {this.chatrooms});
46 | factory ChatList.fromJsonChat(Map parsedJson) {
47 | var list = parsedJson['chatrooms'] as List;
48 | //print(list);
49 | List chatRoomList =
50 | list.map((i) => ChatRoom.fromJsonChatRoom(i)).toList();
51 | return ChatList(
52 | chatrooms: chatRoomList,
53 | );
54 | }
55 | Map toJson() => {
56 | "chatrooms": chatrooms,
57 | };
58 | }
59 |
60 | //A Chatroom class that structures communication between two users
61 | class ChatRoom {
62 | int chatRoomId;
63 | String createdDate;
64 | List messages;
65 | ProfileIDs profileIDs;
66 | int profileOneID;
67 | int profileTwoID;
68 | ProfileNames profileNames;
69 | int lastMessageId;
70 | ChatRoom({
71 | this.chatRoomId,
72 | this.createdDate,
73 | this.messages,
74 | this.profileIDs,
75 | this.profileNames,
76 | this.profileOneID,
77 | this.profileTwoID,
78 | this.lastMessageId,
79 | });
80 | factory ChatRoom.fromJsonChatRoom(Map parsedJson) {
81 | var list = parsedJson['messages'] as List;
82 | List messageList =
83 | list.map((i) => GetMessage.fromJsonGetMessages(i)).toList();
84 | return ChatRoom(
85 | chatRoomId: parsedJson['chatRoomId'],
86 | createdDate: parsedJson['createdDate'],
87 | messages: messageList,
88 | profileIDs: ProfileIDs.fromJsonIDs(parsedJson["profileIDs"]),
89 | profileNames: ProfileNames.fromJsonNames(parsedJson["profileNames"]),
90 | profileOneID: parsedJson['profileOneID'],
91 | profileTwoID: parsedJson['profileTwoID'],
92 | lastMessageId: parsedJson['lastMessageId'],
93 | );
94 | }
95 |
96 | //Converts the data to JSON
97 | Map toJson() => {
98 | "chatRoomId": chatRoomId,
99 | "createdDate": createdDate,
100 | "messages": messages,
101 | "profileIDs": profileIDs,
102 | "profileNames": profileNames,
103 | "profileOneID":profileOneID,
104 | "profileTwoID":profileTwoID,
105 | "lastMessageId": lastMessageId,
106 | };
107 | }
108 |
109 | //Class that creates a Messages object
110 | class Messages {
111 | int chatroomID;
112 | int senderID;
113 | String text;
114 | String timeSent;
115 |
116 | //Constructor for a message object
117 | Messages({
118 | this.chatroomID,
119 | this.senderID,
120 | this.text,
121 | this.timeSent,
122 | });
123 |
124 | //Converts the JSON to a Message
125 | factory Messages.fromJsonGetMessages(Map parsedJson) {
126 | return Messages(
127 | chatroomID: parsedJson['chatroomID'],
128 | senderID: parsedJson['senderID'],
129 | text: parsedJson['text'],
130 | timeSent: parsedJson['timeSent'],
131 | );
132 | }
133 | //Converts the data to JSON
134 | Map toJson() => {
135 | "chatroomID": chatroomID,
136 | "senderID": senderID,
137 | "text": text,
138 | "timeSent": timeSent,
139 | };
140 | }
141 |
142 | //Class to get the text of a chat message
143 | class GetMessage{
144 | int id;
145 | int senderID;
146 | String text;
147 | String timeSent;
148 |
149 | //Constructs a GetMessage object that gives id, senderID, text, and timeSent
150 | GetMessage({
151 | this.id,
152 | this.senderID,
153 | this.text,
154 | this.timeSent,
155 | });
156 |
157 | //Converts the JSON to a GetMessage
158 | factory GetMessage.fromJsonGetMessages(Map parsedJson) {
159 | return GetMessage(
160 | id:parsedJson['id'],
161 | senderID: parsedJson['senderID'],
162 | text: parsedJson['text'],
163 | timeSent: parsedJson['timeSent'],
164 | );
165 | }
166 |
167 | //Converts the data to JSON
168 | Map toJson() => {
169 | "id:": id,
170 | "senderID": senderID,
171 | "text": text,
172 | "timeSent": timeSent,
173 | };
174 | }
175 |
176 | //Class that allows parsing of the profile ID's in chatroom
177 | class ProfileIDs {
178 | int profile1;
179 | int profile2;
180 | ProfileIDs({
181 | this.profile1,
182 | this.profile2,
183 | });
184 | factory ProfileIDs.fromJsonIDs(Map parsedJson) {
185 | return ProfileIDs(
186 | profile1: parsedJson['Profile 1'],
187 | profile2: parsedJson['Profile 2'],
188 | );
189 | }
190 | Map toJson() => {
191 | "Profile 1": profile1,
192 | "Profile 2": profile2,
193 | };
194 | }
195 |
196 | //Constructor for a ProfileNames object
197 | class ProfileNames {
198 | String profile1;
199 | String profile2;
200 | ProfileNames({
201 | this.profile1,
202 | this.profile2,
203 | });
204 |
205 | //Converts the JSON to a ProfileNames object
206 | factory ProfileNames.fromJsonNames(Map parsedJson) {
207 | return ProfileNames(
208 | profile1: parsedJson['Profile 1'],
209 | profile2: parsedJson['Profile 2'],
210 | );
211 | }
212 |
213 | //Converts the data to JSON
214 | Map toJson() => {
215 | "Profile 1": profile1,
216 | "Profile 2": profile2,
217 | };
218 | }
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/Profile.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.model;
2 |
3 | import javax.persistence.*;
4 | import java.io.Serializable;
5 | import java.util.Date;
6 | import java.text.SimpleDateFormat;
7 | import java.util.List;
8 | import java.util.ArrayList;
9 |
10 | /**
11 | * Class to set up the JPA Entity for the Profile table in the database
12 | */
13 | @Entity
14 | @Table(name = "profile")
15 | public class Profile implements Serializable{
16 | @Id
17 | @GeneratedValue(strategy = GenerationType.IDENTITY)
18 | @Column(name="profileID")
19 | private int id;
20 |
21 | private String name;
22 |
23 | @Column(name="EmailAddress")
24 | private String emailAddress;
25 |
26 | // Refers to address table
27 | // ** Leaving out ON UPDATE ON DELETE for now since they are defined in MySQL - will add later if needed.
28 | @OneToOne(cascade=CascadeType.REMOVE)
29 | @JoinColumn(name="AddressID")
30 | private Address address;
31 |
32 | @Column(name="CreatedDate")
33 | private Date createdDate;
34 |
35 | @OneToMany(mappedBy="profile", cascade=CascadeType.REMOVE)
36 | private List schedules = new ArrayList(); // Maintain bi-directional 1 to Many w/ Schedule
37 |
38 | @ManyToMany
39 | @JoinTable(name = "chatroomProfile",
40 | joinColumns = { @JoinColumn(name = "ProfileID") },
41 | inverseJoinColumns = { @JoinColumn(name = "ChatroomID") })
42 | private List chatrooms = new ArrayList(); //Profile is the "owner" side of the relationship
43 |
44 | @Transient
45 | private double distance;
46 | @Transient
47 | private double distanceRounded;
48 | @Transient
49 | private String schedulesString;
50 |
51 | /**
52 | * Default constructor for JPA.
53 | * It should not be used directly as no values will be initialized.
54 | */
55 | public Profile(){
56 |
57 | }
58 |
59 | public Profile(String name, String email, Address address, Date createdDate){
60 | this.name = name;
61 | this.emailAddress = email;
62 | this.address = address;
63 | this.createdDate = createdDate;
64 | }
65 |
66 | /**
67 | * Constructor used when matching is done.
68 | * @param name Name of the matched profile
69 | * @param email Email Address of the matched profile
70 | * @param address Address of the matched profile
71 | * @param distance Distance of the matched profile
72 | */
73 | public Profile(String name, String email, Address address, double distance, double distanceRounded){
74 | this.name = name;
75 | this.emailAddress = email;
76 | this.address = address;
77 | this.distance = distance;
78 | this.distanceRounded = distanceRounded;
79 | }
80 |
81 | /**
82 | * Returns the string representation for Profile.
83 | * @return the String representation for a Profile
84 | */
85 | public String toString(){
86 | SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
87 | return String.format("Name: %s %n Email: %s %n AddressID: %d %n Created Date: %s %n",
88 | name, emailAddress, address.toString(), sdf.format(createdDate));
89 | }
90 |
91 | /**
92 | * Gets the profile id.
93 | * @return the id
94 | */
95 | public int getId() {
96 | return id;
97 | }
98 |
99 | /**
100 | * Gets the name.
101 | * @return the name
102 | */
103 | public String getName() {
104 | return name;
105 | }
106 |
107 | /**
108 | * Gets the email.
109 | * @return the email
110 | */
111 | public String getEmail() {
112 | return emailAddress;
113 | }
114 |
115 | /**
116 | * Gets the address.
117 | * @return the address
118 | */
119 | public Address getAddress() {
120 | return address;
121 | }
122 |
123 | /**
124 | * Get the formatted date and time this profile was created.
125 | * Avoid using SimpleDateFormat as it is not thread-safe.
126 | * @return the createdDate as a formatted String.
127 | */
128 | public String getCreatedDate() {
129 | return String.format("%1$TD %1$TT", createdDate);
130 | }
131 |
132 | /**
133 | * Gets the schedules for a profile.
134 | * @return a list of schedules
135 | */
136 | public List getSchedules() {
137 | return schedules;
138 | }
139 |
140 | /**
141 | * Gets the chatrooms that this profile is in.
142 | * @return a list of chatrooms
143 | */
144 | public List getChatrooms() {
145 | return chatrooms;
146 | }
147 |
148 | /**
149 | * Gets the un-rounded distance to another profile.
150 | * @return the un-rounded distance.
151 | */
152 | public double getDistance() {return distance;}
153 |
154 | /**
155 | * Gets the rounded distance to another profile.
156 | * @return the rounded distance.
157 | */
158 | public double getDistanceRounded() {return distanceRounded;}
159 |
160 | /**
161 | * Gets a string that represents the list of schedules
162 | * @return a string that represents the list of schedules.
163 | */
164 | public String getSchedulesString() {return schedulesString;}
165 |
166 | /**
167 | * Sets the address.
168 | * @param address the address object to set to
169 | */
170 | public void setAddress(Address address) {
171 | this.address = address;
172 | }
173 |
174 | /**
175 | * Sets the email. Limit of 45 characters.
176 | * @param email the email to set
177 | */
178 | public void setEmail(String email) {
179 | this.emailAddress = email;
180 | }
181 |
182 | /**
183 | * Sets the name. Limit of 90 characters.
184 | * @param name the name to set
185 | */
186 | public void setName(String name) {
187 | this.name = name;
188 | }
189 |
190 | /**
191 | * Sets the schedule. Should only be used for displaying needs.
192 | * Note that this method cannot be used to commit schedule changes to the database - not the owner side of the relationship
193 | * between schedule and profile.
194 | *
195 | * @param schedules the schedules to set
196 | */
197 | public void setSchedules(List schedules) {
198 | this.schedules = schedules;
199 | }
200 |
201 | /**
202 | * Sets the string that represents a list of schedules.
203 | * @param string represents the list of schedules.
204 | */
205 | public void setSchedulesString(String string) {this.schedulesString = string;}
206 | }
207 |
--------------------------------------------------------------------------------
/ruber/lib/Main.dart:
--------------------------------------------------------------------------------
1 | /// Main.dart
2 | ///
3 | /// Purpose:
4 | /// The purpose of this file is to act as the main starting point
5 | /// of the app. It describes the Welcome screen which goes
6 | /// to the Google OAuth screen. This also includes the main
7 | /// menu screen which is the starting point of the app once the user
8 | /// is created.
9 |
10 |
11 | /// Imports
12 | import 'package:flutter/foundation.dart';
13 | import 'package:flutter/material.dart';
14 |
15 | import 'AppDrawer.dart';
16 | import 'AuthScreen.dart';
17 | import 'ChatRoomScreen.dart';
18 | import 'RideScreen.dart';
19 | import 'editschedule.dart';
20 | import 'profile.dart';
21 |
22 | var api_key = "AIzaSyDrHKl8IxB4cGXIoELXQOzzZwiH1xtsRf4";
23 |
24 | void main() => runApp(new RUber());
25 |
26 | class RUber extends StatelessWidget {
27 | @override
28 | Widget build(BuildContext context) {
29 | return MaterialApp(
30 | title: 'Ryde',
31 | debugShowCheckedModeBanner: false,
32 | home: WelcomeScreen());
33 | }
34 | }
35 |
36 | /// ==================== WELCOME SCREEN ====================== //
37 |
38 | class WelcomeScreen extends StatelessWidget {
39 | @override
40 | Widget build(BuildContext context) {
41 | return Scaffold(
42 | appBar: AppBar(
43 | title: Text('Welcome to Ryde'),
44 | centerTitle: true,
45 | automaticallyImplyLeading: false,
46 | ),
47 | body: Center(
48 | child: Column(
49 | children: [
50 | Container(
51 | margin: EdgeInsets.only(top: 15.0, bottom: 15.0),
52 | child: Text(
53 | 'Ryde',
54 | style: TextStyle(
55 | fontWeight: FontWeight.bold,
56 | color: Colors.orange,
57 | fontSize: 80.0,
58 | fontFamily: "Audiowide"),
59 | ),
60 | ),
61 | Image.network(
62 | 'https://www.tlcrentalmarketplace.com/wp-content/uploads/2018/03/rideshare.png',
63 | height: 150,
64 | ),
65 | Container(
66 | margin: EdgeInsets.only(
67 | top: 40.0, left: 15.0, right: 15.0, bottom: 15.0),
68 | child: Text(
69 | 'Exclusively for Rowan University students\n\n Commute with other students near you\n\n Match based on class schedule and distance\n\n Save gas and the planet!',
70 | style: TextStyle(
71 | color: Colors.black,
72 | fontSize: 18.0,
73 | fontFamily: "",
74 | ),
75 | textAlign: TextAlign.center,
76 | ),
77 | ),
78 | MaterialButton(
79 | child: Text(
80 | "Start",
81 | style: TextStyle(fontSize: 20),
82 | ),
83 | textColor: Colors.white,
84 | color: Colors.blue,
85 | minWidth: 100.0,
86 | height: 70.0,
87 | onPressed: () {
88 | Navigator.push(context,
89 | MaterialPageRoute(builder: (context) => MyAuthScreen()));
90 | },
91 | ),
92 | ],
93 | ),
94 | ));
95 | }
96 | }
97 |
98 | /// =========================== END WELCOME SCREEN ====================== //
99 |
100 | class MainScreen extends StatelessWidget {
101 | final GlobalKey _scaffoldKey = new GlobalKey();
102 |
103 | final String title;
104 |
105 | MainScreen({Key key, this.title}) : super(key: key);
106 |
107 | @override
108 | Widget build(BuildContext context) {
109 | return WillPopScope(
110 | onWillPop: () async => false,
111 | child: Scaffold(
112 | appBar: AppBar(
113 | title: Text('Ryde',
114 | style: TextStyle(
115 | fontSize: 30,
116 | fontFamily: "Audiowide",
117 | color: Colors.white)),
118 | centerTitle: true,
119 | leading: IconButton(
120 | icon: new Image.network(
121 | 'https://www.tlcrentalmarketplace.com/wp-content/uploads/2018/03/rideshare.png'),
122 | onPressed: () => _scaffoldKey.currentState.openDrawer()),
123 | ),
124 | drawer: launchAppDrawer(context),
125 | key: _scaffoldKey,
126 | body: Center(
127 | child: Column(children: [
128 | Image.network(
129 | 'https://www.tlcrentalmarketplace.com/wp-content/uploads/2018/03/rideshare.png',
130 | height: 150,
131 | ),
132 | ListTile(
133 | leading: Icon(Icons.directions_car),
134 | title: Text('New Ryde'),
135 | contentPadding: new EdgeInsets.only(left: 100.0, top: 30.0),
136 | onTap: () {
137 | Navigator.push(
138 | context,
139 | MaterialPageRoute(
140 | builder: (context) => launchRideScreen()));
141 | }),
142 | ListTile(
143 | leading: Icon(Icons.message),
144 | title: Text('Messages'),
145 | contentPadding: new EdgeInsets.only(left: 100.0),
146 | onTap: () {
147 | Navigator.push(
148 | context,
149 | MaterialPageRoute(builder: (context) => ChatRoomScreen()),
150 | );
151 | },
152 | ),
153 | ListTile(
154 | leading: Icon(Icons.account_box),
155 | title: Text('Profile'),
156 | contentPadding: new EdgeInsets.only(left: 100.0),
157 | onTap: () {
158 | Navigator.push(
159 | context,
160 | MaterialPageRoute(builder: (context) => ProfileScreen()),
161 | );
162 | },
163 | ),
164 | ListTile(
165 | leading: Icon(Icons.schedule),
166 | title: Text('Schedule'),
167 | contentPadding: new EdgeInsets.only(left: 100.0),
168 | onTap: () {
169 | Navigator.push(
170 | context,
171 | MaterialPageRoute(
172 | builder: (context) => ScheduleForm()));
173 | },
174 | )
175 | ]),
176 | )));
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/Search.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber;
2 |
3 | import com.rowan.ruber.model.*;
4 | import com.rowan.ruber.repository.*;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Component;
7 | import org.springframework.jdbc.core.JdbcTemplate;
8 | import org.springframework.jdbc.core.RowMapper;
9 | import org.springframework.jdbc.core.ResultSetExtractor;
10 | import java.sql.ResultSet;
11 |
12 | import java.sql.SQLException;
13 | import java.util.List;
14 | import java.util.Iterator;
15 |
16 | @Component
17 | public class Search{
18 |
19 | @Autowired
20 | JdbcTemplate jdbcTemplate;
21 |
22 | /**
23 | * Gets a list of profiles that match with the user
24 | *
25 | * @param repo the repository that stores the profiles
26 | * @param profileID id of the user
27 | * @param radius search radius in miles
28 | * @return a list of profiles that match with the user based on distance and schedule
29 | */
30 | public List getMatches(ProfileRepository repo, int profileID, int radius) {
31 | // Gets the profile object from the repository
32 | Profile profile = repo.findById(profileID).get();
33 | List matchedProfiles = getMatchesByDistance(profileID, profile.getAddress().getLatitude(), profile.getAddress().getLongitude(), radius);
34 | Iterator profileIterator = matchedProfiles.iterator();
35 | while(profileIterator.hasNext()) {
36 | Profile checkProfile = profileIterator.next();
37 | boolean foundMatchedProfile = false;
38 | String matchedSchedulesString = "";
39 | Iterator scheduleIterator = checkProfile.getSchedules().iterator();
40 | // Checks though each schedule and looks for a match
41 | while(scheduleIterator.hasNext())
42 | {
43 | Schedule checkSchedule = scheduleIterator.next();
44 | boolean foundMatchedSchedule = false;
45 | for (Schedule s: profile.getSchedules()) {
46 | if(checkSchedule.updateWithMatchedTime(s))
47 | {
48 | foundMatchedSchedule = true;
49 | foundMatchedProfile = true;
50 | }
51 | }
52 | if(foundMatchedSchedule)
53 | matchedSchedulesString += Day.toCharacter(checkSchedule.getDay()) + " ";
54 | else
55 | scheduleIterator.remove();
56 | }
57 | if(foundMatchedProfile)
58 | checkProfile.setSchedulesString(matchedSchedulesString.trim());
59 | else
60 | profileIterator.remove(); //profile is removed from the list if no matches are found with the schedules
61 |
62 | }
63 | return matchedProfiles;
64 | }
65 |
66 | /**
67 | * Gets a list of profiles that are within a specified radius of the user
68 | *
69 | * @param profileID id of the user
70 | * @param lat latitude that corresponds to the user's address
71 | * @param lng longitude that corresponds to the user's address
72 | * @param radius search radius in miles
73 | * @return a list of profiles that match with the user based on distance.
74 | */
75 | private List getMatchesByDistance(int profileID, double lat, double lng, double radius){
76 | List matchedProfiles = jdbcTemplate.query(
77 | "SELECT *, ( 3959* ACOS( COS( RADIANS(?) ) * COS( RADIANS( Latitude ) ) * COS( RADIANS( Longitude ) - RADIANS(?) ) + SIN( RADIANS(?) ) * SIN( RADIANS( Latitude ) ) ) ) AS Distance FROM address JOIN profile USING (AddressID) WHERE ProfileID <> ? HAVING Distance < ? ORDER BY Distance;",
78 | new Object[] {lat, lng, lat, profileID, radius},
79 | new ProfileRowMapper());
80 | for (Profile profile : matchedProfiles ) {
81 | List schedules = jdbcTemplate.query(
82 | "SELECT * FROM schedule JOIN profile USING (ProfileID) WHERE EmailAddress = ?;",
83 | new Object[]{profile.getEmail()},
84 | new ScheduleRowMapper());
85 | schedules.sort(new SortByDay());
86 | for (Schedule schedule : schedules)
87 | {
88 | schedule.setProfile(profile);
89 | }
90 | profile.setSchedules(schedules);
91 | }
92 | return matchedProfiles;
93 | }
94 |
95 | /**
96 | * Truncates a double to the nearest hundredth
97 | * @param d double to be truncated
98 | * @return truncated double
99 | */
100 | private double Round(double d)
101 | {
102 | int i = (int)(d * 100);
103 | return (i + 0.0)/100;
104 | }
105 |
106 | public class ProfileResultSetExtractor implements ResultSetExtractor {
107 | @Override
108 | public Object extractData(ResultSet rs) throws SQLException {
109 | return new Profile(rs.getString("Name"),
110 | rs.getString("EmailAddress"),
111 | new Address(rs.getString("StreetAddress"),
112 | rs.getString("City"),
113 | rs.getString("State"),
114 | rs.getString("ZipCode"),
115 | rs.getDouble("Latitude"),
116 | rs.getDouble("Longitude")
117 | ),
118 | rs.getDouble("Distance"),
119 | Round(rs.getDouble("Distance"))
120 | );
121 | }
122 | }
123 |
124 | public class ProfileRowMapper implements RowMapper{
125 | @Override
126 | public Object mapRow(ResultSet rs, int line) throws SQLException {
127 | ProfileResultSetExtractor extractor = new ProfileResultSetExtractor();
128 | return extractor.extractData(rs);
129 | }
130 | }
131 |
132 | public class ScheduleResultSetExtractor implements ResultSetExtractor{
133 | @Override
134 | public Object extractData(ResultSet rs) throws SQLException {
135 | return new Schedule(Day.valueOf(rs.getString("Day")),
136 | rs.getTime("GoingToRangeStart").toLocalTime(),
137 | rs.getTime("GoingToRangeEnd").toLocalTime(),
138 | rs.getTime("LeavingRangeStart").toLocalTime(),
139 | rs.getTime("LeavingRangeEnd").toLocalTime()
140 | );
141 | }
142 | }
143 |
144 | public class ScheduleRowMapper implements RowMapper{
145 | @Override
146 | public Object mapRow(ResultSet rs, int line) throws SQLException {
147 | ScheduleResultSetExtractor extractor = new ScheduleResultSetExtractor();
148 | return extractor.extractData(rs);
149 | }
150 | }
151 | }
--------------------------------------------------------------------------------
/server/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/server/bin/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/server/src/main/java/com/rowan/ruber/model/Schedule.java:
--------------------------------------------------------------------------------
1 | package com.rowan.ruber.model;
2 |
3 | import java.io.Serializable;
4 | import java.time.LocalTime;
5 | import java.util.Comparator;
6 | import javax.persistence.Column;
7 | import javax.persistence.Entity;
8 | import javax.persistence.EnumType;
9 | import javax.persistence.Enumerated;
10 | import javax.persistence.GeneratedValue;
11 | import javax.persistence.GenerationType;
12 | import javax.persistence.Id;
13 | import javax.persistence.JoinColumn;
14 | import javax.persistence.ManyToOne;
15 | import javax.persistence.Table;
16 |
17 | import com.fasterxml.jackson.annotation.JsonBackReference;
18 |
19 | /**
20 | * Class to set up the JPA Entity for the Schedule table in the database.
21 | * Each schedule is represented by a day of the week and time ranges for going and leaving.
22 | */
23 | @Entity
24 | @Table(name="schedule")
25 | public class Schedule implements Serializable {
26 | @Id
27 | @GeneratedValue(strategy = GenerationType.IDENTITY)
28 | @Column(name = "scheduleID")
29 | private int id;
30 |
31 | @ManyToOne
32 | @JsonBackReference
33 | @JoinColumn(name = "ProfileID")
34 | private Profile profile;
35 |
36 | @Enumerated(EnumType.STRING)
37 | @Column(name = "Day")
38 | private Day day;
39 |
40 | @Column(name = "GoingToRangeStart")
41 | private LocalTime goingToStart;
42 |
43 | @Column(name = "GoingToRangeEnd")
44 | private LocalTime goingToEnd;
45 |
46 | @Column(name = "LeavingRangeStart")
47 | private LocalTime leavingStart;
48 |
49 | @Column(name = "LeavingRangeEnd")
50 | private LocalTime leavingEnd;
51 |
52 | /**
53 | * Default constructor for JPA.
54 | * It should not be used directly as no values will be initialized.
55 | */
56 | public Schedule() {
57 |
58 | }
59 |
60 | /**
61 | * Constructor that takes all parameters.
62 | *
63 | * @param profile the profile for this schedule
64 | * @param day the specified day
65 | * @param goingToRangeStart the start of the going to time
66 | * @param goingToRangeEnd the end of the going to time
67 | * @param leavingRangeStart the start of the leaving time
68 | * @param leavingRangeEnd the end of the leaving time
69 | */
70 | public Schedule(Profile profile, Day day, LocalTime goingToRangeStart, LocalTime goingToRangeEnd,
71 | LocalTime leavingRangeStart, LocalTime leavingRangeEnd) {
72 | this.profile = profile;
73 | this.day = day;
74 | this.goingToStart = goingToRangeStart;
75 | this.goingToEnd = goingToRangeEnd;
76 | this.leavingStart = leavingRangeStart;
77 | this.leavingEnd = leavingRangeEnd;
78 | }
79 |
80 | /**
81 | * Constructor that takes all parameters except for profile.
82 | *
83 | * @param day the specified day
84 | * @param goingToRangeStart the start of the going to time
85 | * @param goingToRangeEnd the end of the going to time
86 | * @param leavingRangeStart the start of the leaving time
87 | * @param leavingRangeEnd the end of the leaving time
88 | */
89 | public Schedule(Day day, LocalTime goingToRangeStart, LocalTime goingToRangeEnd,
90 | LocalTime leavingRangeStart, LocalTime leavingRangeEnd) {
91 | this.day = day;
92 | this.goingToStart = goingToRangeStart;
93 | this.goingToEnd = goingToRangeEnd;
94 | this.leavingStart = leavingRangeStart;
95 | this.leavingEnd = leavingRangeEnd;
96 | }
97 |
98 | /**
99 | * Return the id associated with this profile
100 | *
101 | * @return profile id
102 | */
103 | public int getId() {
104 | return id;
105 | }
106 |
107 | /**
108 | * Return the profile associated with this schedule.
109 | *
110 | * @return the profile
111 | */
112 | public Profile getProfile() {
113 | return profile;
114 | }
115 |
116 | /**
117 | * Return the day associated with this schedule.
118 | *
119 | * @return the day
120 | */
121 | public Day getDay() {
122 | return day;
123 | }
124 |
125 | /**
126 | * Sets the day for the schedule to the given day.
127 | *
128 | * @param day the day to set
129 | */
130 | public void setDay(Day day) {
131 | this.day = day;
132 | }
133 |
134 | /**
135 | * Sets the profile for the schedule to the given profile
136 | *
137 | * @param profile the profile to set
138 | */
139 | public void setProfile(Profile profile) {
140 | this.profile = profile;
141 | }
142 |
143 | /**
144 | * Return the going to start time for the schedule.
145 | *
146 | * @return the goingToStart
147 | */
148 | public LocalTime getGoingToStart() {
149 | return goingToStart;
150 | }
151 |
152 | /**
153 | * Sets the going to start time to the given time.
154 | *
155 | * @param goingToStart the goingToStart to set
156 | */
157 | public void setGoingToStart(LocalTime goingToStart) {
158 | this.goingToStart = goingToStart;
159 | }
160 |
161 | /**
162 | * Return the going to end time for the schedule.
163 | *
164 | * @return the goingToEnd
165 | */
166 | public LocalTime getGoingToEnd() {
167 | return goingToEnd;
168 | }
169 |
170 | /**
171 | * Sets the going to end time to the given time.
172 | *
173 | * @param goingToEnd the goingToEnd to set
174 | */
175 | public void setGoingToEnd(LocalTime goingToEnd) {
176 | this.goingToEnd = goingToEnd;
177 | }
178 |
179 | /**
180 | * Return the leaving start time for the schedule.
181 | *
182 | * @return the leavingStart
183 | */
184 | public LocalTime getLeavingStart() {
185 | return leavingStart;
186 | }
187 |
188 | /**
189 | * Sets the leaving start time to the given time.
190 | *
191 | * @param leavingStart the leavingStart to set
192 | */
193 | public void setLeavingStart(LocalTime leavingStart) {
194 | this.leavingStart = leavingStart;
195 | }
196 |
197 | /**
198 | * Get the leaving end time for the schedule.
199 | *
200 | * @return Return the leaving end time for the schedule.
201 | */
202 | public LocalTime getLeavingEnd() {
203 | return leavingEnd;
204 | }
205 |
206 | /**
207 | * Sets the leaving end time to the given time.
208 | *
209 | * @param leavingEnd the leavingEnd to set
210 | */
211 | public void setLeavingEnd(LocalTime leavingEnd) {
212 | this.leavingEnd = leavingEnd;
213 | }
214 |
215 | /**
216 | * Return the String representation of a schedule. Currently a stub.
217 | *
218 | * @return a String for this schedule
219 | */
220 | @Override
221 | public String toString() {
222 | return "STUB FOR SCHEDULE";
223 | }
224 |
225 | /**
226 | * Updates this schedule with the matched times between this schedule and the schedule passed in.
227 | *
228 | * @param schedule the schedule to be compared
229 | * @return true if there was a match, false if there was not a match
230 | */
231 | public boolean updateWithMatchedTime(Schedule schedule) {
232 | if ((day == schedule.getDay())
233 | && (goingToEnd.compareTo(schedule.getGoingToStart()) >= 0)
234 | && (schedule.getGoingToEnd().compareTo(goingToStart) >= 0)
235 | && (leavingEnd.compareTo(schedule.getLeavingStart()) >= 0)
236 | && (schedule.getLeavingEnd().compareTo(leavingStart) >= 0)) {
237 | if (goingToStart.isBefore(schedule.getGoingToStart()))
238 | goingToStart = schedule.getGoingToStart();
239 | if (goingToEnd.isAfter(schedule.getGoingToEnd()))
240 | goingToEnd = schedule.getGoingToEnd();
241 | if (leavingStart.isBefore(schedule.getLeavingStart()))
242 | leavingStart = schedule.getLeavingStart();
243 | if (leavingEnd.isAfter(schedule.getLeavingEnd()))
244 | leavingEnd = schedule.getLeavingEnd();
245 | return true;
246 | }
247 | return false;
248 | }
249 |
250 |
251 | }
252 |
253 |
--------------------------------------------------------------------------------
/ruber/lib/matches_screen.dart:
--------------------------------------------------------------------------------
1 | /// matches_screen.dart
2 | ///
3 | /// Purpose:
4 | /// The purpose of this file is to show the matches found depending on the
5 | /// radius set by the user. It shows the user name, the days matched, and
6 | /// the distance they are away from the main user. It uses a listview builder
7 | /// which is a dynamic list created using the length of the returned match
8 | /// profiles JSON.
9 |
10 | /// Imports
11 | import 'dart:async';
12 | import 'dart:async' show Future;
13 | import 'dart:convert';
14 | import 'dart:io';
15 |
16 | import 'package:flutter/material.dart';
17 | import 'package:http/http.dart' as http;
18 | import 'package:ruber/AppDrawer.dart';
19 | import 'package:ruber/Constants.dart';
20 | import 'package:shared_preferences/shared_preferences.dart';
21 |
22 | import 'ChatRoomScreen.dart';
23 | import 'ChatroomModel.dart';
24 | import 'ProfileModel.dart';
25 |
26 | /// Variable where the returned matched profiles are stored
27 | List profileMatches;
28 |
29 | getId() async {
30 | int id;
31 | if (id == 0 || id == null) {
32 | SharedPreferences prefs = await SharedPreferences.getInstance();
33 | id = prefs.getInt("id");
34 | }
35 | ;
36 | return id;
37 | }
38 |
39 | getProfile() {
40 | return profileMatches;
41 | }
42 |
43 | class matchesScreen extends StatefulWidget {
44 | @override
45 | matchesScreenState createState() => new matchesScreenState();
46 | }
47 | /*
48 | * This method returns the users matches.
49 | */
50 | class matchesScreenState extends State {
51 | Future> getData() async {
52 | int userId = await getId();
53 | SharedPreferences prefs = await SharedPreferences.getInstance();
54 | int radius = prefs.get("radius");
55 | var response = await http.get(
56 | Uri.encodeFull(BASE_URL + '/rides/matching/$userId/$radius'),
57 | headers: {"Accept": "application/json"});
58 |
59 | this.setState(() {
60 | profileMatches = json.decode(response.body);
61 | });
62 |
63 | return allPostsFromJson(response.body);
64 | }
65 |
66 | @override
67 | void initState() {
68 | super.initState();
69 | this.getData();
70 | }
71 |
72 | /// This is the widget which is called on when the user clicks a match
73 | /// It shows the full profile (without address), to the user and it
74 | /// allows the user to send them a ride request
75 |
76 | Widget expandProfile(BuildContext context, int index) {
77 | return Scaffold(
78 | appBar: AppBar(
79 | title: Text(profileMatches[index]["name"]), // Name of the person
80 | centerTitle: true,
81 | ),
82 | body: Center(
83 | child: ListView(
84 | children: [
85 | Container(
86 | margin: EdgeInsets.only(
87 | bottom: 0.0, left: 90.0, right: 90.0, top: 15.0),
88 | width: 150.0,
89 | height: 160.0,
90 | child: new CircleAvatar(
91 | child: new Text(
92 | profileMatches[index]["name"].toString().substring(0, 1),
93 | style: TextStyle(fontSize: 65),
94 | ))),
95 |
96 | /// Full Name
97 |
98 | Container(
99 | margin: EdgeInsets.only(top: 15.0),
100 | child: Text('Full Name',
101 | textAlign: TextAlign.center,
102 | style: TextStyle(
103 | fontWeight: FontWeight.bold,
104 | fontSize: 20.0,
105 | fontFamily: 'Helvetica',
106 | color: Colors.blueAccent))),
107 |
108 | Container(
109 | child: Center(child: Text(profileMatches[index]["name"])),
110 | ),
111 |
112 | Container(
113 | margin: EdgeInsets.only(top: 15.0),
114 | child: Text('Email',
115 | textAlign: TextAlign.center,
116 | style: TextStyle(
117 | fontWeight: FontWeight.bold,
118 | fontSize: 20.0,
119 | fontFamily: 'Helvetica',
120 | color: Colors.deepOrange)),
121 | ),
122 |
123 | Container(
124 | child: Center(child: Text(profileMatches[index]["email"]))),
125 |
126 | Container(
127 | margin: EdgeInsets.only(top: 15.0),
128 | child: Text(
129 | 'Distance',
130 | textAlign: TextAlign.center,
131 | style: TextStyle(
132 | fontWeight: FontWeight.bold,
133 | fontSize: 20.0,
134 | fontFamily: 'Helvetica',
135 | color: Colors.deepPurpleAccent),
136 | )),
137 |
138 | Container(
139 | child: Center(
140 | child: Text(
141 | profileMatches[index]["distanceRounded"].toString() +
142 | " miles"))),
143 |
144 | Container(
145 | margin: EdgeInsets.only(top: 20.0),
146 | child: Center(
147 | child: RaisedButton(
148 | color: Colors.blue,
149 | textColor: Colors.white,
150 | child: Text('Send Ride Request!'),
151 | onPressed: () {
152 | String matchEmail = profileMatches[index]["email"];
153 | getMatchesId(matchEmail).then((otherId) {
154 | getMyProfileId().then((myId) {
155 | print(myId);
156 | ChatRoom newRoom = new ChatRoom(
157 | profileOneID: myId, profileTwoID: otherId);
158 | createChatRoom(newRoom).then((response) {
159 | if (response.statusCode > 200)
160 | print(response.body);
161 | else
162 | print(response.statusCode);
163 | Navigator.push(
164 | context,
165 | MaterialPageRoute(
166 | builder: (context) => ChatRoomScreen()));
167 | }).catchError((error) {
168 | print('error : $error');
169 | });
170 | }).catchError((error) {
171 | print('unable to get id. error : $error');
172 | });
173 | });
174 | },
175 | )))
176 | ],
177 | ),
178 | ));
179 | }
180 |
181 | /// This is the main widget that is displayed. It shows a dynamically
182 | /// created list based on the profilematches list. It shows the
183 | /// name, distance, and matched day.
184 |
185 | @override
186 | Widget build(BuildContext context) {
187 | return Scaffold(
188 | appBar: AppBar(title: Text('Matches'), centerTitle: true),
189 | drawer: launchAppDrawer(context),
190 | body: ListView.builder(
191 | itemCount: profileMatches == null ? 0 : profileMatches.length,
192 | itemBuilder: (BuildContext context, int index) {
193 | return new ListTile(
194 | leading: Container(
195 | margin: EdgeInsets.only(
196 | bottom: 0.0, left: 5.0, right: 5.0, top: 0.0),
197 | width: 40.0,
198 | height: 50.0,
199 | child: new CircleAvatar(
200 | child: new Text(
201 | profileMatches[index]["name"].toString().substring(0, 1),
202 | style: TextStyle(fontSize: 20),
203 | ))),
204 | title: Text(profileMatches[index]["name"]),
205 | subtitle: Text(
206 | profileMatches[index]["distanceRounded"].toString() +
207 | " miles " +
208 | profileMatches[index]["schedulesString"].toString()),
209 | onTap: () {
210 | Navigator.push(
211 | context,
212 | MaterialPageRoute(
213 | builder: (context) => expandProfile(context, index)));
214 | },
215 | );
216 | }));
217 | }
218 | }
219 |
220 | /*
221 | * This method creates a new chatroom for users that match.
222 | */
223 | Future createChatRoom(ChatRoom chatroom) async {
224 | int userId = await getId();
225 | //print(userId);
226 | String newMessageUrl = BASE_URL + '/rides/chatroom/new';
227 | final response = await http.post('$newMessageUrl',
228 | headers: {
229 | HttpHeaders.contentTypeHeader: 'application/json',
230 | HttpHeaders.authorizationHeader: ''
231 | },
232 | body: chatroomPostToJson(chatroom));
233 | print(response.body);
234 | return response;
235 | }
236 | /*
237 | * This method returns the users Id using their email.
238 | */
239 |
240 |
241 | Future getMatchesId(String tempEmail) async {
242 | String addressUrl = BASE_URL + '/rides/profile/getmyid/$tempEmail';
243 | final response2 = await http.get(addressUrl);
244 | var res = response2.body;
245 | await setMatchId(int.parse(res));
246 | print(res);
247 | return int.parse(res);
248 | }
249 |
250 | int matchId;
251 | /*
252 | * This method finds the id of the user they matched with.
253 | */
254 | getMatchId() async {
255 | SharedPreferences prefs = await SharedPreferences.getInstance();
256 | int tempId = prefs.getInt("matchID");
257 | if (tempId != 0 && tempId != null) {
258 | matchId = tempId;
259 | }
260 |
261 | return matchId;
262 | }
263 |
264 | getMatchIdInt() {
265 | return matchId;
266 | }
267 |
268 | setMatchId(int newId) async {
269 | if (newId != null && newId != 0) {
270 | SharedPreferences prefs = await SharedPreferences.getInstance();
271 | prefs.setInt("matchID", newId);
272 | //print(newId);
273 | matchId = newId;
274 | }
275 | }
276 |
277 | int id;
278 | /*
279 | * This method returns the users id from shared preferences.
280 | */
281 | Future getMyProfileId() async {
282 | SharedPreferences prefs = await SharedPreferences.getInstance();
283 | int tempId = prefs.getInt("id");
284 | if (tempId != 0 && tempId != null) {
285 | id = tempId;
286 | }
287 |
288 | return id;
289 | }
290 |
291 | getMyId() {
292 | return id;
293 | }
294 |
--------------------------------------------------------------------------------
/ruber/lib/AuthScreen.dart:
--------------------------------------------------------------------------------
1 | /// AuthScreen.dart
2 | ///
3 | /// Purpose:
4 | /// This file is used for the OAuth functionality for the application.
5 | /// It uses the Google OAuth API to authenticate Rowan users. This handles
6 | /// all GUI for the login, the password management, and we receive a email,
7 | /// full name, and a profile picture from Google as a returned object.
8 |
9 | /// Mandatory Copyright Information
10 | // Copyright 2017 The Chromium Authors. All rights reserved.
11 | // Use of this source code is governed by a BSD-style license that can be
12 | // found in the LICENSE file.
13 |
14 | /// Imports
15 | import 'dart:async';
16 | import 'dart:async' show Future;
17 | import 'dart:convert';
18 | import 'dart:io';
19 |
20 | import 'package:firebase_auth/firebase_auth.dart';
21 | import 'package:flutter/material.dart';
22 | import 'package:google_sign_in/google_sign_in.dart';
23 | import 'package:http/http.dart' as http;
24 | import 'package:ruber/Constants.dart';
25 | import 'package:shared_preferences/shared_preferences.dart';
26 |
27 | import 'Main.dart';
28 | import 'ProfileModel.dart';
29 | import 'UserModel.dart';
30 | import 'initialaddaddress.dart';
31 |
32 |
33 | /// Global variables which are set to the return values from Google
34 |
35 | final FirebaseAuth _auth = FirebaseAuth.instance;
36 | final GoogleSignIn _googleSignIn = GoogleSignIn();
37 |
38 | String userName;
39 | String firstName;
40 | String userProfilePic;
41 | List profileList;
42 | int id;
43 | Future _message = Future.value('');
44 | String emailAddress = "";
45 |
46 | /// Getter and setter methods for the global variables
47 |
48 | getUserProfilePic() async {
49 | SharedPreferences prefs = await SharedPreferences.getInstance();
50 | String imageUrl = prefs.getString("photo");
51 | return imageUrl;
52 | }
53 |
54 | getUserName() {
55 | return userName;
56 | }
57 |
58 | getFirstName() {
59 | return firstName;
60 | }
61 |
62 | setUserProfilePic(String newPhotoUrl) async {
63 | userProfilePic = newPhotoUrl;
64 | SharedPreferences prefs = await SharedPreferences.getInstance();
65 | prefs.setString("photo", newPhotoUrl);
66 | }
67 |
68 | setFirstName(String tempUserName) async {
69 | if (tempUserName.contains(" "))
70 | tempUserName = tempUserName.substring(0, tempUserName.indexOf(" "));
71 | SharedPreferences prefs = await SharedPreferences.getInstance();
72 | prefs.setString("username", tempUserName);
73 | firstName = tempUserName;
74 | }
75 |
76 | setUserName(String tempName) async {
77 | SharedPreferences prefs = await SharedPreferences.getInstance();
78 | prefs.setString("name", tempName);
79 | userName = tempName;
80 | }
81 |
82 | getMyUserName() async {
83 | SharedPreferences prefs = await SharedPreferences.getInstance();
84 | String userName = prefs.getString("username");
85 | return userName;
86 | }
87 |
88 | getEmailAddress() {
89 | return emailAddress;
90 | }
91 |
92 | setEmailAddress(String newEmail) async {
93 | emailAddress = newEmail;
94 | SharedPreferences prefs = await SharedPreferences.getInstance();
95 | prefs.setString("email", newEmail);
96 | }
97 |
98 | /// The MyAuthScreen class is a StatefulWidget which is extended by
99 | /// the _MyAuthScreenState class.
100 | /// The build Widget handles the GUI screen for the login and handles
101 | /// the flow of the application from one screen to another
102 | class MyAuthScreen extends StatefulWidget {
103 | @override
104 | _MyAuthScreenState createState() => _MyAuthScreenState();
105 | }
106 |
107 | class _MyAuthScreenState extends State {
108 | String verificationId;
109 |
110 | Future _testSignInWithGoogle() async {
111 | final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
112 | final GoogleSignInAuthentication googleAuth =
113 | await googleUser.authentication;
114 | final FirebaseUser user = await _auth.signInWithGoogle(
115 | accessToken: googleAuth.accessToken,
116 | idToken: googleAuth.idToken,
117 | );
118 | assert(user.email != null);
119 | assert(user.displayName != null);
120 | assert(!user.isAnonymous);
121 | assert(await user.getIdToken() != null);
122 |
123 | String tempName = user.displayName.toString();
124 | String newPhotoUrl = user.photoUrl.toString();
125 | String tempEmail = user.email.toString();
126 |
127 | setUserName(tempName);
128 | setFirstName(tempName);
129 | setUserProfilePic(newPhotoUrl);
130 | setEmailAddress(tempEmail);
131 |
132 | final FirebaseUser currentUser = await _auth.currentUser();
133 | assert(user.uid == currentUser.uid);
134 |
135 | print(getId().toString());
136 | SharedPreferences prefs = await SharedPreferences.getInstance();
137 | int tempId = prefs.getInt("id");
138 | print("temp id: " + tempId.toString());
139 |
140 | if (tempId == null) {
141 | NewUser tempUser = NewUser(name: tempName, email: tempEmail);
142 |
143 | createUser(tempUser).then((response) {
144 | if (response.statusCode > 200) {
145 | print(tempEmail);
146 | print(response.body);
147 | } else
148 | print(response.statusCode);
149 | }).catchError((error) {
150 | print('error : $error');
151 | });
152 |
153 | Navigator.pop(context);
154 |
155 | Navigator.push(
156 | context,
157 | MaterialPageRoute(
158 | builder: (context) => InitialAddressForm(
159 | emailAddress)));
160 | } else {
161 | Navigator.pop(context);
162 |
163 | Navigator.push(
164 | context, MaterialPageRoute(builder: (context) => MainScreen()));
165 |
166 | _loggedIn();
167 | }
168 |
169 | return 'signInWithGoogle succeeded: $user';
170 | }
171 |
172 | @override
173 | Widget build(BuildContext context) {
174 | return Scaffold(
175 | appBar: AppBar(
176 | title: Text('Login to Continue'),
177 | centerTitle: true,
178 | ),
179 | body: Center(
180 | child: Column(
181 | children: [
182 | Image.network(
183 | 'https://www.rowan.edu/home/sites/default/files/styles/basic_page_banner_image/public/sitecontent/page/campuscalendar_page.jpg?itok=W7vURkjO',
184 | ),
185 | MaterialButton(
186 | onPressed: null,
187 | child: const Text(
188 | 'Click "Sign in" below to Log in with your Rowan Gmail Account',
189 | textAlign: TextAlign.center,
190 | ),
191 | textColor: Colors.white,
192 | minWidth: 200.0,
193 | height: 100.0,
194 | ),
195 | MaterialButton(
196 | child: Row(
197 | mainAxisAlignment: MainAxisAlignment.center,
198 | children: [
199 | Image.network(
200 | 'https://pbs.twimg.com/profile_images/1057899591708753921/PSpUS-Hp_400x400.jpg',
201 | height: 70,
202 | width: 65),
203 | Text(
204 | ' Sign into Ryde with Google',
205 | style: TextStyle(fontSize: 19),
206 | ),
207 | ]),
208 | textColor: Colors.white,
209 | color: Colors.blue,
210 | minWidth: 150.0,
211 | height: 100.0,
212 | onPressed: () {
213 | setState(() {
214 | _message = _testSignInWithGoogle();
215 | emailAddress = getEmailAddress();
216 | });
217 | },
218 | ),
219 | ],
220 | ),
221 | ),
222 | );
223 | }
224 |
225 | Future createUser(NewUser user) async {
226 | String updateUrl = BASE_URL + '/rides/profile/new';
227 | final response = await http.post('$updateUrl',
228 | headers: {
229 | HttpHeaders.contentTypeHeader: 'application/json',
230 | HttpHeaders.authorizationHeader: ''
231 | },
232 | body: userToJson(user));
233 | return response;
234 | }
235 |
236 | Future _loggedIn() async {
237 | return showDialog(
238 | context: context,
239 | barrierDismissible: true,
240 | builder: (BuildContext context) {
241 | return AlertDialog(
242 | title: Text(
243 | 'Login Successful!',
244 | textAlign: TextAlign.center,
245 | style: TextStyle(fontWeight: FontWeight.bold, fontSize: 22),
246 | ),
247 | content: SingleChildScrollView(
248 | child: ListBody(
249 | children: [
250 | Text(
251 | 'Welcome Back, ' + getFirstName() + '!',
252 | textAlign: TextAlign.center,
253 | style: TextStyle(color: Colors.blue, fontSize: 18),
254 | ),
255 | Text(' '),
256 | Container(
257 | margin: EdgeInsets.only(
258 | bottom: 0.0, left: 40.0, right: 40.0, top: 0.0),
259 | width: 90.0,
260 | height: 150.0,
261 | decoration: new BoxDecoration(
262 | shape: BoxShape.circle,
263 | image: new DecorationImage(
264 | fit: BoxFit.fill,
265 | image: NetworkImage(userProfilePic)))),
266 | Text(' '),
267 | Text(
268 | 'Google Account',
269 | textAlign: TextAlign.center,
270 | style: TextStyle(
271 | color: Colors.blue, fontWeight: FontWeight.bold),
272 | ),
273 | Text(
274 | getUserName(),
275 | textAlign: TextAlign.center,
276 | style: TextStyle(color: Colors.blue),
277 | ),
278 | Text(
279 | getEmailAddress(),
280 | textAlign: TextAlign.center,
281 | style: TextStyle(color: Colors.blue),
282 | ),
283 | ],
284 | ),
285 | ),
286 | actions: [
287 | FlatButton(
288 | child: Text('Close'),
289 | onPressed: () {
290 | Navigator.of(context).pop();
291 | },
292 | ),
293 | ],
294 | );
295 | },
296 | );
297 | }
298 |
299 | Future> getAllPost() async {
300 | String postUrl = BASE_URL + '/rides/profile/all';
301 | final response = await http.get(postUrl);
302 | return allPostsFromJson(response.body);
303 | }
304 |
305 | Future> getData() async {
306 | String postUrl = BASE_URL + '/rides/profile/all';
307 | final response = await http.get(postUrl);
308 | this.setState(() {
309 | profileList = json.decode(response.body);
310 | });
311 |
312 | return allPostsFromJson(response.body);
313 | }
314 |
315 | setUserId(int newId) async {
316 | if (newId != null && newId != 0) {
317 | SharedPreferences prefs = await SharedPreferences.getInstance();
318 | prefs.setInt("id", newId);
319 | id = newId;
320 | }
321 | }
322 |
323 | Future getMyUserId() async {
324 | String addressUrl = BASE_URL + '/rides/profile/getmyid/$emailAddress';
325 | final response2 = await http.get(addressUrl);
326 | var res = response2.body;
327 | await setUserId(int.parse(res));
328 | print(res);
329 | return int.parse(res);
330 | }
331 | }
332 |
--------------------------------------------------------------------------------
/ruber/lib/initialaddaddress.dart:
--------------------------------------------------------------------------------
1 | /// initialaddress.dart
2 | ///
3 | /// Purpose:
4 | /// The purpose of this file is for the user to be able to input
5 | /// their address into the application. It requires a street name
6 | /// city, zip, and state to move onto the next screen. This is named
7 | /// initial because it is shown at the user creation process
8 | /// and it saves the data to the database as a new user, not an existing
9 | /// user.
10 |
11 | /// Imports
12 | import 'dart:async';
13 | import 'dart:async' show Future;
14 | import 'dart:io';
15 |
16 | import 'package:flutter/material.dart';
17 | import 'package:http/http.dart' as http;
18 | import 'package:ruber/Constants.dart';
19 | import 'package:shared_preferences/shared_preferences.dart';
20 |
21 | import 'AddressPostModel.dart';
22 | import 'AppDrawer.dart';
23 | import 'initialeditschedule.dart';
24 |
25 |
26 | /// Global variable declarations for saving the input from the user
27 | int id;
28 | String profilePic;
29 | String streetName = "";
30 | String city = "";
31 | String zipCode = "";
32 | String state = "";
33 |
34 | String email = "";
35 | String name = "";
36 |
37 | /// Shared preferences methods
38 |
39 | getId() async {
40 |
41 | SharedPreferences prefs = await SharedPreferences.getInstance();
42 | int tempId = prefs.getInt("id");
43 | if (tempId != 0 && tempId != null) {
44 | id = tempId;
45 | }
46 |
47 | return id;
48 | }
49 |
50 | setId(int newId) async {
51 | if (newId != null && newId != 0) {
52 | SharedPreferences prefs = await SharedPreferences.getInstance();
53 | prefs.setInt("id", newId);
54 | id = newId;
55 | }
56 | }
57 |
58 | /// Getters and setters for the global variables
59 |
60 | setName(String newName) {
61 | name = newName;
62 | }
63 |
64 | setStreetName(String newStreetName) {
65 | streetName = newStreetName;
66 | }
67 |
68 | setCity(String newCity) {
69 | city = newCity;
70 | }
71 |
72 | setNewState(String newState) {
73 | state = newState;
74 | }
75 |
76 | setZip(String newZip) {
77 | zipCode = newZip;
78 | }
79 |
80 | setProfilePic(String picLocation) {
81 | profilePic = picLocation;
82 | }
83 |
84 | // GETTERS
85 |
86 | getName() {
87 | return name;
88 | }
89 |
90 | getStreetName() {
91 | return streetName;
92 | }
93 |
94 | getCity() {
95 | return city;
96 | }
97 |
98 | getZip() {
99 | return zipCode;
100 | }
101 |
102 | getState() {
103 | return state;
104 | }
105 |
106 | getProfilePic() {
107 | return profilePic;
108 | }
109 |
110 | class InitialAddressForm extends StatefulWidget {
111 | final String emailAddress;
112 |
113 | InitialAddressForm(this.emailAddress);
114 |
115 | @override
116 | _MyAddressForm createState() => _MyAddressForm();
117 | }
118 |
119 | /// This class holds all the widgets and text controllers (which handle
120 | /// the input from the text forms). It also does error checking
121 | /// so that the user has to populate all the fields in order to
122 | /// move past this screen
123 |
124 | class _MyAddressForm extends State {
125 | final streetNameController = TextEditingController();
126 | final cityController = TextEditingController();
127 | final zipController = TextEditingController();
128 | final stateController = TextEditingController();
129 |
130 | String newStreet = "";
131 | String newCity = "";
132 | String newZip = "";
133 | String newState = "";
134 |
135 | bool a = false;
136 | bool b = false;
137 | bool c = false;
138 | bool d = false;
139 |
140 | @override
141 | void dispose() {
142 | streetNameController.dispose();
143 | cityController.dispose();
144 | zipController.dispose();
145 | stateController.dispose();
146 |
147 | super.dispose();
148 | }
149 |
150 | @override
151 | Widget build(BuildContext context) {
152 | print(email);
153 | return Scaffold(
154 | appBar: AppBar(
155 | title: Text('Edit your address'),
156 | centerTitle: true,
157 | automaticallyImplyLeading: false),
158 | drawer: launchAppDrawer(context),
159 | body: Center(
160 | child: ListView(
161 | children: [
162 | Container(
163 | margin: EdgeInsets.all(10.0),
164 | child: Text(
165 | 'Click on each field to edit it',
166 | textAlign: TextAlign.center,
167 | ),
168 | ),
169 |
170 | /// Street Name input
171 |
172 | Container(
173 | margin: EdgeInsets.only(top: 15.0),
174 | child: Text('Street Name',
175 | textAlign: TextAlign.center,
176 | style: TextStyle(
177 | fontWeight: FontWeight.bold,
178 | fontSize: 20.0,
179 | fontFamily: 'Helvetica',
180 | color: Colors.blueAccent))),
181 | Container(
182 | child: TextField(
183 | textAlign: TextAlign.center,
184 | decoration: InputDecoration.collapsed(hintText: streetName),
185 | controller: streetNameController,
186 | onEditingComplete: () {
187 | newStreet = streetNameController.text;
188 |
189 | FocusScope.of(context).requestFocus(new FocusNode());
190 | },
191 | )),
192 |
193 | /// City input
194 |
195 | Container(
196 | margin: EdgeInsets.only(top: 15.0),
197 | child: Text('City',
198 | textAlign: TextAlign.center,
199 | style: TextStyle(
200 | fontWeight: FontWeight.bold,
201 | fontSize: 20.0,
202 | fontFamily: 'Helvetica',
203 | color: Colors.blueAccent))),
204 | Container(
205 | child: TextField(
206 | textAlign: TextAlign.center,
207 | decoration: InputDecoration.collapsed(hintText: city),
208 | controller: cityController,
209 | onEditingComplete: () {
210 |
211 | newCity = cityController.text;
212 |
213 | FocusScope.of(context).requestFocus(new FocusNode());
214 | },
215 | )),
216 |
217 | /// State input
218 |
219 | Container(
220 | margin: EdgeInsets.only(top: 15.0),
221 | child: Text('State',
222 | textAlign: TextAlign.center,
223 | style: TextStyle(
224 | fontWeight: FontWeight.bold,
225 | fontSize: 20.0,
226 | fontFamily: 'Helvetica',
227 | color: Colors.blueAccent))),
228 | Container(
229 | child: TextField(
230 | textAlign: TextAlign.center,
231 | decoration: InputDecoration.collapsed(hintText: state),
232 | controller: stateController,
233 | onEditingComplete: () {
234 | // Make sure to write to Database
235 |
236 | newState = stateController.text;
237 |
238 | FocusScope.of(context).requestFocus(new FocusNode());
239 | },
240 | )),
241 |
242 | /// ZIP code input
243 |
244 | Container(
245 | margin: EdgeInsets.only(top: 15.0),
246 | child: Text('ZIP',
247 | textAlign: TextAlign.center,
248 | style: TextStyle(
249 | fontWeight: FontWeight.bold,
250 | fontSize: 20.0,
251 | fontFamily: 'Helvetica',
252 | color: Colors.blueAccent))),
253 | Container(
254 | child: TextField(
255 | textAlign: TextAlign.center,
256 | decoration: InputDecoration.collapsed(hintText: zipCode),
257 | controller: zipController,
258 | onEditingComplete: () {
259 | // Make sure to write to Database
260 | newZip = zipController.text;
261 |
262 | FocusScope.of(context).requestFocus(new FocusNode());
263 | },
264 | )),
265 |
266 | /// Save address button - does error checking to make sure
267 | /// that the user had populated all the fields before clicking
268 | /// on the button
269 |
270 | Container(
271 | margin: EdgeInsets.only(top: 40.0, left: 70.0, right: 70.0),
272 | child: RaisedButton(
273 | color: Colors.blue,
274 | textColor: Colors.white,
275 | child: Text('Save Address'),
276 | onPressed: () {
277 |
278 | if (streetNameController.text.isEmpty != true) {
279 | setStreetName(streetNameController.text);
280 | a = true;
281 | }
282 | if (stateController.text.isEmpty != true) {
283 | setNewState(stateController.text);
284 | b = true;
285 | }
286 | if (cityController.text.isEmpty != true) {
287 | setCity(cityController.text);
288 | c = true;
289 | }
290 | if (zipController.text.isEmpty != true) {
291 | setZip(zipController.text);
292 | d = true;
293 | }
294 |
295 | // Only activates after all the fields have information in them
296 | if (true) {
297 | String streetNameEdit = getStreetName();
298 | String cityNameFinal = getCity();
299 | String zipCodeEdit = getZip();
300 | String stateEdit = getState();
301 | AddressPost newAddress = AddressPost(
302 | streetAddress: streetNameEdit,
303 | city: cityNameFinal,
304 | zipCode: zipCodeEdit,
305 | state:
306 | stateEdit); // creating a new Post object to send it to API
307 |
308 | createAddress(newAddress).then((response) {
309 | if (response.statusCode > 200)
310 | print(response.body);
311 | else
312 | print(response.statusCode);
313 | }).catchError((error) {
314 | print('error : $error');
315 | });
316 |
317 | print(newAddress.toString());
318 |
319 | Navigator.push(
320 | context,
321 | MaterialPageRoute(
322 | builder: (context) => InitialScheduleForm()),
323 | );
324 | }
325 | },
326 | )),
327 | ],
328 | )));
329 | }
330 | }
331 |
332 | /*
333 | * This method returns the users id using their email from shared preferences.
334 | */
335 | Future getMyId() async {
336 | SharedPreferences prefs = await SharedPreferences.getInstance();
337 | String emailUrl = prefs.getString("email");
338 |
339 | //String emailUrl = ; // Need to work on getting email from AuthScreen.dart
340 | String addressUrl = BASE_URL + '/rides/profile/getmyid/$emailUrl';
341 | final response2 = await http.get(addressUrl);
342 | var res = response2.body;
343 | await setId(int.parse(res));
344 | print(res);
345 | return int.parse(res);
346 | }
347 | /*
348 | * This method adds the users new address to their profile on the server.
349 | */
350 | Future createAddress(AddressPost address) async {
351 | int userId = await getId();
352 | print(userId);
353 | String updateUrl = BASE_URL + '/rides/address/$userId/new';
354 | final response = await http.post('$updateUrl',
355 | headers: {
356 | HttpHeaders.contentTypeHeader: 'application/json',
357 | HttpHeaders.authorizationHeader: ''
358 | },
359 | body: addressPostToJson(address));
360 | return response;
361 | }
362 |
--------------------------------------------------------------------------------
/ruber/lib/ChatRoomScreen.dart:
--------------------------------------------------------------------------------
1 | /// ChatRoomScreen.dart
2 | ///
3 | /// Purpose:
4 | /// This file is used to show the different chat threads once the user
5 | /// clicks on the "Messages" option from the main menu. It also includes
6 | /// the screen which allows the user to type in a message and send it
7 | /// to the opposing user.
8 |
9 | /// Imports
10 | import 'dart:async';
11 | import 'dart:async' show Future;
12 | import 'dart:convert';
13 | import 'dart:io';
14 |
15 | import 'package:flutter/material.dart';
16 | import 'package:http/http.dart' as http;
17 | import 'package:shared_preferences/shared_preferences.dart';
18 |
19 | import 'AppDrawer.dart';
20 | import 'AuthScreen.dart';
21 | import 'ChatroomModel.dart';
22 | import 'Constants.dart';
23 |
24 | /// Global variables for storing the chat rooms from the server
25 |
26 | Map profileChats;
27 | String myInputText;
28 |
29 | int chatRoomId;
30 |
31 | /// Getter and setter methods
32 |
33 | getChatRoomId() {
34 | return chatRoomId;
35 | }
36 |
37 | setChatRoomId(int tempID) {
38 | chatRoomId = tempID;
39 | }
40 |
41 | getProfiles() {
42 | return profileChats;
43 | }
44 |
45 | getMyInputText() {
46 | return myInputText;
47 | }
48 |
49 | setMyInputText(String tempInput) {
50 | myInputText = tempInput;
51 | }
52 |
53 | class ChatRoomScreen extends StatefulWidget {
54 | @override
55 | ChatRoomScreenState createState() => new ChatRoomScreenState();
56 | }
57 |
58 | /// ChatRoomScreenState class holds all the Widgets for the chat room
59 | /// functionality.
60 | /// Widgets in ChatRoomScreenState:
61 | /// Chat Threads Screen - build()
62 | ///
63 | class ChatRoomScreenState extends State {
64 |
65 | int index;
66 | Future getData() async {
67 | int userId = await getId();
68 | SharedPreferences prefs = await SharedPreferences.getInstance();
69 |
70 | var response = await http.get(
71 |
72 | /// Change the URL to the end point from the database
73 | Uri.encodeFull(BASE_URL + '/rides/profile/$userId/chatrooms'),
74 | headers: {"Accept": "application/json"});
75 |
76 | this.setState(() {
77 | profileChats = json.decode(response.body);
78 | });
79 |
80 | return listFromJsonChat(response.body);
81 | }
82 |
83 | @override
84 | void initState() {
85 | super.initState();
86 | this.getData();
87 | }
88 |
89 | /// Chat Thread screen -- initial screen which is shown whenever
90 | /// the user clicks on the "Messages" option
91 |
92 | @override
93 | Widget build(BuildContext context) {
94 | return Scaffold(
95 | appBar: AppBar(
96 | title: Text('Messages'),
97 | centerTitle: true,
98 | ),
99 | drawer: launchAppDrawer(context),
100 | body: ListView.builder(
101 | itemCount:
102 | profileChats == null ? 0 : profileChats["chatrooms"].length,
103 | itemBuilder: (BuildContext context, int index) {
104 | int chatid = profileChats["chatrooms"][index]["chatRoomId"];
105 | setChatRoomId(chatid);
106 | return new ListTile(
107 | leading: Container(
108 | margin: EdgeInsets.only(
109 | bottom: 5.0, left: 5.0, right: 5.0, top: 5.0),
110 | width: 40.0,
111 | height: 50.0,
112 | child: new CircleAvatar(
113 | child: new Text(
114 | profileChats["chatrooms"][index]["profileNames"]
115 | ["Profile 2"]
116 | .toString()
117 | .substring(0, 1) +
118 | profileChats["chatrooms"][index]["profileNames"]
119 | ["Profile 1"]
120 | .toString()
121 | .substring(0, 1),
122 | style: TextStyle(fontSize: 20),
123 | ))),
124 | title: Text(profileChats["chatrooms"][index]["profileNames"]
125 | ["Profile 2"]
126 | .toString() +
127 | " & " +
128 | profileChats["chatrooms"][index]["profileNames"]["Profile 1"]
129 | .toString()),
130 | onTap: () {
131 | Navigator.push(
132 | context,
133 | MaterialPageRoute(
134 | builder: (context) =>
135 | IndividualChatThread(context, index)));
136 | },
137 | );
138 | },
139 | ));
140 | }
141 |
142 | /// Text Editing Controller - for holding the message that was typed
143 |
144 | TextEditingController _textController = new TextEditingController();
145 |
146 | void _afterMessageSubmission(String text) {
147 | setState(() {
148 | if (_textController.text.isEmpty) {
149 | } else
150 | setMyInputText(_textController.text);
151 | });
152 | }
153 |
154 | /// This widget holds the different messages from both parties - also
155 | /// shows the time sent/received and their profile image
156 |
157 | Widget MessageContainer() {
158 | return new IconTheme(
159 | data: new IconThemeData(color: Theme.of(context).accentColor),
160 | child: new Container(
161 | margin: const EdgeInsets.symmetric(horizontal: 8.0),
162 | child: new Row(
163 | children: [
164 | new Flexible(
165 | child: new TextField(
166 | controller: _textController,
167 | onChanged: _afterMessageSubmission,
168 | onSubmitted: _afterMessageSubmission,
169 | decoration:
170 | new InputDecoration.collapsed(hintText: "Send a message"),
171 | ),
172 | ),
173 | new Container(
174 | margin: new EdgeInsets.symmetric(horizontal: 8.0),
175 | child: new IconButton(
176 | icon: new Icon(Icons.send),
177 | onPressed: () {
178 | String newText = getMyInputText();
179 | Messages newMessage = Messages(
180 | chatroomID: getChatRoomId(),
181 | senderID: id,
182 | text: newText);
183 | createMessage(newMessage).then((response) {
184 | if (response.statusCode > 200)
185 | print(response.body);
186 | else
187 | print(response.statusCode);
188 |
189 | getData().then((res) {
190 | Navigator.push(
191 | context,
192 | MaterialPageRoute(
193 | builder: (context) =>
194 | IndividualChatThread(context, index)));
195 | });
196 |
197 | }).catchError((error) {
198 | print('error : $error');
199 | });
200 | _textController.clear();
201 | }),
202 | ),
203 | ],
204 | ),
205 | ));
206 | }
207 |
208 | /// This is the screen shown when the user clicks onto a chat thread
209 | /// in the chat room screen. It holds the MessageContainer inside it
210 | /// so that it can show the different messages being typed
211 |
212 | Widget IndividualChatThread(BuildContext context, int index) {
213 | this.index = index;
214 | return Scaffold(
215 | appBar: AppBar(
216 | title: Text(profileChats["chatrooms"][index]["profileNames"]
217 | ["Profile 2"]
218 | .toString() +
219 | " & " +
220 | profileChats["chatrooms"][index]["profileNames"]["Profile 1"]
221 | .toString()),
222 | centerTitle: true,
223 | actions: [
224 | IconButton(
225 | icon: Icon(Icons.refresh),
226 | onPressed: () {
227 |
228 | getData().then((res) {
229 | Navigator.push(
230 | context,
231 | MaterialPageRoute(
232 | builder: (context) =>
233 | IndividualChatThread(context, index)));
234 | });
235 |
236 | })
237 |
238 | ]),
239 | drawer: launchAppDrawer(context),
240 | body: new Column(
241 | children: [
242 | Flexible(
243 | child: ListView.builder(
244 | padding: new EdgeInsets.all(15.0),
245 | reverse: true,
246 | itemCount: profileChats == null
247 | ? 0
248 | : profileChats["chatrooms"][index]["messages"].length,
249 | itemBuilder: (BuildContext context, int index2) {
250 | return Container(
251 |
252 | /// This logic decides where the messages go in the
253 | /// MessageContainer - right or left. Right is for the
254 | /// sender, left is for the received messages. It does
255 | /// this by comparing the senderID of the message being
256 | /// sent to the profileID of the user of the app. If they
257 | /// are equal, then it means that the sender is the user
258 | /// so it goes on the right hand side, and ANY other message
259 | /// goes on the left hand side (receiver messages)
260 |
261 | child: Row(
262 | children: profileChats["chatrooms"][index]["messages"]
263 | [index2]["senderID"] ==
264 | id
265 | ? rightSide(index, index2)
266 | : leftSide(index, index2)));
267 | },
268 | ),
269 | ),
270 | Divider(height: 0.0),
271 | Container(
272 | child: MessageContainer(),
273 | decoration:
274 | new BoxDecoration(color: Theme.of(context).cardColor))
275 | ],
276 | ));
277 | }
278 |
279 | /// This is for structuring the message to go on the right side, if
280 | /// the message is being sent by the user of the app - currently
281 | /// Received messages from the other party are displayed on the left
282 | /// hand side
283 |
284 | List rightSide(int index, int index2) {
285 | return [
286 | Expanded(
287 | child: Column(
288 | crossAxisAlignment: CrossAxisAlignment.end,
289 | children: [
290 | new Container(
291 | margin: const EdgeInsets.only(top: 15.0),
292 | child: Container(
293 | child: FutureBuilder(
294 | future: getChatrooms(),
295 | builder: (context, snapshot) {
296 | return Text(
297 | profileChats["chatrooms"][index]["messages"]
298 | [index2]["text"]
299 | .toString(),
300 | style: TextStyle(
301 | fontSize: 18.0,
302 | color: Colors.lightBlue,
303 | fontWeight: FontWeight.bold));
304 | }))),
305 | new Container(
306 | margin: const EdgeInsets.only(top: 10.0),
307 | child: Container(
308 | child: FutureBuilder(
309 | future: getChatrooms(),
310 | builder: (context, snapshot) {
311 | return Text(
312 | profileChats["chatrooms"][index]["messages"]
313 | [index2]["timeSent"]
314 | .toString(),
315 | style: TextStyle(
316 | fontSize: 14.0,
317 | color: Colors.grey,
318 | fontWeight: FontWeight.normal));
319 | }))),
320 | ],
321 | ),
322 | ),
323 | Column(
324 | crossAxisAlignment: CrossAxisAlignment.end,
325 | children: [
326 | new Container(
327 | margin:
328 | EdgeInsets.only(bottom: 0.0, left: 5.0, right: 5.0, top: 0.0),
329 | width: 42.0,
330 | height: 38.0,
331 | decoration: new BoxDecoration(
332 | shape: BoxShape.circle,
333 | image: new DecorationImage(
334 | fit: BoxFit.fill,
335 | // This is where we would retrieve the image from the data base
336 | image: NetworkImage(userProfilePic)))),
337 | ],
338 | )
339 | ];
340 | }
341 |
342 | /// This is used to structure the message on the left hand side -- for
343 | /// received messages. Sent messages are displayed on the right hand side.
344 |
345 | List leftSide(int index, int index2) {
346 | return [
347 | Column(
348 | crossAxisAlignment: CrossAxisAlignment.start,
349 | children: [
350 | new Container(
351 | margin:
352 | EdgeInsets.only(bottom: 0.0, left: 0.0, right: 5.0, top: 0.0),
353 | width: 40.0,
354 | height: 50.0,
355 | child: new CircleAvatar(
356 | child: new Text(
357 | profileChats["chatrooms"][index]["profileNames"]["Profile 2"]
358 | .toString()
359 | .substring(0, 1),
360 | style: TextStyle(fontSize: 20),
361 | ))),
362 | ],
363 | ),
364 | Expanded(
365 | child: Column(
366 | crossAxisAlignment: CrossAxisAlignment.start,
367 | children: [
368 | new Container(
369 | margin: const EdgeInsets.only(top: 15.0),
370 | child: Container(
371 | child: FutureBuilder(
372 | future: getChatrooms(),
373 | builder: (context, snapshot) {
374 | return Text(
375 | profileChats["chatrooms"][index]["messages"]
376 | [index2]["text"]
377 | .toString(),
378 | style: TextStyle(
379 | fontSize: 18.0,
380 | color: Colors.lightBlue,
381 | fontWeight: FontWeight.bold));
382 | }))),
383 | new Container(
384 | margin: const EdgeInsets.only(top: 5.0),
385 | child: Container(
386 | child: FutureBuilder(
387 | future: getChatrooms(),
388 | builder: (context, snapshot) {
389 | return Text(
390 | profileChats["chatrooms"][index]["messages"]
391 | [index2]["timeSent"]
392 | .toString(),
393 | style: TextStyle(
394 | fontSize: 14.0,
395 | color: Colors.grey,
396 | fontWeight: FontWeight.normal));
397 | }))),
398 | ],
399 | ),
400 | )
401 | ];
402 | }
403 | }
404 |
405 | /*
406 | * This method is used to get the users Id from shared Preferences
407 | */
408 | getId() async {
409 | SharedPreferences prefs = await SharedPreferences.getInstance();
410 | int tempId = prefs.getInt("id");
411 | if (tempId != 0 && tempId != null) {
412 | id = tempId;
413 | }
414 | return id;
415 | }
416 | /*
417 | * This Method is used to return all of the chatrooms the user is part of.
418 | */
419 | Future getChatrooms() async {
420 | int userid = await getId();
421 | String postUrl = BASE_URL + '/rides/profile/$userid/chatrooms';
422 | final response = await http.get(postUrl);
423 | return listFromJsonChat(response.body);
424 | }
425 | /*
426 | *This method is used to post messages to the server.
427 | */
428 | Future createMessage(Messages myMessage) async {
429 | String newMessageUrl = BASE_URL + '/rides/message/new';
430 | final response = await http.post('$newMessageUrl',
431 | headers: {
432 | HttpHeaders.contentTypeHeader: 'application/json',
433 | HttpHeaders.authorizationHeader: ''
434 | },
435 | body: messagePostToJson(myMessage));
436 | return response;
437 | }
438 |
--------------------------------------------------------------------------------