diff --git a/Hyperrail/build.gradle b/Hyperrail/build.gradle index 2d2cb61d..2fe827c0 100644 --- a/Hyperrail/build.gradle +++ b/Hyperrail/build.gradle @@ -6,6 +6,10 @@ apply plugin: 'com.android.application' apply plugin: 'com.google.firebase.firebase-perf' +apply plugin: 'com.google.firebase.firebase-crash' + +def VERSION_CODE = 4 +def VERSION_NAME = '0.9.2' android { signingConfigs { @@ -24,8 +28,8 @@ android { applicationId "be.hyperrail.android" minSdkVersion 19 targetSdkVersion 25 - versionCode 3 - versionName '0.9.2' + versionCode VERSION_CODE + versionName VERSION_NAME testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true } @@ -50,12 +54,12 @@ dependencies { androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) + compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support:support-v4:25.3.1' compile 'com.android.support:cardview-v7:25.3.1' compile 'com.android.support:recyclerview-v7:25.3.1' compile 'com.android.support:design:25.3.1' - compile 'com.google.android.gms:play-services-location:10.2.6' compile 'com.google.firebase:firebase-crash:10.2.6' compile 'com.google.firebase:firebase-perf:10.2.6' @@ -63,5 +67,4 @@ dependencies { testCompile 'junit:junit:4.12' } - apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/Hyperrail/proguard-rules.pro b/Hyperrail/proguard-rules.pro index 0081dc19..3583512f 100644 --- a/Hyperrail/proguard-rules.pro +++ b/Hyperrail/proguard-rules.pro @@ -15,3 +15,4 @@ #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} +-keepattributes SourceFile,LineNumberTable \ No newline at end of file diff --git a/Hyperrail/src/main/java/be/hyperrail/android/FeedbackFragment.java b/Hyperrail/src/main/java/be/hyperrail/android/FeedbackFragment.java new file mode 100644 index 00000000..97767ee7 --- /dev/null +++ b/Hyperrail/src/main/java/be/hyperrail/android/FeedbackFragment.java @@ -0,0 +1,68 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package be.hyperrail.android; + +import android.app.Fragment; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; + +/** + * A simple {@link Fragment} subclass. + */ +public class FeedbackFragment extends Fragment { + + public FeedbackFragment() { + // Required empty public constructor + } + + public static FeedbackFragment newInstance() { + return new FeedbackFragment(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_feedback, container, false); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + final EditText vFeedbackText = ((EditText) view.findViewById(R.id.input_text)); + + view.findViewById(R.id.button_send).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Context context = FeedbackFragment.this.getActivity(); + String version = "unknown"; + + try { + PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); + version = pInfo.versionName; + } catch (Exception e) { + // Ignored + } + + Intent feedbackEmail = new Intent(Intent.ACTION_SEND); + + feedbackEmail.setType("text/email"); + feedbackEmail.putExtra(Intent.EXTRA_EMAIL, new String[]{"feedback@hyperrail.be"}); + feedbackEmail.putExtra(Intent.EXTRA_SUBJECT, "Feedback for hyperrail " + version); + feedbackEmail.putExtra(Intent.EXTRA_TEXT, vFeedbackText.getText()); + startActivity(Intent.createChooser(feedbackEmail, "Send feedback mail:")); + } + }); + } +} diff --git a/Hyperrail/src/main/java/be/hyperrail/android/LiveboardActivity.java b/Hyperrail/src/main/java/be/hyperrail/android/LiveboardActivity.java index 6b2c98a5..054d0310 100644 --- a/Hyperrail/src/main/java/be/hyperrail/android/LiveboardActivity.java +++ b/Hyperrail/src/main/java/be/hyperrail/android/LiveboardActivity.java @@ -258,7 +258,7 @@ public void markFavorite(boolean favorite) { } if (favorite) { - persistentQueryProvider.addFavoriteStation(mCurrentStation); + mPersistentQuaryProvider.addFavoriteStation(mCurrentStation); Snackbar.make(vLayoutRoot, R.string.marked_station_favorite, Snackbar.LENGTH_SHORT) .setAction(R.string.undo, new View.OnClickListener() { @Override @@ -268,7 +268,7 @@ public void onClick(View v) { }) .show(); } else { - persistentQueryProvider.removeFavoriteStation(mCurrentStation); + mPersistentQuaryProvider.removeFavoriteStation(mCurrentStation); Snackbar.make(vLayoutRoot, R.string.unmarked_station_favorite, Snackbar.LENGTH_SHORT) .setAction(R.string.undo, new View.OnClickListener() { @Override @@ -284,7 +284,7 @@ public void onClick(View v) { @Override public boolean isFavorite() { // If it's not loaded, it's not a favorite - return mCurrentStation != null && persistentQueryProvider.isFavoriteStation(mCurrentStation); + return mCurrentStation != null && mPersistentQuaryProvider.isFavoriteStation(mCurrentStation); } diff --git a/Hyperrail/src/main/java/be/hyperrail/android/MainActivity.java b/Hyperrail/src/main/java/be/hyperrail/android/MainActivity.java index f3112989..db9ed9c7 100644 --- a/Hyperrail/src/main/java/be/hyperrail/android/MainActivity.java +++ b/Hyperrail/src/main/java/be/hyperrail/android/MainActivity.java @@ -51,6 +51,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On private static final int VIEW_TYPE_ROUTE = 1; private static final int VIEW_TYPE_DISTURBANCE = 2; private static final int VIEW_TYPE_SETTINGS = 3; + private static final int VIEW_TYPE_FEEDBACK = 4; private boolean mDualPane = false; @@ -178,6 +179,10 @@ private void setView(int i, Bundle args) { frg = DisturbanceListFragment.newInstance(); setSubTitle(R.string.title_disturbances); break; + case VIEW_TYPE_FEEDBACK: + frg = FeedbackFragment.newInstance(); + setSubTitle(R.string.title_feedback); + break; } if (args != null){ frg.setArguments(args); @@ -221,6 +226,9 @@ public boolean onNavigationItemSelected(@NonNull MenuItem item) { Intent i = new Intent(this, SettingsActivity.class); startActivity(i); break; + case R.id.action_feedback: + setView(VIEW_TYPE_FEEDBACK,null); + break; } if (!mDualPane) { vDrawerLayout.closeDrawers(); diff --git a/Hyperrail/src/main/java/be/hyperrail/android/RecyclerViewActivity.java b/Hyperrail/src/main/java/be/hyperrail/android/RecyclerViewActivity.java index 09e92cef..c3a1e515 100644 --- a/Hyperrail/src/main/java/be/hyperrail/android/RecyclerViewActivity.java +++ b/Hyperrail/src/main/java/be/hyperrail/android/RecyclerViewActivity.java @@ -76,7 +76,7 @@ public abstract class RecyclerViewActivity extends AppCompatActivity implemen /** * History & favorites provider */ - PersistentQueryProvider persistentQueryProvider; + PersistentQueryProvider mPersistentQuaryProvider; /** * Favorite button in menu @@ -98,9 +98,9 @@ public abstract class RecyclerViewActivity extends AppCompatActivity implemen protected SharedPreferences mSharedPreferences; /** - * Wether or not to show dividers between list items + * Whether or not to show dividers between list items */ - protected boolean show_dividers = true; + protected boolean mShowDividers = true; @Override protected void onCreate(Bundle savedInstanceState) { @@ -115,7 +115,7 @@ protected void onCreate(Bundle savedInstanceState) { setSupportActionBar(toolbar); // Initialize history & favorites, preferences - persistentQueryProvider = new PersistentQueryProvider(this.getApplicationContext()); + mPersistentQuaryProvider = new PersistentQueryProvider(this.getApplicationContext()); mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext()); // Initialize pull to refresh @@ -145,7 +145,7 @@ public void onRefresh() { vRecyclerView.setLayoutManager(mLayoutManager); // Show dividers in case wanted & not using the card layout - if (show_dividers && !PreferenceManager.getDefaultSharedPreferences(this.getApplication()).getBoolean("use_card_layout", false)) { + if (mShowDividers && !PreferenceManager.getDefaultSharedPreferences(this.getApplication()).getBoolean("use_card_layout", false)) { // Cards have their own division by margin, others need a divider vRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)); } diff --git a/Hyperrail/src/main/java/be/hyperrail/android/RouteActivity.java b/Hyperrail/src/main/java/be/hyperrail/android/RouteActivity.java index 1c4ad9d5..d5936331 100644 --- a/Hyperrail/src/main/java/be/hyperrail/android/RouteActivity.java +++ b/Hyperrail/src/main/java/be/hyperrail/android/RouteActivity.java @@ -295,7 +295,7 @@ public void loadMoreRecyclerviewItems() { public void markFavorite(boolean favorite) { if (favorite) { - persistentQueryProvider.addFavoriteRoute(mSearchFrom, mSearchTo); + mPersistentQuaryProvider.addFavoriteRoute(mSearchFrom, mSearchTo); Snackbar.make(vLayoutRoot, R.string.marked_route_favorite, Snackbar.LENGTH_SHORT) .setAction(R.string.undo, new View.OnClickListener() { @Override @@ -305,7 +305,7 @@ public void onClick(View v) { }) .show(); } else { - persistentQueryProvider.removeFavoriteRoute(mSearchFrom, mSearchTo); + mPersistentQuaryProvider.removeFavoriteRoute(mSearchFrom, mSearchTo); Snackbar.make(vLayoutRoot, R.string.unmarked_route_favorite, Snackbar.LENGTH_SHORT) .setAction(R.string.undo, new View.OnClickListener() { @Override @@ -319,6 +319,6 @@ public void onClick(View v) { } public boolean isFavorite() { - return persistentQueryProvider.isFavoriteRoute(mSearchFrom, mSearchTo); + return mPersistentQuaryProvider.isFavoriteRoute(mSearchFrom, mSearchTo); } } diff --git a/Hyperrail/src/main/java/be/hyperrail/android/RouteDetailActivity.java b/Hyperrail/src/main/java/be/hyperrail/android/RouteDetailActivity.java index ed9c9c69..4b4eb132 100644 --- a/Hyperrail/src/main/java/be/hyperrail/android/RouteDetailActivity.java +++ b/Hyperrail/src/main/java/be/hyperrail/android/RouteDetailActivity.java @@ -47,7 +47,7 @@ public static Intent createIntent(Context c, Route r) { @Override protected void onCreate(Bundle savedInstanceState) { route = (Route) getIntent().getSerializableExtra("route"); - this.show_dividers = false; + this.mShowDividers = false; super.onCreate(savedInstanceState); diff --git a/Hyperrail/src/main/java/be/hyperrail/android/adapter/TrainCardAdapter.java b/Hyperrail/src/main/java/be/hyperrail/android/adapter/TrainCardAdapter.java index 668622d8..6fccb814 100644 --- a/Hyperrail/src/main/java/be/hyperrail/android/adapter/TrainCardAdapter.java +++ b/Hyperrail/src/main/java/be/hyperrail/android/adapter/TrainCardAdapter.java @@ -101,8 +101,7 @@ public void onBindViewHolder(TrainStopViewHolder holder, int position) { } } - // TODO: fix this as soon as hasLeft is reliable - if (s.hasLeft() || true) { + if (s.hasLeft()) { if (position == 0) { holder.vIcon.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.timeline_departure_filled)); } else if (position == this.getItemCount() - 1) { diff --git a/Hyperrail/src/main/java/be/hyperrail/android/irail/db/StationsDb.java b/Hyperrail/src/main/java/be/hyperrail/android/irail/db/StationsDb.java index 4a1abd94..b3625875 100644 --- a/Hyperrail/src/main/java/be/hyperrail/android/irail/db/StationsDb.java +++ b/Hyperrail/src/main/java/be/hyperrail/android/irail/db/StationsDb.java @@ -333,6 +333,12 @@ public int compare(Station o1, Station o2) { */ @Override public String[] getStationNames(Station[] Stations) { + + if (Stations == null ||Stations.length == 0){ + FirebaseCrash.logcat(WARNING.intValue(),LOGTAG,"Tried to load station names on empty station list!"); + return new String[0]; + } + String[] results = new String[Stations.length]; for (int i = 0; i < Stations.length; i++) { results[i] = Stations[i].getLocalizedName(); @@ -450,6 +456,12 @@ public Station getStationByName(String name) { */ private Station[] loadStationCursor(Cursor c) { if (c.isClosed()) { + FirebaseCrash.logcat(SEVERE.intValue(),LOGTAG,"Tried to load closed cursor"); + return null; + } + + if (c.getCount() == 0){ + FirebaseCrash.logcat(SEVERE.intValue(),LOGTAG,"Tried to load cursor with 0 results!"); return null; } diff --git a/Hyperrail/src/main/java/be/hyperrail/android/irail/implementation/IrailApiParser.java b/Hyperrail/src/main/java/be/hyperrail/android/irail/implementation/IrailApiParser.java index b7222e9e..92a63028 100644 --- a/Hyperrail/src/main/java/be/hyperrail/android/irail/implementation/IrailApiParser.java +++ b/Hyperrail/src/main/java/be/hyperrail/android/irail/implementation/IrailApiParser.java @@ -254,7 +254,7 @@ private TrainStop parseTrainStop(Station destination, TrainStub t, JSONObject it item.getInt("arrivalDelay"), item.getInt("departureCanceled") != 0, item.getInt("arrivalCanceled") != 0, - false + item.getInt("left") == 1 ); } @@ -275,19 +275,11 @@ public Train parseTrain(JSONObject jsonData, Date searchdate) throws JSONExcepti TrainStop[] stops = new TrainStop[jsonStops.length()]; TrainStub t = new TrainStub(id, destination); - TrainStop lastHaltedStop = null; - for (int i = 0; i < jsonStops.length(); i++) { stops[i] = parseTrainStop(destination, t, jsonStops.getJSONObject(i)); - if (stops[i].getStation().getLatitude() == latitude && stops[i].getStation().getLongitude() == longitude) { - lastHaltedStop = stops[i]; - for (int j = i; j >=0; j--){ - stops[j].setHasLeft(true); - } - } } - return new Train(id, destination, stops[0].getStation(), longitude, latitude, stops, lastHaltedStop); + return new Train(id, destination, stops[0].getStation(), longitude, latitude, stops); } private static Date timestamp2date(String time) { diff --git a/Hyperrail/src/main/java/be/hyperrail/android/irail/implementation/Train.java b/Hyperrail/src/main/java/be/hyperrail/android/irail/implementation/Train.java index c4c472bc..21923092 100644 --- a/Hyperrail/src/main/java/be/hyperrail/android/irail/implementation/Train.java +++ b/Hyperrail/src/main/java/be/hyperrail/android/irail/implementation/Train.java @@ -29,15 +29,20 @@ public class Train extends TrainStub implements Serializable { private final Station origin; private final TrainStop[] stops; - private final TrainStop lastHaltedStop; + private TrainStop lastHaltedStop; - Train(String id, Station destination, Station origin, double longitude, double latitude, TrainStop[] stops, TrainStop lastHaltedStop) { + Train(String id, Station destination, Station origin, double longitude, double latitude, TrainStop[] stops) { super(id, destination); this.origin = origin; this.longitude = longitude; this.latitude = latitude; this.stops = stops; - this.lastHaltedStop = lastHaltedStop; + + for (int i = 0; i < stops.length; i++){ + if (stops[i].hasLeft()){ + lastHaltedStop = stops[i]; + } + } } public Station getOrigin() { diff --git a/Hyperrail/src/main/java/be/hyperrail/android/persistence/PersistentQueryProvider.java b/Hyperrail/src/main/java/be/hyperrail/android/persistence/PersistentQueryProvider.java index b51b5a35..f247adfc 100644 --- a/Hyperrail/src/main/java/be/hyperrail/android/persistence/PersistentQueryProvider.java +++ b/Hyperrail/src/main/java/be/hyperrail/android/persistence/PersistentQueryProvider.java @@ -17,6 +17,8 @@ import android.preference.PreferenceManager; import android.util.Log; +import com.google.firebase.crash.FirebaseCrash; + import org.json.JSONException; import org.json.JSONObject; @@ -30,6 +32,7 @@ import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.logging.Level; import be.hyperrail.android.irail.contracts.IrailStationProvider; import be.hyperrail.android.irail.db.Station; @@ -91,7 +94,7 @@ public PersistentQueryProvider(Context context) { if (sharedPreferences.getBoolean("migrated1.9.1", false)) { for (String tag : new String[]{TAG_FAV_ROUTES, TAG_FAV_STATIONS, TAG_RECENT_ROUTES, TAG_RECENT_STATIONS}) { - Log.d("PersistentMigration","Tag " + tag ); + Log.d("PersistentMigration", "Tag " + tag); Set oldValue = context.getSharedPreferences(PREFERENCES_NAME, 0).getStringSet(tag, new HashSet()); ArrayList newValue = new ArrayList<>(); @@ -101,16 +104,16 @@ public PersistentQueryProvider(Context context) { JSONObject object = new JSONObject(entry); Station from = stationProvider.getStationByName(object.getString("from")); Station to; - if (! object.getString("to").equals("")) { + if (!object.getString("to").equals("")) { to = stationProvider.getStationByName(object.getString("to")); } else { to = null; } - Log.d("PersistentMigration","FROM " + object.getString("from") + " - " + from.getId()); + Log.d("PersistentMigration", "FROM " + object.getString("from") + " - " + from.getId()); if (to != null) { Log.d("PersistentMigration", "TO " + object.getString("to") + " - " + to.getId()); } else { - Log.d("PersistentMigration","TO " + object.getString("to") + " - NULL"); + Log.d("PersistentMigration", "TO " + object.getString("to") + " - NULL"); } RouteQuery query = new RouteQuery(from, to); newValue.add(query); @@ -121,8 +124,8 @@ public PersistentQueryProvider(Context context) { clear(tag); - for (RouteQuery q: newValue){ - store(tag,q); + for (RouteQuery q : newValue) { + store(tag, q); } } sharedPreferences.edit().putBoolean("migrated1.9.1", true).apply(); @@ -489,6 +492,11 @@ private ArrayList load(String tag, int limit, RouteQuery.RouteQueryT * @return List or routeQueries */ private ArrayList load(String tag, int limit, boolean timeSensitive, RouteQuery.RouteQueryType type) { + + if (limit <= 0) { + return new ArrayList<>(0); + } + SharedPreferences settings = context.getSharedPreferences(PREFERENCES_NAME, 0); Set items = settings.getStringSet(tag, null); @@ -591,16 +599,25 @@ private ArrayList setToList(Set set, RouteQuery.RouteQueryTy for (String entry : set) { try { JSONObject object = new JSONObject(entry); + Station from = stationProvider.getStationById(object.getString("from")); Station to = null; - if (! object.getString("to").equals("")) { + + if (!object.getString("to").equals("")) { to = stationProvider.getStationById(object.getString("to")); } + RouteQuery query = new RouteQuery(from, to); query.created_at = new Date(object.getLong("created_at")); query.type = type; + + if (from == null) { + FirebaseCrash.logcat(Level.SEVERE.intValue(), "PersistentQuery", "Loaded invalid routeQuery: " + object.getString("from") + " could not be decoded! Type is " + type.toString()); + } + results.add(query); } catch (JSONException exception) { + FirebaseCrash.logcat(Level.WARNING.intValue(), "PersistentQuery", "Failed to load routequery for type " + type.toString() + ": " + exception.getMessage()); // ignored } } @@ -649,7 +666,7 @@ private Collection removeFromCollection(Collection colle Set toBeRemoved = new HashSet<>(); for (RouteQuery entry : collection) { for (RouteQuery removalEntry : remove) { - if (entry.from.getId().equals(removalEntry.from.getId()) && ((entry.to != null && removalEntry.to != null && entry.to.getId().equals(removalEntry.to.getId()))||(entry.to == null && removalEntry.to == null))) { + if (entry.from.getId().equals(removalEntry.from.getId()) && ((entry.to != null && removalEntry.to != null && entry.to.getId().equals(removalEntry.to.getId())) || (entry.to == null && removalEntry.to == null))) { toBeRemoved.add(entry); } } diff --git a/Hyperrail/src/main/res/drawable-hdpi/ic_action_github.png b/Hyperrail/src/main/res/drawable-hdpi/ic_action_github.png new file mode 100644 index 00000000..bc9331c4 Binary files /dev/null and b/Hyperrail/src/main/res/drawable-hdpi/ic_action_github.png differ diff --git a/Hyperrail/src/main/res/drawable-hdpi/ic_feedback.png b/Hyperrail/src/main/res/drawable-hdpi/ic_feedback.png new file mode 100644 index 00000000..2b832f5b Binary files /dev/null and b/Hyperrail/src/main/res/drawable-hdpi/ic_feedback.png differ diff --git a/Hyperrail/src/main/res/drawable-mdpi/ic_action_github.png b/Hyperrail/src/main/res/drawable-mdpi/ic_action_github.png new file mode 100644 index 00000000..5fc2d0e9 Binary files /dev/null and b/Hyperrail/src/main/res/drawable-mdpi/ic_action_github.png differ diff --git a/Hyperrail/src/main/res/drawable-mdpi/ic_feedback.png b/Hyperrail/src/main/res/drawable-mdpi/ic_feedback.png new file mode 100644 index 00000000..904bc585 Binary files /dev/null and b/Hyperrail/src/main/res/drawable-mdpi/ic_feedback.png differ diff --git a/Hyperrail/src/main/res/drawable-xhdpi/ic_action_github.png b/Hyperrail/src/main/res/drawable-xhdpi/ic_action_github.png new file mode 100644 index 00000000..63addc7c Binary files /dev/null and b/Hyperrail/src/main/res/drawable-xhdpi/ic_action_github.png differ diff --git a/Hyperrail/src/main/res/drawable-xhdpi/ic_feedback.png b/Hyperrail/src/main/res/drawable-xhdpi/ic_feedback.png new file mode 100644 index 00000000..ae2af08c Binary files /dev/null and b/Hyperrail/src/main/res/drawable-xhdpi/ic_feedback.png differ diff --git a/Hyperrail/src/main/res/drawable-xxhdpi/ic_action_github.png b/Hyperrail/src/main/res/drawable-xxhdpi/ic_action_github.png new file mode 100644 index 00000000..08b2aaac Binary files /dev/null and b/Hyperrail/src/main/res/drawable-xxhdpi/ic_action_github.png differ diff --git a/Hyperrail/src/main/res/drawable-xxhdpi/ic_feedback.png b/Hyperrail/src/main/res/drawable-xxhdpi/ic_feedback.png new file mode 100644 index 00000000..c0ef921e Binary files /dev/null and b/Hyperrail/src/main/res/drawable-xxhdpi/ic_feedback.png differ diff --git a/Hyperrail/src/main/res/drawable-xxxhdpi/ic_action_github.png b/Hyperrail/src/main/res/drawable-xxxhdpi/ic_action_github.png new file mode 100644 index 00000000..067d1fdd Binary files /dev/null and b/Hyperrail/src/main/res/drawable-xxxhdpi/ic_action_github.png differ diff --git a/Hyperrail/src/main/res/drawable-xxxhdpi/ic_feedback.png b/Hyperrail/src/main/res/drawable-xxxhdpi/ic_feedback.png new file mode 100644 index 00000000..015a3690 Binary files /dev/null and b/Hyperrail/src/main/res/drawable-xxxhdpi/ic_feedback.png differ diff --git a/Hyperrail/src/main/res/layout/activity_main.xml b/Hyperrail/src/main/res/layout/activity_main.xml index 843ac7c2..3acdaf16 100644 --- a/Hyperrail/src/main/res/layout/activity_main.xml +++ b/Hyperrail/src/main/res/layout/activity_main.xml @@ -1,35 +1,35 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> - + + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/drawer" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context="be.hyperrail.android.MainActivity"> + android:layout_height="wrap_content"/> - + \ No newline at end of file diff --git a/Hyperrail/src/main/res/layout/fragment_disturbance_list.xml b/Hyperrail/src/main/res/layout/fragment_disturbance_list.xml index ffc04bb6..3dcd5f56 100644 --- a/Hyperrail/src/main/res/layout/fragment_disturbance_list.xml +++ b/Hyperrail/src/main/res/layout/fragment_disturbance_list.xml @@ -4,6 +4,18 @@ android:layout_height="match_parent" tools:context="be.hyperrail.android.DisturbanceListFragment"> + + + + + + + diff --git a/Hyperrail/src/main/res/layout/fragment_feedback.xml b/Hyperrail/src/main/res/layout/fragment_feedback.xml new file mode 100644 index 00000000..d0b9234a --- /dev/null +++ b/Hyperrail/src/main/res/layout/fragment_feedback.xml @@ -0,0 +1,34 @@ + + + + + + + + +