diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml
deleted file mode 100644
index 8b8b96b..0000000
--- a/.idea/assetWizardSettings.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index 9601e05..0dcfb72 100644
Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 99202cc..cc04cd3 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -5,27 +5,37 @@
-
+
diff --git a/app/build.gradle b/app/build.gradle
index 7fbdb17..d98c658 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,15 +1,17 @@
apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-kapt'
android {
- compileSdkVersion 27
- buildToolsVersion "27.0.3"
+ compileSdkVersion 28
+ buildToolsVersion '28.0.3'
defaultConfig {
applicationId "razorbacktransit.arcu.razorbacktransit"
- minSdkVersion 19
- targetSdkVersion 27
+ minSdkVersion 21
+ targetSdkVersion 28
versionCode 17
versionName "4.2.1"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
@@ -23,23 +25,49 @@ android {
// signingConfig signingConfigs.config
}
}
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
}
dependencies {
+ def lifecycle_version = "2.0.0"
implementation fileTree(include: ['*.jar'], dir: 'libs')
- implementation 'com.google.firebase:firebase-messaging:17.3.0'
- androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
+ implementation 'com.google.firebase:firebase-core:16.0.5'
+ implementation 'com.google.firebase:firebase-messaging:17.3.4'
+ androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
exclude group: 'com.android.support', module: 'support-annotations'
})
- implementation 'com.android.support:appcompat-v7:27.1.1'
- implementation 'com.github.barteksc:android-pdf-viewer:2.8.1'
- implementation 'com.android.support:design:27.1.1'
- implementation 'com.android.support.constraint:constraint-layout:1.1.2'
- implementation 'com.android.support:support-v4:27.1.1'
- implementation 'com.google.firebase:firebase-core:15.0.0'
- implementation 'com.google.android.gms:play-services-maps:15.0.0'
- implementation 'com.squareup.okhttp3:okhttp:3.10.0'
testImplementation 'junit:junit:4.12'
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'com.github.barteksc:android-pdf-viewer:2.8.1'
+ implementation 'com.google.android.material:material:1.1.0-alpha02'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'com.google.android.gms:play-services-maps:16.0.0'
+ implementation 'com.squareup.okhttp3:okhttp:3.12.0'
+ implementation 'com.squareup.retrofit2:retrofit:2.5.0'
+ implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
+ implementation 'com.squareup.retrofit2:converter-moshi:2.4.0'
+ implementation 'com.squareup.moshi:moshi-kotlin:1.8.0'
+ implementation 'io.reactivex.rxjava2:rxjava:2.2.6'
+ implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
+ implementation 'com.jakewharton.rxbinding3:rxbinding-core:3.0.0-alpha1'
+ implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
+ implementation 'com.jakewharton:butterknife:9.0.0'
+ kapt 'com.jakewharton:butterknife-compiler:9.0.0'
+ implementation 'androidx.core:core-ktx:1.0.1'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
+ implementation "android.arch.lifecycle:extensions:$lifecycle_version"
+ implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
+ implementation 'com.github.bumptech.glide:glide:4.8.0'
+ kapt 'com.github.bumptech.glide:compiler:4.8.0'
+
}
apply plugin: 'com.google.gms.google-services'
+apply plugin: 'kotlin-android'
+repositories {
+ mavenCentral()
+}
diff --git a/app/src/androidTest/java/razorbacktransit/arcu/razorbacktransit/ExampleInstrumentedTest.java b/app/src/androidTest/java/razorbacktransit/arcu/razorbacktransit/ExampleInstrumentedTest.java
index ca016e5..d09c403 100644
--- a/app/src/androidTest/java/razorbacktransit/arcu/razorbacktransit/ExampleInstrumentedTest.java
+++ b/app/src/androidTest/java/razorbacktransit/arcu/razorbacktransit/ExampleInstrumentedTest.java
@@ -1,8 +1,8 @@
package razorbacktransit.arcu.razorbacktransit;
import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -18,7 +18,7 @@
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
- // Context of the app under test.
+ // Context of the applivation under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("razorbacktransit.arcu.razorbacktransit", appContext.getPackageName());
diff --git a/app/src/debug/res/values/google_maps_api.xml b/app/src/debug/res/values/google_maps_api.xml
index b669533..7072663 100644
--- a/app/src/debug/res/values/google_maps_api.xml
+++ b/app/src/debug/res/values/google_maps_api.xml
@@ -21,6 +21,6 @@
string in this file.
-->
- AIzaSyCw6Ph5uz-2fnVzVMFDIZs0B8aBXONywOk
+ AIzaSyCJ_t16aFkINz-nsI1T2BMoP6EPrz1iM80
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/LiveMapFragment.java b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/LiveMapFragment.java
deleted file mode 100644
index 5ad1dd1..0000000
--- a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/LiveMapFragment.java
+++ /dev/null
@@ -1,643 +0,0 @@
-package razorbacktransit.arcu.razorbacktransit;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.support.v4.app.Fragment;
-import android.util.Base64;
-import android.util.DisplayMetrics;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.google.android.gms.maps.CameraUpdate;
-import com.google.android.gms.maps.CameraUpdateFactory;
-import com.google.android.gms.maps.GoogleMap;
-import com.google.android.gms.maps.OnMapReadyCallback;
-import com.google.android.gms.maps.SupportMapFragment;
-import com.google.android.gms.maps.UiSettings;
-import com.google.android.gms.maps.model.BitmapDescriptor;
-import com.google.android.gms.maps.model.BitmapDescriptorFactory;
-import com.google.android.gms.maps.model.LatLng;
-import com.google.android.gms.maps.model.LatLngBounds;
-import com.google.android.gms.maps.model.Marker;
-import com.google.android.gms.maps.model.MarkerOptions;
-import com.google.android.gms.maps.model.Polyline;
-import com.google.android.gms.maps.model.PolylineOptions;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import okhttp3.Call;
-import okhttp3.Callback;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
-import okhttp3.ResponseBody;
-
-public class LiveMapFragment extends Fragment implements OnMapReadyCallback, GoogleMap.OnMarkerClickListener {
-
- private OnFragmentInteractionListener mListener;
- private GoogleMap googleMap;
- private SharedPreferences sharedPreferences;
- private SharedPreferences.Editor editor;
-
- private final OkHttpClient client = new OkHttpClient();
- private final List busMarkers = new ArrayList<>();
- private final HashMap stopMarkerHashMap = new HashMap<>();
- private List routeIDsForBusses = new ArrayList<>();
- private Timer busTimer;
-
- private int stopImageWidth;
- private int stopImageHeight;
- private int busImageWidth;
- private int busImageHeight;
-
- public LiveMapFragment() {
- // Required empty public constructor
- }
-
- public static LiveMapFragment newInstance(String param1, String param2) {
- return new LiveMapFragment();
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- try {
- sharedPreferences = getActivity().getPreferences(Context.MODE_PRIVATE);
- } catch (NullPointerException e) {
- e.printStackTrace();
- }
-
- editor = sharedPreferences.edit();
-
- final int widthPixels = getActivity().getResources().getDisplayMetrics().widthPixels;
-
- stopImageWidth = (int) (widthPixels * 0.02638888889);
- stopImageHeight = (int) (widthPixels * 0.02638888889);
-
- busImageWidth = (int) (widthPixels * 0.05833333333);
- busImageHeight = (int) (widthPixels * 0.05833333333 * 1.6153846154);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
-
- View view = inflater.inflate(R.layout.fragment_maps, container, false);
- SupportMapFragment mapFragment = (SupportMapFragment) this.getChildFragmentManager()
- .findFragmentById(R.id.map);
- mapFragment.getMapAsync(this);
-
- return view;
- }
-
- @Override
- public void onResume() {
- super.onResume();
-
- if (this.googleMap != null) {
- this.googleMap.clear();
- }
-
- try {
- loadRoutes();
- loadBusses();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- busTimer = new Timer();
- busTimer.schedule(new TimerTask() {
- @Override
- public void run() {
- try {
- loadBusses();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }, 5000, 5000);
- }
-
- @Override
- public void onPause() {
- super.onPause();
-
- editor.apply();
- busTimer.cancel();
- }
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- if (context instanceof OnFragmentInteractionListener) {
- mListener = (OnFragmentInteractionListener) context;
- } else {
- throw new RuntimeException(context.toString()
- + " must implement OnFragmentInteractionListener");
- }
- }
-
- @Override
- public void onDetach() {
- super.onDetach();
- mListener = null;
- }
-
- @Override
- public void onMapReady(GoogleMap googleMap) {
- this.googleMap = googleMap;
-
- this.googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(36.09, -94.1785)));
- this.googleMap.moveCamera(CameraUpdateFactory.zoomTo(12.0f));
- this.googleMap.setMinZoomPreference(10);
- this.googleMap.setOnMarkerClickListener(this);
- UiSettings uiSettings = this.googleMap.getUiSettings();
- uiSettings.setRotateGesturesEnabled(true);
- uiSettings.setTiltGesturesEnabled(false);
-
- }
-
- public void loadRoutes() throws Exception {
-
- Request request = new Request.Builder()
- .url(getString(R.string.route_url))
- .build();
-
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- e.printStackTrace();
- }
-
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- try (ResponseBody responseBody = response.body()) {
- if (!response.isSuccessful())
- throw new IOException("Unexpected code " + response);
-
- String responseText = responseBody.string();
- responseText = responseText.substring(7, responseText.length() - 2);
-
- try {
- final JSONArray jsonArray = new JSONArray(responseText);
-
- Runnable myRunnable = new Runnable() {
- @Override
- public void run() {
-
- List routeIDs = new ArrayList<>();
- for (int i = 0; i < jsonArray.length(); i++) {
-
- try {
- final JSONObject jsonObject = jsonArray.getJSONObject(i);
- if (jsonObject.getString("inService").equals("1")) {
-
- List points = new ArrayList<>();
- String[] coordinates = jsonObject.getString("shape").split(",");
-
- if (coordinates.length > 1) {
- for (String coordinate : coordinates) {
- String[] latlong = coordinate.split(" ");
- points.add(new LatLng(
- Double.parseDouble(latlong[0]),
- Double.parseDouble(latlong[1])));
- }
- final Polyline polyline = googleMap.addPolyline(new PolylineOptions()
- .color((int) Long.parseLong(("99" + jsonObject.getString("color")
- .substring(1)), 16)));
- polyline.setPoints(points);
- }
- if (!routeIDs.contains(jsonObject.getString("id"))) {
- routeIDs.add(jsonObject.getString("id"));
- }
- }
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- try {
- routeIDsForBusses = new ArrayList<>(routeIDs);
- loadBusses();
- loadStops(routeIDs);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- };
- new Handler(Looper.getMainLooper()).post(myRunnable);
-
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- }
- });
- }
-
- private String buildStopURL(List routeIDs) {
- String stopString = getString(R.string.stop_url);
- for (String id : routeIDs) {
- stopString = stopString.concat("-" + id);
- }
- return stopString;
- }
-
- private String buildStopImageULR(String id, List routeIDs) {
- String urlString = "https://campusdata.uark.edu/api/stopimages?stopId=" + id + "&routeIds=undefined";
- for (String routeID : routeIDs) {
- urlString = urlString.concat("-" + routeID);
- }
- return urlString;
- }
-
- public void loadStops(final List routeIDs) throws Exception {
-
- Request request = new Request.Builder()
- .url(buildStopURL(routeIDs))
- .build();
-
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- e.printStackTrace();
- }
-
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- try (ResponseBody responseBody = response.body()) {
- if (!response.isSuccessful())
- throw new IOException("Unexpected code " + response);
-
- String responseText = responseBody.string();
- responseText = responseText.substring(10, responseText.length() - 2);
-
- try {
- final JSONArray jsonArray = new JSONArray(responseText);
- stopMarkerHashMap.clear();
-
- if (getActivity() == null) {
- return;
- }
-
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
-
- for (int i = 0; i < jsonArray.length(); i++) {
-
- try {
- final JSONObject jsonObject = jsonArray.getJSONObject(i);
-
- final Marker marker = googleMap.addMarker(new MarkerOptions()
- .flat(true)
- .alpha(0)
- .snippet(jsonObject.getString("name"))
- .title("Next Arrival: ...")
- .position(new LatLng(
- Double.parseDouble(jsonObject.getString("latitude")),
- Double.parseDouble(jsonObject.getString("longitude")))));
-
- stopMarkerHashMap.put(marker, jsonObject.getString("id"));
- String encodedImage = sharedPreferences.getString(jsonObject.getString("id") + "1", "");
-
- if (!encodedImage.equals("")) {
- byte[] bytes = Base64.decode(encodedImage, Base64.DEFAULT);
- final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
- final BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.
- fromBitmap(bitmap);
- marker.setIcon(bitmapDescriptor);
- marker.setAlpha(1);
- }
-
- Request iconRequest = new Request
- .Builder()
- .url(buildStopImageULR(jsonObject.getString("id"), routeIDs))
- .build();
-
- client.newCall(iconRequest).enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- e.printStackTrace();
- }
-
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- try (ResponseBody responseBody = response.body()) {
- if (!response.isSuccessful())
- throw new IOException("Unexpected code " + response);
-
- InputStream inputStream = response.body().byteStream();
- final Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(inputStream), stopImageWidth, stopImageHeight, true);
- final BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.
- fromBitmap(bitmap);
-
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
- byte[] bytes = byteArrayOutputStream.toByteArray();
-
- editor.putString(jsonObject.getString("id") + "1", Base64.encodeToString(bytes, Base64.DEFAULT));
-
- if (getActivity() == null) {
- return;
- }
-
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- marker.setIcon(bitmapDescriptor);
- marker.setAlpha(1);
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- }
- }
- });
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- });
-
- } catch (JSONException e) {
- e.printStackTrace();
- }
-
- LatLngBounds.Builder builder = new LatLngBounds.Builder();
-
- for (Marker marker : stopMarkerHashMap.keySet().toArray(new Marker[]{})) {
- builder.include(marker.getPosition());
- }
- LatLngBounds bounds = builder.build();
- int padding = busImageHeight; // offset from edges of the map in pixels
- CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
- googleMap.animateCamera(cu);
- }
- }
-
- });
- } catch (JSONException e) {
- e.printStackTrace();
- }
- } catch (NullPointerException e) {
- e.printStackTrace();
- }
- }
- });
- }
-
- public String getBusImageKey(String heading, String color) {
- Double x = Double.parseDouble(heading);
- return color + Integer.toString(((x.intValue() + 29) / 30) * 30);
- }
-
- private String buildBusURL() {
- String part1 = "https://campusdata.uark.edu/api/buses?callback=jQuery18002674589609856972_1510069338014&routeIds=undefined";
- String part2 = "&_=1510069339459";
- for (String id : routeIDsForBusses) {
- part1 = part1.concat("-" + id);
- }
- part1 = part1.concat(part2);
- return part1;
- }
-
- public void loadBusses() throws Exception {
-
- Request request = new Request.Builder()
- .url(buildBusURL())
- .build();
-
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- e.printStackTrace();
- }
-
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- try (ResponseBody responseBody = response.body()) {
- if (!response.isSuccessful())
- throw new IOException("Unexpected code " + response);
-
- String responseText = responseBody.string();
- responseText = responseText.substring(41, responseText.length() - 2);
-
- try {
- final JSONArray jsonArray = new JSONArray(responseText);
-
- if (getActivity() == null) {
- return;
- }
-
- getActivity().runOnUiThread(new Runnable() {
-
- @Override
- public void run() {
-
- List oldMarkers = new ArrayList<>(busMarkers);
- busMarkers.clear();
-
- for (int i = 0; i < jsonArray.length(); i++) {
-
- try {
- final JSONObject jsonObject = jsonArray.getJSONObject(i);
-
-
-
- final Marker marker = googleMap.addMarker(new MarkerOptions()
- .position(new LatLng(
- Double.parseDouble(jsonObject.getString("latitude")),
- Double.parseDouble(jsonObject.getString("longitude"))))
- .flat(true)
- .alpha(0)
- .title(jsonObject.getString("routeName")));
-
- busMarkers.add(marker);
- final String key = getBusImageKey(jsonObject.getString("heading"), jsonObject.getString("color"));
- final String encodedImage = sharedPreferences.getString(key, "");
-
- if (!encodedImage.equals("")) {
-
- byte[] bytes = Base64.decode(encodedImage, Base64.DEFAULT);
- final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
- final BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.
- fromBitmap(bitmap);
- marker.setIcon(bitmapDescriptor);
- marker.setAlpha(1);
-
- } else {
-
- Request iconRequest = new Request
- .Builder()
- .url("https://campusdata.uark.edu/api/busimages?color=" + jsonObject.getString("color").substring(1) + "&heading=" + jsonObject.getString("heading"))
- .build();
-
- client.newCall(iconRequest).enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- e.printStackTrace();
- }
-
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- try (ResponseBody responseBody = response.body()) {
- if (!response.isSuccessful())
- throw new IOException("Unexpected code " + response);
-
- InputStream inputStream = response.body().byteStream();
- final Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(inputStream), busImageWidth, busImageHeight, true);
- final BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.
- fromBitmap(bitmap);
-
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
- byte[] bytes = byteArrayOutputStream.toByteArray();
-
- editor.putString(key, Base64.encodeToString(bytes, Base64.DEFAULT));
- editor.apply();
-
- if (getActivity() == null) {
- return;
- }
-
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (marker.isVisible()) {
- try {
- marker.setIcon(bitmapDescriptor);
- marker.setAlpha(1);
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- }
- }
- }
- });
- }
- }
- });
-
- }
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- for (Marker temp : oldMarkers) {
- try {
- temp.remove();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- }
- }
- }
- });
- } catch (JSONException e) {
- e.printStackTrace();
- }
- } catch (NullPointerException e) {
- e.printStackTrace();
- }
- }
- });
- }
-
- @Override
- public boolean onMarkerClick(final Marker marker) {
-
- if (!stopMarkerHashMap.containsKey(marker)) {
- return false;
- }
-
- marker.setTitle("Next Arrival: Loading...");
- marker.showInfoWindow();
-
- final String url = "https://campusdata.uark.edu/api/routes?callback=jQuery18004251280482585251_1507605405541&stopId=" + stopMarkerHashMap.get(marker) + "&_=1507605550296";
-
- final Request request = new Request.Builder()
- .url(url)
- .build();
-
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- e.printStackTrace();
- }
-
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- try (ResponseBody responseBody = response.body()) {
- if (!response.isSuccessful())
- throw new IOException("Unexpected code " + response);
-
- String responseText = responseBody.string();
- responseText = responseText.substring(41, responseText.length() - 2);
- try {
-
- final JSONArray jsonArray = new JSONArray(responseText);
-
- if (getActivity() == null) {
- return;
- }
-
- getActivity().runOnUiThread(new Runnable() {
-
- @Override
- public void run() {
-
- for (int i = 0; i < jsonArray.length(); i++) {
-
- try {
- JSONObject jsonObject = jsonArray.getJSONObject(i);
-
- final String nextArrival = jsonObject.getString("nextArrival");
-
- if (!nextArrival.equals("...") && !nextArrival.equals("null")) {
-
- marker.setTitle("Next Arival: " + nextArrival);
- marker.showInfoWindow();
-
- return;
- }
-
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- marker.setTitle("Next Arrival: None");
- marker.showInfoWindow();
- }
- });
- } catch (JSONException e) {
- e.printStackTrace();
- }
- } catch (NullPointerException e) {
- e.printStackTrace();
- }
- }
- });
- return false;
- }
-
- public interface OnFragmentInteractionListener {
- // TODO: Update argument type and name
- void onFragmentInteraction(Uri uri);
- }
-}
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/LiveMapFragment.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/LiveMapFragment.kt
new file mode 100644
index 0000000..cbbf9e9
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/LiveMapFragment.kt
@@ -0,0 +1,163 @@
+package razorbacktransit.arcu.razorbacktransit
+
+import android.content.Context
+import android.net.Uri
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.annotation.MainThread
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProviders
+import com.google.android.gms.maps.CameraUpdateFactory
+import com.google.android.gms.maps.GoogleMap
+import com.google.android.gms.maps.OnMapReadyCallback
+import com.google.android.gms.maps.SupportMapFragment
+import com.google.android.gms.maps.model.LatLng
+import com.google.android.gms.maps.model.Marker
+import com.google.android.gms.maps.model.MarkerOptions
+import com.google.android.gms.maps.model.PolylineOptions
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.Disposable
+import razorbacktransit.arcu.razorbacktransit.model.bus.Bus
+import razorbacktransit.arcu.razorbacktransit.model.route.Route
+import razorbacktransit.arcu.razorbacktransit.network.LiveMapViewModel
+import razorbacktransit.arcu.razorbacktransit.network.SubmitUiModel
+import razorbacktransit.arcu.razorbacktransit.utils.clearMarkers
+
+
+class LiveMapFragment: Fragment(), OnMapReadyCallback, GoogleMap.OnMarkerClickListener
+{
+ private var mListener: OnFragmentInteractionListener? = null
+ private var googleMap: GoogleMap? = null
+
+ private var busMarkers = arrayListOf()
+ private val stopMarkers = arrayListOf()
+
+ private lateinit var disposable: Disposable
+ private lateinit var viewModel: LiveMapViewModel
+
+ override fun onCreate(savedInstanceState: Bundle?)
+ {
+ super.onCreate(savedInstanceState)
+ viewModel = ViewModelProviders.of(this).get(LiveMapViewModel::class.java)
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
+ {
+
+ val view = inflater.inflate(R.layout.fragment_maps, container, false)
+ val mapFragment = this.childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
+ mapFragment!!.getMapAsync(this)
+
+ return view
+ }
+
+ override fun onResume()
+ {
+ super.onResume()
+
+ disposable = viewModel.observeAll
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe {
+ when(it)
+ {
+ is SubmitUiModel.SubmitRoute -> updateRoutes(it.route)
+ is SubmitUiModel.SubmitBuses -> updateBusses(it.bus)
+ is SubmitUiModel.SubmitStop -> updateStops(it.stop.icon!!)
+ }
+ }
+
+ if (googleMap != null)
+ {
+ busMarkers.clearMarkers()
+ googleMap?.clear()
+ }
+ }
+
+ override fun onAttach(context: Context?)
+ {
+ super.onAttach(context)
+ if (context is OnFragmentInteractionListener)
+ {
+ mListener = context
+ }
+ else
+ {
+ throw RuntimeException(context!!.toString() + " must implement OnFragmentInteractionListener")
+ }
+ }
+
+ override fun onDetach()
+ {
+ super.onDetach()
+ mListener = null
+ disposable.dispose()
+ }
+
+ override fun onMapReady(map: GoogleMap)
+ {
+ googleMap = map
+ googleMap?.apply {
+ moveCamera(CameraUpdateFactory.newLatLng(LatLng(36.09, -94.1785)))
+ moveCamera(CameraUpdateFactory.zoomTo(12.0f))
+ setMinZoomPreference(10f)
+ setOnMarkerClickListener(this@LiveMapFragment)
+ uiSettings.isRotateGesturesEnabled = true
+ uiSettings.isTiltGesturesEnabled = false
+ }
+ }
+
+ @MainThread
+ private fun updateRoutes(routes: List)
+ {
+ Log.d("DEBUGGING", "updateRoutes()")
+ for (route in routes)
+ {
+ if (route.coordinates.size > 1)
+ {
+ val polylineOptions = PolylineOptions().color(route.color)
+ val polyline = googleMap!!.addPolyline(polylineOptions)
+ polyline.points = route.coordinates
+ }
+ }
+ }
+
+ @MainThread
+ private fun updateBusses(buses: List)
+ {
+ Log.d("DEBUGGING", "updateBusses()")
+ val markers = ArrayList()
+ for(bus in buses)
+ {
+ markers += googleMap!!.addMarker(bus.icon).apply { alpha = 1f }
+ }
+ busMarkers.clearMarkers()
+ busMarkers = markers
+ }
+
+ @MainThread
+ private fun updateStops(stop: MarkerOptions)
+ {
+ Log.d("DEBUGGING", "updateStops()")
+ stopMarkers += googleMap!!.addMarker( stop ).apply { alpha = 1f }
+ }
+
+ override fun onMarkerClick(marker: Marker): Boolean = false
+
+ interface OnFragmentInteractionListener
+ {
+ // TODO: Update argument type and name
+ fun onFragmentInteraction(uri: Uri)
+ }
+
+ companion object
+ {
+
+ fun newInstance(param1: String, param2: String): LiveMapFragment
+ {
+ return LiveMapFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/MainActivity.java b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/MainActivity.java
index d30914d..11be525 100644
--- a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/MainActivity.java
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/MainActivity.java
@@ -2,18 +2,21 @@
import android.net.Uri;
import android.os.Bundle;
-import android.support.design.widget.NavigationView;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v4.view.GravityCompat;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v7.app.ActionBarDrawerToggle;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
+import com.google.android.material.navigation.NavigationView;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.core.view.GravityCompat;
+import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.appcompat.app.ActionBarDrawerToggle;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
import com.google.firebase.analytics.FirebaseAnalytics;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener,
LiveMapFragment.OnFragmentInteractionListener,
@@ -21,10 +24,12 @@ public class MainActivity extends AppCompatActivity
SchedulesFragment.OnFragmentInteractionListener,
RoutesFragment.OnFragmentInteractionListener,
ViewScheduleFragment.OnFragmentInteractionListener,
- ViewRouteFragment.OnFragmentInteractionListener {
+ ViewRouteFragment.OnFragmentInteractionListener
+{
- int lastMenuItemId = 10;
- private NavigationView navigationView;
+ @BindView(R.id.nav_view) NavigationView navigationView;
+ @BindView(R.id.toolbar) Toolbar toolbar;
+ @BindView(R.id.drawer_layout) DrawerLayout drawer;
private LiveMapFragment liveMapFragment;
private SchedulesFragment schedulesFragment;
private RoutesFragment routesFragment;
@@ -33,6 +38,7 @@ public class MainActivity extends AppCompatActivity
private ViewRouteFragment viewRouteFragment;
private FirebaseAnalytics mFirebaseAnalytics;
private final FragmentManager fragmentManager = getSupportFragmentManager();
+ int lastMenuItemId = 10;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -41,16 +47,14 @@ protected void onCreate(Bundle savedInstanceState) {
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
setTheme(R.style.AppTheme_NoActionBar);
setContentView(R.layout.activity_main);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ ButterKnife.bind(this);
setSupportActionBar(toolbar);
- DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
- navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
liveMapFragment = new LiveMapFragment();
@@ -70,7 +74,6 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
public void onBackPressed() {
- DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
@@ -88,7 +91,6 @@ public boolean onNavigationItemSelected(MenuItem item) {
if (lastMenuItemId == navigationView.getMenu().getItem(1).getItemId() || lastMenuItemId == navigationView.getMenu().getItem(2).getItemId()) {
lastMenuItemId = id;
} else {
- DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
@@ -213,7 +215,6 @@ public boolean onNavigationItemSelected(MenuItem item) {
}
}
- DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
@@ -250,7 +251,7 @@ public void onFragmentInteraction(ViewRouteFragment fragment, String title) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.ITEM_ID, title);
- bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "Route Viewed");
+ bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "BusRoute Viewed");
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle);
fragmentTransaction.add(R.id.container, viewRouteFragment).addToBackStack(viewRouteFragment.getClass().getSimpleName());
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/MyFirebaseInstanceIDService.java b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/MyFirebaseInstanceIDService.java
index 8c57e42..f38e7f7 100644
--- a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/MyFirebaseInstanceIDService.java
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/MyFirebaseInstanceIDService.java
@@ -46,7 +46,7 @@ public void onTokenRefresh() {
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
- // Instance ID token to your app server.
+ // Instance ID token to your applivation server.
sendRegistrationToServer(refreshedToken);
}
// [END refresh_token]
@@ -60,6 +60,6 @@ public void onTokenRefresh() {
* @param token The new token.
*/
private void sendRegistrationToServer(String token) {
- // TODO: Implement this method to send token to your app server.
+ // TODO: Implement this method to send token to your applivation server.
}
}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/MyFirebaseMessagingService.java b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/MyFirebaseMessagingService.java
index edd56cb..5006584 100644
--- a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/MyFirebaseMessagingService.java
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/MyFirebaseMessagingService.java
@@ -26,26 +26,23 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.net.Uri;
-import android.support.v4.app.NotificationCompat;
+import androidx.core.app.NotificationCompat;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyAndroidFCMService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
- //Log data to Log Cat
+ //Log busRoutes to Log Cat
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
//create notification
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/PDFFactory.java b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/PDFFactory.java
index 3cc07f2..90da45f 100644
--- a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/PDFFactory.java
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/PDFFactory.java
@@ -14,7 +14,7 @@ public class PDFFactory {
private PDF PURPLE44 = new PDF("Purple 44", "purple_44_schedule");
private PDF RED26 = new PDF("Red 26", "red_26_schedule");
private PDF REMOTEEXPRESS = new PDF("Remote Express 48", "remoteexpress_48_schedule");
- private PDF ROUTE13 = new PDF("Route 13", "route_13_schedule");
+ private PDF ROUTE13 = new PDF("BusRoute 13", "route_13_schedule");
private PDF TAN35 = new PDF("Tan 35", "tan_35_schedule");
private PDF YELLOW12 = new PDF("Yellow 12", "yellow_12_schedule");
private PDF GRAY21 = new PDF("Gray 21", "gray_21_schedule");
@@ -34,7 +34,7 @@ public class PDFFactory {
private PDF PURPLE44_ROUTE = new PDF("Purple 44", "purple_44_route");
private PDF RED26_ROUTE = new PDF("Red 26", "red_26_route");
private PDF REMOTEEXPRESS_ROUTE = new PDF("Remote Express 48", "remoteexpress_48_route");
- private PDF ROUTE13_ROUTE = new PDF("Route 13", "route_13_route");
+ private PDF ROUTE13_ROUTE = new PDF("BusRoute 13", "route_13_route");
private PDF TAN35_ROUTE = new PDF("Tan 35", "tan_35_route");
private PDF YELLOW12_ROUTE = new PDF("Yellow 12", "yellow_12_route");
private PDF GRAY21_ROUTE = new PDF("Gray 21", "gray_21_route");
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/ParkingMapFragment.java b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/ParkingMapFragment.java
index ab10756..cdcaa02 100644
--- a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/ParkingMapFragment.java
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/ParkingMapFragment.java
@@ -3,7 +3,7 @@
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
+import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -12,6 +12,9 @@
import java.io.InputStream;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.Unbinder;
/**
@@ -24,9 +27,9 @@
*/
public class ParkingMapFragment extends Fragment {
- private PDFView pdfView;
+ @BindView(R.id.pdfView) PDFView pdfView;
+ private Unbinder unbinder;
private Boolean loaded;
-
private OnFragmentInteractionListener mListener;
public ParkingMapFragment() {
@@ -53,8 +56,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_parking_map, container, false);
-
- pdfView = (PDFView)view.findViewById(R.id.pdfView);
+ unbinder = ButterKnife.bind(this, view);
InputStream inputStream = getResources().openRawResource(
getResources().getIdentifier("parkmap",
@@ -97,6 +99,12 @@ public void onDetach() {
mListener = null;
}
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ unbinder.unbind();
+ }
+
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/RoutesFragment.java b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/RoutesFragment.java
index 38fd7d1..3fe2eb1 100644
--- a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/RoutesFragment.java
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/RoutesFragment.java
@@ -2,8 +2,8 @@
import android.content.Context;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.ListFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/SchedulesFragment.java b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/SchedulesFragment.java
index eaefd4a..ff648ad 100644
--- a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/SchedulesFragment.java
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/SchedulesFragment.java
@@ -2,8 +2,8 @@
import android.content.Context;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.ListFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/ViewRouteFragment.java b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/ViewRouteFragment.java
index d924195..694b097 100644
--- a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/ViewRouteFragment.java
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/ViewRouteFragment.java
@@ -3,7 +3,7 @@
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
+import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -12,6 +12,9 @@
import java.io.InputStream;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
/**
* A simple {@link Fragment} subclass.
@@ -27,7 +30,7 @@ public class ViewRouteFragment extends Fragment {
private static final String ARG_PARAM1 = "filepath";
private String mParam1;
- private PDFView pdfView;
+ @BindView(R.id.pdfView) PDFView pdfView;
private OnFragmentInteractionListener mListener;
@@ -56,7 +59,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_view_route, container, false);
- pdfView = (PDFView)view.findViewById(R.id.pdfView);
+ ButterKnife.bind(this, view);
InputStream inputStream = getResources().openRawResource(
getResources().getIdentifier(mParam1,
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/ViewScheduleFragment.java b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/ViewScheduleFragment.java
index f82999d..a763e71 100644
--- a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/ViewScheduleFragment.java
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/ViewScheduleFragment.java
@@ -3,7 +3,7 @@
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
+import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -13,6 +13,9 @@
import java.io.InputStream;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
/**
* A simple {@link Fragment} subclass.
@@ -24,11 +27,9 @@
*/
public class ViewScheduleFragment extends Fragment {
+ @BindView(R.id.pdfView) PDFView pdfView;
private static final String ARG_PARAM1 = "filepath";
-
private String mParam1;
- private PDFView pdfView;
-
private OnFragmentInteractionListener mListener;
public ViewScheduleFragment() {
@@ -57,7 +58,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_view_schedule, container, false);
- pdfView = (PDFView)view.findViewById(R.id.pdfView);
+ ButterKnife.bind(this, view);
InputStream inputStream = getResources().openRawResource(
getResources().getIdentifier(mParam1,
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/bus/Bus.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/bus/Bus.kt
new file mode 100644
index 0000000..21d75f2
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/bus/Bus.kt
@@ -0,0 +1,27 @@
+package razorbacktransit.arcu.razorbacktransit.model.bus
+
+import com.google.android.gms.maps.model.BitmapDescriptor
+import com.google.android.gms.maps.model.LatLng
+import com.google.android.gms.maps.model.MarkerOptions
+
+data class Bus(val id: String,
+ val fleet: String,
+ val name: String,
+ val description: String,
+ val zonarId: String,
+ val gpsId: String,
+ val coordinates: LatLng,
+ val speed: Float,
+ val heading: Int,
+ val power: Boolean,
+ val date: String,
+ val color: String?,
+ val routeName: String?,
+ val routeId: String?,
+ val distance: Double?,
+ val nextStop: String?,
+ val nextArrival: String?)
+{
+ @Transient var icon: MarkerOptions? = null
+ @Transient var ids: String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/bus/BusJson.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/bus/BusJson.kt
new file mode 100644
index 0000000..7b1bbc0
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/bus/BusJson.kt
@@ -0,0 +1,45 @@
+package razorbacktransit.arcu.razorbacktransit.model.bus
+
+import com.google.android.gms.maps.model.LatLng
+import com.squareup.moshi.Json
+import kotlin.math.roundToInt
+
+data class BusJson(@Json(name = "id") val id: String,
+ @Json(name = "fleet") val fleet: String,
+ @Json(name = "name") val name: String,
+ @Json(name = "description") val description: String,
+ @Json(name = "zonarId") val zonarId: String,
+ @Json(name = "gpsId") val gpsId: String,
+ @Json(name = "latitude") val latitude: Double,
+ @Json(name = "longitude") val longitude: Double,
+ @Json(name = "speed") val speed: Float,
+ @Json(name = "heading") val heading: Float,
+ @Json(name = "power") val power: Boolean,
+ @Json(name = "date") val date: String,
+ @Json(name = "color") val color: String?,
+ @Json(name = "routeName") val routeName: String?,
+ @Json(name = "routeId") val routeId: String?,
+ @Json(name = "distance") val distance: Double?,
+ @Json(name = "nextStop") val nextStop: String?,
+ @Json(name = "nextArrival") val nextArrival: String?)
+{
+ fun toBus() = Bus(
+ id = id,
+ fleet = fleet,
+ name = name,
+ description = description,
+ zonarId = zonarId,
+ gpsId = gpsId,
+ coordinates = LatLng(latitude, longitude),
+ speed = speed,
+ heading = heading.roundToInt(),
+ power = power,
+ date = date,
+ color = color,
+ routeName = routeName,
+ routeId = routeId,
+ distance = distance,
+ nextStop = nextStop,
+ nextArrival = nextArrival
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/bus/BusJsonAdapter.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/bus/BusJsonAdapter.kt
new file mode 100644
index 0000000..4d38954
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/bus/BusJsonAdapter.kt
@@ -0,0 +1,8 @@
+package razorbacktransit.arcu.razorbacktransit.model.bus
+
+import com.squareup.moshi.FromJson
+
+class BusJsonAdapter
+{
+ @FromJson fun busFromJson(busJson: BusJson): Bus = busJson.toBus()
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/route/Route.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/route/Route.kt
new file mode 100644
index 0000000..2ee4aa8
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/route/Route.kt
@@ -0,0 +1,16 @@
+package razorbacktransit.arcu.razorbacktransit.model.route
+
+import com.google.android.gms.maps.model.LatLng
+
+data class Route(val id: Int,
+ val name: String,
+ val description: String,
+ val color: Int,
+ val coordinates: List,
+ val status: Int,
+ val inService: Boolean,
+ val pdfUrl: String?,
+ val nextArrival: String?,
+ val length: Float,
+ val departureStop: Int,
+ val nextDeparture: String?)
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/route/RouteJson.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/route/RouteJson.kt
new file mode 100644
index 0000000..e6a0a57
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/route/RouteJson.kt
@@ -0,0 +1,51 @@
+package razorbacktransit.arcu.razorbacktransit.model.route
+
+import android.graphics.Color
+import com.google.android.gms.maps.model.LatLng
+import com.squareup.moshi.Json
+
+data class RouteJson(@field:Json(name = "id") val id: Int,
+ @field:Json(name = "name") val name: String,
+ @field:Json(name = "description") val description: String,
+ @field:Json(name = "color") val color: String,
+ @field:Json(name = "shape") val shape: String,
+ @field:Json(name = "status") val status: Int,
+ @field:Json(name = "inService") val inService: Int,
+ @field:Json(name = "url") val pdfUrl: String?,
+ @field:Json(name = "nextArrival") val nextArrival: String?,
+ @field:Json(name = "length") val length: Float,
+ @field:Json(name = "departureStop") val departureStop: Int,
+ @field:Json(name = "nextDeparture") val nextDeparture: String?)
+{
+ fun toRoute(): Route
+ {
+ val coords = parseCoordinates( this.shape )
+ return Route(
+ id = id,
+ name = name,
+ description = description,
+ color = Color.parseColor( color ),
+ coordinates = coords,
+ status = status,
+ inService = inService == 1,
+ pdfUrl = pdfUrl,
+ nextArrival = nextArrival,
+ length = length,
+ departureStop = departureStop,
+ nextDeparture = nextDeparture
+ )
+ }
+
+ private fun parseCoordinates( shape: String ): List
+ {
+ val pairs = shape.split(",")
+ val list = arrayListOf()
+ for(pair in pairs)
+ {
+ val latLongPair = pair.split(" ")
+ list.add( LatLng( latLongPair[0].toDouble(), latLongPair[1].toDouble() ) )
+
+ }
+ return list
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/route/RouteJsonAdapter.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/route/RouteJsonAdapter.kt
new file mode 100644
index 0000000..83b8f46
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/route/RouteJsonAdapter.kt
@@ -0,0 +1,8 @@
+package razorbacktransit.arcu.razorbacktransit.model.route
+
+import com.squareup.moshi.FromJson
+
+class RouteJsonAdapter
+{
+ @FromJson fun routeFromJson( routeJson: RouteJson ): Route = routeJson.toRoute()
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/stop/Stop.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/stop/Stop.kt
new file mode 100644
index 0000000..b4d46e9
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/stop/Stop.kt
@@ -0,0 +1,16 @@
+package razorbacktransit.arcu.razorbacktransit.model.stop
+
+import com.google.android.gms.maps.model.LatLng
+import com.google.android.gms.maps.model.MarkerOptions
+
+class Stop(val id: String,
+ val name: String,
+ val description: String,
+ val coordinates: LatLng,
+ val order: Int,
+ val distance: String?,
+ val nextArrival: String?)
+{
+ @Transient var icon: MarkerOptions? = null
+ @Transient var routeIds: String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/stop/StopJson.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/stop/StopJson.kt
new file mode 100644
index 0000000..21c9fab
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/stop/StopJson.kt
@@ -0,0 +1,24 @@
+package razorbacktransit.arcu.razorbacktransit.model.stop
+
+import com.google.android.gms.maps.model.LatLng
+import com.squareup.moshi.Json
+
+data class StopJson(@Json(name = "id") val id: String,
+ @Json(name = "name") val name: String,
+ @Json(name = "description") val description: String,
+ @Json(name = "latitude") val latitude: String,
+ @Json(name = "longitude") val longitude: String,
+ @Json(name = "order") val order: Int,
+ @Json(name = "distance") val distance: String?,
+ @Json(name = "nextArrival") val nextArrival: String?)
+{
+ fun toStop() = Stop(
+ id = id,
+ name = name,
+ description = description,
+ coordinates = LatLng(latitude.toDouble(), longitude.toDouble()),
+ order = order,
+ distance = distance,
+ nextArrival = nextArrival
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/stop/StopJsonAdapter.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/stop/StopJsonAdapter.kt
new file mode 100644
index 0000000..c1c6aba
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/model/stop/StopJsonAdapter.kt
@@ -0,0 +1,8 @@
+package razorbacktransit.arcu.razorbacktransit.model.stop
+
+import com.squareup.moshi.FromJson
+
+class StopJsonAdapter
+{
+ @FromJson fun stopFromJson(stopJson: StopJson): Stop = stopJson.toStop()
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/CampusService.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/CampusService.kt
new file mode 100644
index 0000000..52b0d76
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/CampusService.kt
@@ -0,0 +1,29 @@
+package razorbacktransit.arcu.razorbacktransit.network
+
+import io.reactivex.Flowable
+import okhttp3.ResponseBody
+import razorbacktransit.arcu.razorbacktransit.model.bus.Bus
+import razorbacktransit.arcu.razorbacktransit.model.route.Route
+import razorbacktransit.arcu.razorbacktransit.model.stop.Stop
+import retrofit2.http.GET
+import retrofit2.http.Query
+import retrofit2.http.QueryMap
+
+// Base
+// https://campusdata.uark.edu/api/
+interface CampusService
+{
+ @GET("routes")
+ fun getRoutes(): Flowable>
+
+ @GET("buses")
+ fun getBuses(@Query("routeIds") ids: String ): Flowable>
+
+ @GET("stops")
+ fun getStops(@Query("routeIds") ids: String ): Flowable>
+}
+// Buildings
+// https://campusdata.uark.edu/api/buildings?callback=Buildings
+
+// Routes
+// https://campusdata.uark.edu/api/routes?callback=Routes
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/LiveMapViewModel.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/LiveMapViewModel.kt
new file mode 100644
index 0000000..0049805
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/LiveMapViewModel.kt
@@ -0,0 +1,49 @@
+package razorbacktransit.arcu.razorbacktransit.network
+
+import android.app.Application
+import android.util.Log
+import androidx.lifecycle.AndroidViewModel
+import io.reactivex.Flowable
+import io.reactivex.schedulers.Schedulers
+import java.util.concurrent.TimeUnit
+
+class LiveMapViewModel(application: Application): AndroidViewModel(application)
+{
+ private val applicationContext = application.applicationContext
+ private val routeNetworking = RouteNetworking(applicationContext)
+ private val updateBusesNotification = Flowable.interval(5, TimeUnit.SECONDS, Schedulers.io())
+ .map { Unit }
+ .share()
+
+ private val routes: Flowable = updateBusesNotification
+ .compose(routeNetworking.routesEndpoint)
+ .map {
+ if(it is NetworkState.Success.Routes)
+ {
+ it.busRoutes = it.busRoutes.filter{ route -> listOf(221, 223, 227).contains(route.id) }
+ }
+ return@map it
+ }
+ .share()
+
+ private val routesUi: Flowable = routes
+ .ofType(NetworkState.Success.Routes::class.java)
+ .map { return@map SubmitUiModel.SubmitRoute(it.busRoutes) }
+ .distinctUntilChanged()
+
+ private val buses: Flowable = routes
+ .ofType(NetworkState.Success.Routes::class.java)
+ .compose(routeNetworking.buses)
+ .distinctUntilChanged()
+
+ private val stops: Flowable = routes
+ .ofType(NetworkState.Success.Routes::class.java)
+ .compose(routeNetworking.stops)
+ .distinctUntilChanged { old, new -> old.stops != new.stops }
+ .flatMapIterable { it.stops }
+ .map { SubmitUiModel.SubmitStop(it) }
+
+ val observeAll: Flowable = Flowable.merge(routesUi, buses, stops)
+ .onBackpressureDrop()
+ .share()
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/NetworkState.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/NetworkState.kt
new file mode 100644
index 0000000..5a66b33
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/NetworkState.kt
@@ -0,0 +1,17 @@
+package razorbacktransit.arcu.razorbacktransit.network
+
+import razorbacktransit.arcu.razorbacktransit.model.bus.Bus
+import razorbacktransit.arcu.razorbacktransit.model.route.Route
+import razorbacktransit.arcu.razorbacktransit.model.stop.Stop
+
+sealed class NetworkState
+{
+ class InTransit(val message: String = ""): NetworkState()
+ sealed class Success: NetworkState()
+ {
+ class Routes(var busRoutes: List): Success()
+ class Buses(val buses: List): Success()
+ class Stops(val stops: List): Success()
+ }
+ class Failure(val t: Throwable): NetworkState()
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/NetworkUtils.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/NetworkUtils.kt
new file mode 100644
index 0000000..7f589eb
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/NetworkUtils.kt
@@ -0,0 +1,64 @@
+package razorbacktransit.arcu.razorbacktransit.network
+
+import android.util.Log
+import io.reactivex.Flowable
+import okhttp3.HttpUrl
+import razorbacktransit.arcu.razorbacktransit.model.route.Route
+
+fun getBusImageUrl(color: String, heading: String): String = HttpUrl.Builder()
+ .scheme("https")
+ .host("campusdata.uark.edu")
+ .addPathSegment("api")
+ .addPathSegment("busimages")
+ .addQueryParameter("color", color.replace("#", ""))
+ .addQueryParameter("heading", heading)
+ .build()
+ .uri()
+ .toASCIIString()
+
+fun getStopImageUrl(stopId: String, routeIds: String): String = HttpUrl.Builder()
+ .scheme("https")
+ .host("campusdata.uark.edu")
+ .addPathSegment("api")
+ .addPathSegment("stopimages")
+ .addQueryParameter("stopId", stopId)
+ .addQueryParameter("routeIds", routeIds)
+ .build()
+ .uri()
+ .toASCIIString()
+
+fun Flowable>.buildBusIdsString(): Flowable
+{
+ return this.map { it.map { route -> route.id } }
+ .filter { it.isNotEmpty() }
+ .map { ids: List ->
+ var idString = ""
+ for (id in ids)
+ {
+ idString += "$id-"
+ }
+ if (idString[idString.lastIndex] == '-')
+ {
+ return@map idString.substring(0, idString.lastIndex)
+ }
+ return@map idString
+ }
+}
+
+fun Flowable>.buildStopIdsString(): Flowable
+{
+ return this.map { it.map { route -> route.id } }
+ .filter { it.isNotEmpty() }
+ .map { ids: List ->
+ var idString = ""
+ for (id in ids)
+ {
+ idString += "$id-"
+ }
+ if (idString[idString.lastIndex] == '-')
+ {
+ return@map idString.substring(0, idString.lastIndex)
+ }
+ return@map idString
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/RouteNetworking.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/RouteNetworking.kt
new file mode 100644
index 0000000..9b239da
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/RouteNetworking.kt
@@ -0,0 +1,143 @@
+package razorbacktransit.arcu.razorbacktransit.network
+
+import android.content.Context
+import com.bumptech.glide.Glide
+import com.google.android.gms.maps.model.MarkerOptions
+import com.squareup.moshi.Moshi
+import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
+import io.reactivex.Flowable
+import io.reactivex.FlowableTransformer
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.schedulers.Schedulers
+import razorbacktransit.arcu.razorbacktransit.model.bus.Bus
+import razorbacktransit.arcu.razorbacktransit.model.bus.BusJsonAdapter
+import razorbacktransit.arcu.razorbacktransit.model.route.Route
+import razorbacktransit.arcu.razorbacktransit.model.route.RouteJsonAdapter
+import razorbacktransit.arcu.razorbacktransit.model.stop.Stop
+import razorbacktransit.arcu.razorbacktransit.model.stop.StopJsonAdapter
+import razorbacktransit.arcu.razorbacktransit.utils.toBitMapDescriptor
+import retrofit2.Retrofit
+import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
+import retrofit2.converter.moshi.MoshiConverterFactory
+
+class RouteNetworking(private val applicationContext: Context)
+{
+ private val widthPixels: Int = applicationContext.resources.displayMetrics.widthPixels
+
+ private val moshiAdapter = Moshi.Builder()
+ .add(RouteJsonAdapter())
+ .add(BusJsonAdapter())
+ .add(StopJsonAdapter())
+ .add(KotlinJsonAdapterFactory())
+ .build()
+
+ private val campusAPI: CampusService = Retrofit.Builder()
+ .baseUrl("https://campusdata.uark.edu/api/")
+ .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
+ .addConverterFactory(MoshiConverterFactory.create(moshiAdapter).asLenient())
+ .build()
+ .create(CampusService::class.java)
+
+ val routesEndpoint: FlowableTransformer = FlowableTransformer {
+ it.observeOn(Schedulers.io())
+ .flatMap {
+ campusAPI.getRoutes()
+ .map { routes: List -> NetworkState.Success.Routes(routes) }
+ .onErrorReturn { t -> NetworkState.Failure(t) }
+ .observeOn(AndroidSchedulers.mainThread())
+ .startWith(NetworkState.InTransit())
+ }
+ }
+
+ val buses: FlowableTransformer = FlowableTransformer {
+ it.compose(busesEndpoint)
+ .ofType(NetworkState.Success.Buses::class.java)
+ .compose(busImagesEndpoint)
+ }
+
+ private val busesEndpoint: FlowableTransformer = FlowableTransformer {
+ it.map { it.busRoutes }
+ .buildBusIdsString()
+ .flatMap { busIds: String ->
+ campusAPI.getBuses(busIds)
+ .map { busses: List -> NetworkState.Success.Buses(busses) }
+ .onErrorReturn { t -> NetworkState.Failure(t) }
+ .observeOn(AndroidSchedulers.mainThread())
+ .startWith(NetworkState.InTransit())
+ }
+ }
+
+ private val busImagesEndpoint: FlowableTransformer = FlowableTransformer {
+ it.observeOn( Schedulers.computation() )
+ .map { it.buses }
+ .observeOn( Schedulers.io() )
+ // Load the images into the busses
+ .flatMap { busses: List ->
+ Flowable.fromIterable( busses )
+ .map {
+ it.apply {
+ if(it.color != null)
+ {
+ val busImageWidth = (widthPixels * 0.05833333333).toInt()
+ val busImageHeight = (widthPixels.toDouble() * 0.05833333333 * 1.6153846154).toInt()
+ val myIcon = Glide.with(applicationContext).load(getBusImageUrl(it.color, heading.toString())).submit().get().toBitMapDescriptor(busImageWidth, busImageHeight)
+ it.icon = MarkerOptions()
+ .title( it.routeName )
+ .position( it.coordinates )
+ .icon( myIcon )
+ .flat(true)
+ .alpha(0f)
+ }
+ }
+ }
+ .observeOn(Schedulers.computation())
+ .toList().toFlowable()
+ .map { buses -> return@map SubmitUiModel.SubmitBuses(buses) }
+ }
+ }
+
+ val stops: FlowableTransformer = FlowableTransformer {
+ it.compose(loadStops)
+ .ofType(NetworkState.Success.Stops::class.java)
+ .compose(stopImages)
+ }
+
+ private val loadStops: FlowableTransformer = FlowableTransformer {
+ it.map { it.busRoutes }
+ .buildStopIdsString()
+ .observeOn( Schedulers.io() )
+ .flatMap { ids: String ->
+ campusAPI.getStops( ids )
+ .map { stops: List -> NetworkState.Success.Stops( stops.onEach { it.routeIds = ids } ) }
+ .onErrorReturn{ t -> NetworkState.Failure( t ) }
+ .observeOn( AndroidSchedulers.mainThread() )
+ .startWith( NetworkState.InTransit() )
+ }
+ }
+
+ private val stopImages: FlowableTransformer = FlowableTransformer {
+ it.observeOn(Schedulers.computation())
+ .map { it.stops }
+ .observeOn( Schedulers.computation() )
+ .switchMap {stops: List ->
+ Flowable.fromIterable( stops )
+ .map {
+ val stopImageWidth = (widthPixels * 0.02638888889).toInt()
+ val stopImageHeight = (widthPixels * 0.02638888889).toInt()
+ val myIcon = Glide.with(applicationContext).load(getStopImageUrl(it.id, it.routeIds!!)).submit().get().toBitMapDescriptor(stopImageWidth, stopImageHeight)
+ it.icon = MarkerOptions()
+ .snippet( it.name )
+ .title( it.nextArrival )
+ .position( it.coordinates )
+ .icon( myIcon )
+ .flat(true)
+ .alpha(0f)
+ return@map it
+ }
+ .toList()
+ .toFlowable()
+ .map { return@map SubmitUiModel.SubmitStops(it) }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/SubmitUiModel.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/SubmitUiModel.kt
new file mode 100644
index 0000000..fc9d71d
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/network/SubmitUiModel.kt
@@ -0,0 +1,14 @@
+package razorbacktransit.arcu.razorbacktransit.network
+
+import razorbacktransit.arcu.razorbacktransit.model.bus.Bus
+import razorbacktransit.arcu.razorbacktransit.model.route.Route
+import razorbacktransit.arcu.razorbacktransit.model.stop.Stop
+
+sealed class SubmitUiModel
+{
+ class SubmitBuses(val bus: List): SubmitUiModel()
+ class SubmitStops(val stops: List): SubmitUiModel()
+ class SubmitStop(val stop: Stop): SubmitUiModel()
+ class SubmitRoute(val route: List): SubmitUiModel()
+ class InProgress(): SubmitUiModel()
+}
\ No newline at end of file
diff --git a/app/src/main/java/razorbacktransit/arcu/razorbacktransit/utils/Utils.kt b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/utils/Utils.kt
new file mode 100644
index 0000000..c4c4bdc
--- /dev/null
+++ b/app/src/main/java/razorbacktransit/arcu/razorbacktransit/utils/Utils.kt
@@ -0,0 +1,42 @@
+package razorbacktransit.arcu.razorbacktransit.utils
+
+import android.graphics.drawable.Drawable
+import android.util.Log
+import androidx.core.graphics.drawable.toBitmap
+import com.google.android.gms.maps.model.BitmapDescriptor
+import com.google.android.gms.maps.model.BitmapDescriptorFactory
+import com.google.android.gms.maps.model.Marker
+import io.reactivex.Flowable
+import razorbacktransit.arcu.razorbacktransit.model.route.Route
+import razorbacktransit.arcu.razorbacktransit.network.NetworkState
+
+fun Flowable.logNetworkState( methodName: String ): Flowable
+{
+ return this.doOnNext {
+ when(it)
+ {
+ is NetworkState.Failure ->
+ {
+ Log.d("NETWORKDEBUGGING", "$methodName: FAILURE, ${it.t.localizedMessage}")
+ it.t.printStackTrace()
+ }
+ is NetworkState.InTransit -> Log.d("NETWORKDEBUGGING", "$methodName: IN TRANSIT")
+ is NetworkState.Success -> Log.d("NETWORKDEBUGGING", "$methodName: SUCCESS")
+ }
+ }
+
+}
+
+fun ArrayList.clearMarkers()
+{
+ for(marker in this)
+ {
+ marker.remove()
+ }
+ this.clear()
+}
+
+fun Drawable.toBitMapDescriptor(width: Int, height: Int): BitmapDescriptor
+{
+ return BitmapDescriptorFactory.fromBitmap(this.toBitmap(width, height))
+}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index a61d8a6..8e69e22 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,5 +1,5 @@
-
-
-
+
diff --git a/app/src/main/res/layout/app_bar_main.xml b/app/src/main/res/layout/app_bar_main.xml
index 6517f69..7132181 100644
--- a/app/src/main/res/layout/app_bar_main.xml
+++ b/app/src/main/res/layout/app_bar_main.xml
@@ -1,26 +1,26 @@
-
-
-
-
+
-
+
diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml
index 3f65978..5e8fe3c 100644
--- a/app/src/main/res/layout/content_main.xml
+++ b/app/src/main/res/layout/content_main.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/build.gradle b/build.gradle
index 558fdf8..870de58 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,16 +1,18 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
+ ext.kotlin_version = '1.3.11'
repositories {
jcenter()
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.1.4'
+ classpath 'com.android.tools.build:gradle:3.3.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'com.google.gms:google-services:4.0.1'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
diff --git a/gradle.properties b/gradle.properties
index aac7c9b..dfd42d6 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -9,8 +9,12 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
+android.enableJetifier=true
+android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
+android.jetifier.blacklist = butterknife-compiler
+
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 8f43cb3..e7b257e 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Tue Jun 19 16:57:27 CDT 2018
+#Tue Jan 15 00:51:33 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip