diff --git a/app/.gitignore b/app/.gitignore
deleted file mode 100644
index 796b96d..0000000
--- a/app/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
diff --git a/app/build.gradle b/app/build.gradle
deleted file mode 100644
index 7cde814..0000000
--- a/app/build.gradle
+++ /dev/null
@@ -1,29 +0,0 @@
-apply plugin: 'com.android.application'
-
-android {
- compileSdkVersion 28
- defaultConfig {
- applicationId "com.example.hochi.nextcompanion"
- minSdkVersion 15
- targetSdkVersion 28
- versionCode 9
- versionName "0.1.7.2"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- }
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-}
-
-dependencies {
- implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'com.android.support:appcompat-v7:28.0.0'
- implementation 'com.android.support.constraint:constraint-layout:1.1.3'
- implementation 'com.android.support:design:28.0.0'
- testImplementation 'junit:junit:4.12'
- androidTestImplementation 'com.android.support.test:runner:1.0.2'
- androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
-}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
deleted file mode 100644
index f1b4245..0000000
--- a/app/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/app/src/androidTest/java/com/example/hochi/nextcompanion/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/hochi/nextcompanion/ExampleInstrumentedTest.java
deleted file mode 100644
index 2759dd6..0000000
--- a/app/src/androidTest/java/com/example/hochi/nextcompanion/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.example.hochi.nextcompanion;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("com.example.hochi.nextcompanion", appContext.getPackageName());
- }
-}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
deleted file mode 100644
index f15290c..0000000
--- a/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png
deleted file mode 100644
index e96c6aa..0000000
Binary files a/app/src/main/ic_launcher-web.png and /dev/null differ
diff --git a/app/src/main/java/com/example/hochi/nextcompanion/AsyncTaskCallbacks.java b/app/src/main/java/com/example/hochi/nextcompanion/AsyncTaskCallbacks.java
deleted file mode 100644
index 2099b15..0000000
--- a/app/src/main/java/com/example/hochi/nextcompanion/AsyncTaskCallbacks.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.example.hochi.nextcompanion;
-
-interface AsyncTaskCallbacks {
- void onTaskComplete(T response);
-}
diff --git a/app/src/main/java/com/example/hochi/nextcompanion/LoginActivity.java b/app/src/main/java/com/example/hochi/nextcompanion/LoginActivity.java
deleted file mode 100644
index 1ff8e6b..0000000
--- a/app/src/main/java/com/example/hochi/nextcompanion/LoginActivity.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package com.example.hochi.nextcompanion;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.annotation.TargetApi;
-
-import android.content.SharedPreferences;
-import android.support.v7.app.AppCompatActivity;
-
-import android.os.Build;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.inputmethod.EditorInfo;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-
-import org.json.JSONObject;
-
-
-/**
- * A login screen that offers login via phone number/pin.
- */
-public class LoginActivity extends AppCompatActivity implements AsyncTaskCallbacks {
-
- /**
- * Keep track of the login task to ensure we can cancel it if requested.
- */
- private RequestHandler mAuthTask = null;
-
- // UI references.
- private TextView mPhoneView;
- private EditText mPinView;
- private View mProgressView;
- private View mLoginFormView;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_login);
- // Set up the login form.
- mPhoneView = findViewById(R.id.phone);
-
- mPinView = findViewById(R.id.pin);
- mPinView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
- @Override
- public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
- if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) {
- attemptLogin();
- return true;
- }
- return false;
- }
- });
-
- Button mPhoneSignInButton = findViewById(R.id.phone_sign_in_button);
- mPhoneSignInButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- attemptLogin();
- }
- });
-
- mLoginFormView = findViewById(R.id.login_form);
- mProgressView = findViewById(R.id.login_progress);
- }
-
- /**
- * Attempts to sign in or register the account specified by the login form.
- * If there are form errors (invalid phone number, missing fields, etc.), the
- * errors are presented and no actual login attempt is made.
- */
- private void attemptLogin() {
- if (mAuthTask != null) {
- return;
- }
-
- // Reset errors.
- mPhoneView.setError(null);
- mPinView.setError(null);
-
- // Store values at the time of the login attempt.
- String phone = mPhoneView.getText().toString();
- String pin = mPinView.getText().toString();
- String[] credentials = {
- "apikey=", getString(R.string.apikey),
- "mobile=", mPhoneView.getText().toString(),
- "pin=", mPinView.getText().toString()
- };
-
- boolean cancel = false;
- View focusView = null;
-
- // Check for a valid pin, if the user entered one.
- if (TextUtils.isEmpty(pin)) {
- mPinView.setError(getString(R.string.error_field_required));
- focusView = mPinView;
- cancel = true;
- }
-
- // Check for a valid phone address.
- if (TextUtils.isEmpty(phone)) {
- mPhoneView.setError(getString(R.string.error_field_required));
- focusView = mPhoneView;
- cancel = true;
- }
-
- if (cancel) {
- // There was an error; don't attempt login and focus the first
- // form field with an error.
- focusView.requestFocus();
- } else {
- // Show a progress spinner, and kick off a background task to
- // perform the user login attempt.
- showProgress(true);
- mAuthTask = new RequestHandler(this, "POST",
- "api/login.json", credentials);
- mAuthTask.execute((Void) null);
- }
- }
-
- /**
- * Shows the progress UI and hides the login form.
- */
- @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
- private void showProgress(final boolean show) {
- // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
- // for very easy animations. If available, use these APIs to fade-in
- // the progress spinner.
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
- int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
-
- mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
- mLoginFormView.animate().setDuration(shortAnimTime).alpha(
- show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
- }
- });
-
- mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
- mProgressView.animate().setDuration(shortAnimTime).alpha(
- show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
- }
- });
- } else {
- // The ViewPropertyAnimator APIs are not available, so simply show
- // and hide the relevant UI components.
- mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
- mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
- }
- }
-
- @Override
- public void onTaskComplete(String response) {
- //Callback called when RequestHandler finished request
- if (!response.isEmpty()) {
- try {
- JSONObject jObject = new JSONObject(response);
- JSONObject userObject = jObject.getJSONObject("user");
- String loginkey = userObject.getString("loginkey");
- SharedPreferences sharedPref = getSharedPreferences("persistence", MODE_PRIVATE);
- SharedPreferences.Editor editor = sharedPref.edit();
- editor.putString("loginKey", loginkey);
- editor.apply();
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- finish();
- } else {
- mPinView.setError(getString(R.string.error_incorrect_pin));
- mPinView.requestFocus();
- }
- }
-}
-
diff --git a/app/src/main/java/com/example/hochi/nextcompanion/MainActivity.java b/app/src/main/java/com/example/hochi/nextcompanion/MainActivity.java
deleted file mode 100644
index ee51d6e..0000000
--- a/app/src/main/java/com/example/hochi/nextcompanion/MainActivity.java
+++ /dev/null
@@ -1,175 +0,0 @@
-package com.example.hochi.nextcompanion;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.design.widget.FloatingActionButton;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
-import android.view.View;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.util.ArrayList;
-
-public class MainActivity extends AppCompatActivity implements AsyncTaskCallbacks {
- private RequestHandler getBikesTask = null;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- //now this "every android activity" stuff
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Toolbar toolbar = findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
- final Context context = this;
-
- //Floating Button
- FloatingActionButton fab = findViewById(R.id.fab);
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent intent = new Intent(context, RentActivity.class);
- startActivity(intent);
- }
- });
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- //pre-condition: Is there a login key?
- SharedPreferences sharedPref = getSharedPreferences("persistence", MODE_PRIVATE);
- String defaultValue = "nokey";
- String loginKey = sharedPref.getString("loginKey", defaultValue);
- //if not, go to LoginActivity
- if (loginKey.equals("nokey")) {
- Intent intent = new Intent(this, LoginActivity.class);
- startActivity(intent);
- }
- else {
- reloadBikeList();
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.menu_main, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // Handle action bar item clicks here. The action bar will
- // automatically handle clicks on the Home/Up button, so long
- // as you specify a parent activity in AndroidManifest.xml.
- int id = item.getItemId();
-
-
- //noinspection SimplifiableIfStatement
- if (id == R.id.action_logout) {
- SharedPreferences sharedPref = getSharedPreferences("persistence", MODE_PRIVATE);
- SharedPreferences.Editor editor = sharedPref.edit();
- editor.remove("loginKey");
- editor.apply();
- Intent intent = new Intent(this, LoginActivity.class);
- startActivity(intent);
- }
-
- if (id == R.id.action_map) {
- Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.map_url)));
- startActivity(browserIntent);
- }
-
- return super.onOptionsItemSelected(item);
- }
-
- protected void reloadBikeList() {
- //get loginkey
- SharedPreferences sharedPref = getSharedPreferences("persistence", MODE_PRIVATE);
- String defaultValue = "nokey";
- String loginKey = sharedPref.getString("loginKey", defaultValue);
-
- String[] params = {
- "apikey=", getString(R.string.apikey),
- "loginkey=", loginKey
- };
-
- getBikesTask = new RequestHandler(this, "POST",
- "api/getOpenRentals.json", params);
- getBikesTask.execute((Void) null);
- }
-
- @Override
- public void onTaskComplete(String response) {
- //Callback called when RequestHandler finished request
- final Context context = this;
- if (!response.isEmpty()) {
- final ArrayList list = new ArrayList<>();
- try {
- JSONObject jObject = new JSONObject(response);
- JSONArray bikesArray = jObject.getJSONArray("rentalCollection");
- for (int i = 0; i < bikesArray.length(); i++) {
- String entry;
- JSONObject bike = bikesArray.getJSONObject(i);
- entry = "Bike " + bike.getString("bike")
- + " with lock code " + bike.getString("code");
- list.add(entry);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- //Create and fill list
- final ListView listview = findViewById(R.id.listview);
- final ArrayAdapter adapter = new ArrayAdapter<>(this,
- android.R.layout.simple_list_item_1, list);
- listview.setAdapter(adapter);
-
- //Print indicator if empty
- TextView tv = findViewById(R.id.noBikes);
- if(list.isEmpty()) tv.setVisibility(View.VISIBLE);
- else tv.setVisibility(View.INVISIBLE);
-
- try {
- final JSONObject jObject = new JSONObject(response);
- final JSONArray bikesArray = jObject.getJSONArray("rentalCollection");
- listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView> parent, final View view, int position, long id) {
- Intent intent = new Intent(context, ReturnActivity.class);
- try {
- JSONObject bike = bikesArray.getJSONObject(position);
- String bID = bike.getString("bike");
- String stID = bike.getString("start_place");
- String lockE = bike.getString("electric_lock");
- String[] bikeArray = {bID, stID, lockE};
- intent.putExtra("bike", bikeArray);
- startActivity(intent);
- }
- catch (JSONException e) {
- e.printStackTrace();
- }
- }
-
- });
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- else {
- //TODO: implement error handling
- }
- }
-}
diff --git a/app/src/main/java/com/example/hochi/nextcompanion/RentActivity.java b/app/src/main/java/com/example/hochi/nextcompanion/RentActivity.java
deleted file mode 100644
index 4b1eb87..0000000
--- a/app/src/main/java/com/example/hochi/nextcompanion/RentActivity.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.example.hochi.nextcompanion;
-
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.Uri;
-import android.support.v7.app.AppCompatActivity;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.Button;
-import android.widget.TextView;
-
-import org.w3c.dom.Text;
-
-public class RentActivity extends AppCompatActivity implements AsyncTaskCallbacks {
- private RequestHandler rentRequestTask = null;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_rent);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- Button mRentSubmitButton = findViewById(R.id.rent_submit_button);
- mRentSubmitButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- rentRequest();
- }
- });
-
- Intent intent = getIntent();
- Uri data = intent.getData();
-
- if (data != null) {
- String bikeID = data.toString().substring(15);
- ((TextView) findViewById(R.id.bike_id)).setText(bikeID);
- }
- }
-
- void rentRequest() {
- //Prepare request to rent bike
- TextView mBikeInput;
- mBikeInput = findViewById(R.id.bike_id);
- String bikeID = mBikeInput.getText().toString();
- //get loginkey
- SharedPreferences sharedPref = getSharedPreferences("persistence", MODE_PRIVATE);
- String defaultValue = "nokey";
- String loginKey = sharedPref.getString("loginKey", defaultValue);
-
- String[] params = {
- "apikey=", getString(R.string.apikey),
- "loginkey=", loginKey,
- "bike=", bikeID
- };
-
- rentRequestTask = new RequestHandler(this, "POST",
- "api/rent.json", params);
- rentRequestTask.execute((Void) null);
- }
-
- @Override
- public void onTaskComplete(String response) {
- //get back to main activity
- //TODO: *any* response handling
- finish();
- }
-}
diff --git a/app/src/main/java/com/example/hochi/nextcompanion/RequestHandler.java b/app/src/main/java/com/example/hochi/nextcompanion/RequestHandler.java
deleted file mode 100644
index 2476e63..0000000
--- a/app/src/main/java/com/example/hochi/nextcompanion/RequestHandler.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package com.example.hochi.nextcompanion;
-
-import android.os.AsyncTask;
-
-import java.io.BufferedReader;
-import java.io.DataOutputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLEncoder;
-
-public class RequestHandler extends AsyncTask {
-
- private String mHTTPmethod;
- private String mEndpoint;
- private AsyncTaskCallbacks callback;
- private String[] mCredentials;
-
- RequestHandler(AsyncTaskCallbacks act, String HTTPmethod,
- String endpoint, String[] credentials) {
- mHTTPmethod = HTTPmethod;
- mEndpoint = endpoint;
- mCredentials = credentials;
- callback = act;
- }
-
- @Override
- protected String doInBackground(Void... params) {
- StringBuilder response = new StringBuilder();
- StringBuilder urlParameters = new StringBuilder();
- int i=0;
- while (i {
- private String[] bikeArray;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_return);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-
-
- Intent intent = getIntent();
- bikeArray = intent.getStringArrayExtra("bike");
-
- //if GPS and electric lock, show the instruction
- TextView tv = findViewById(R.id.gps_info);
- LinearLayout la = findViewById(R.id.return_form_container);
- if(bikeArray[2].equals("true")) {
- tv.setVisibility(View.VISIBLE);
- la.setVisibility(View.INVISIBLE);
- }
- else {
- la.setVisibility(View.VISIBLE);
- tv.setVisibility(View.INVISIBLE);
- Button mReturnSubmitButton = findViewById(R.id.return_submit_button);
- mReturnSubmitButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- returnRequest();
- }
- });
- }
- }
- void returnRequest() {
- TextView mStationInput;
- mStationInput = findViewById(R.id.return_station_id);
- String stationID = mStationInput.getText().toString();
- //get loginkey
- SharedPreferences sharedPref = getSharedPreferences("persistence", MODE_PRIVATE);
- String defaultValue = "nokey";
- String loginKey = sharedPref.getString("loginKey", defaultValue);
-
- String[] params = {
- "apikey=", getString(R.string.apikey),
- "bike=", bikeArray[0],
- "loginkey=", loginKey,
- "station=", stationID,
- "comment=", ""
- };
- RequestHandler returnRequestTask = new RequestHandler(this, "POST",
- "api/return.json", params);
- returnRequestTask.execute((Void) null);
- }
-
- @Override
- public void onTaskComplete(String response) {
- //get back to main activity
- //TODO: *any* response handling
- finish();
- }
-}
diff --git a/app/src/main/res/drawable/ic_add_white_24dp.xml b/app/src/main/res/drawable/ic_add_white_24dp.xml
deleted file mode 100644
index b5b5ba4..0000000
--- a/app/src/main/res/drawable/ic_add_white_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
deleted file mode 100644
index de480af..0000000
--- a/app/src/main/res/layout/activity_login.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
deleted file mode 100644
index d48b1b1..0000000
--- a/app/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_rent.xml b/app/src/main/res/layout/activity_rent.xml
deleted file mode 100644
index fb3084d..0000000
--- a/app/src/main/res/layout/activity_rent.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_return.xml b/app/src/main/res/layout/activity_return.xml
deleted file mode 100644
index 5728d58..0000000
--- a/app/src/main/res/layout/activity_return.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml
deleted file mode 100644
index ef9edf3..0000000
--- a/app/src/main/res/layout/content_main.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml
deleted file mode 100644
index e2970cd..0000000
--- a/app/src/main/res/menu/menu_main.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
deleted file mode 100644
index 036d09b..0000000
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
deleted file mode 100644
index 036d09b..0000000
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 287a510..0000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
deleted file mode 100644
index 6c91c71..0000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
deleted file mode 100644
index 595b2c8..0000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index ded5dc9..0000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
deleted file mode 100644
index 03ca674..0000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
deleted file mode 100644
index 92b9d0c..0000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 661eb62..0000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
deleted file mode 100644
index d0b1866..0000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
deleted file mode 100644
index 5c57a47..0000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index e83664a..0000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
deleted file mode 100644
index 11e7dfc..0000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
deleted file mode 100644
index ac47ad8..0000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index d9dbdd8..0000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
deleted file mode 100644
index a6563a5..0000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
deleted file mode 100644
index 120860f..0000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
deleted file mode 100644
index 4c558ea..0000000
--- a/app/src/main/res/values-de/strings.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
- NextCompanion
-
- Ausloggen
- Anmelden
- Mobiltelefonnummer
- Pin
- Anmelden
- Anmelden
- Telefonnummer ist inkorrekt
- Pin oder Telefonnummer ist inkorrekt
- Feld ist erforderlich
- Rad ausleihen
- Fahrrad-ID eingeben
- Ausleihen
- Nummer der Rückgabestation
- Rückgabe
- Fahrrad zurückgeben
- Karte
- Keine Räder geliehen…
- Dieses Rad ein elektronisches Schloss. Zur Rückgabe bitte das Schloss schließen.
-
-
- 3IaBlP9OZw14dvES
-
- persistence
- Ausleihen mit NextCompanion
-
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
deleted file mode 100644
index 541cfd5..0000000
--- a/app/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- #3F51B5
- #303F9F
- #9c274f
-
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
deleted file mode 100644
index 617af6a..0000000
--- a/app/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
- 16dp
-
- 16dp
- 16dp
-
diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml
deleted file mode 100644
index beab31f..0000000
--- a/app/src/main/res/values/ic_launcher_background.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- #000000
-
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
deleted file mode 100644
index 736f6f6..0000000
--- a/app/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
- NextCompanion
-
- Logout
- Sign in
- Phone number
- Pin
- Sign in
- Sign in
- This phone number is invalid
- This pin or phone number is incorrect
- This field is required
- Rent Bike
- Enter Bike UID
- Rent
- Enter the station UID where you leave the bike
- Return
- Return Bike
- Map
- No bikes here…
- This is a bike with electric lock. Please just close the lock to return.
-
-
- 3IaBlP9OZw14dvES
-
- persistence
- Rent with NextCompanion
-
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
deleted file mode 100644
index d4ea9ae..0000000
--- a/app/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/test/java/com/example/hochi/nextcompanion/ExampleUnitTest.java b/app/src/test/java/com/example/hochi/nextcompanion/ExampleUnitTest.java
deleted file mode 100644
index 8568a8c..0000000
--- a/app/src/test/java/com/example/hochi/nextcompanion/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.example.hochi.nextcompanion;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index 4082391..0000000
--- a/build.gradle
+++ /dev/null
@@ -1,27 +0,0 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-
-buildscript {
-
- repositories {
- google()
- jcenter()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:3.3.1'
-
-
- // NOTE: Do not place your application dependencies here; they belong
- // in the individual module build.gradle files
- }
-}
-
-allprojects {
- repositories {
- google()
- jcenter()
- }
-}
-
-task clean(type: Delete) {
- delete rootProject.buildDir
-}
diff --git a/gradle.properties b/gradle.properties
deleted file mode 100644
index 743d692..0000000
--- a/gradle.properties
+++ /dev/null
@@ -1,13 +0,0 @@
-# Project-wide Gradle settings.
-# IDE (e.g. Android Studio) users:
-# Gradle settings configured through the IDE *will override*
-# any settings specified in this file.
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-org.gradle.jvmargs=-Xmx1536m
-# 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
-# org.gradle.parallel=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 7a3265e..0000000
Binary files a/gradle/wrapper/gradle-wrapper.jar and /dev/null differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 10ff630..0000000
--- a/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Fri May 03 12:47:19 GMT 2019
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
diff --git a/gradlew b/gradlew
deleted file mode 100755
index cccdd3d..0000000
--- a/gradlew
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/usr/bin/env sh
-
-##############################################################################
-##
-## Gradle start up script for UN*X
-##
-##############################################################################
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn () {
- echo "$*"
-}
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=$((i+1))
- done
- case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
-fi
-
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=$(save "$@")
-
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-
-# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
-if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
- cd "$(dirname "$0")"
-fi
-
-exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
deleted file mode 100644
index e95643d..0000000
--- a/gradlew.bat
+++ /dev/null
@@ -1,84 +0,0 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/settings.gradle b/settings.gradle
deleted file mode 100644
index e7b4def..0000000
--- a/settings.gradle
+++ /dev/null
@@ -1 +0,0 @@
-include ':app'
diff --git a/src/main.rs b/src/main.rs
index 31f6de8..1d13efd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -243,7 +243,45 @@ fn build_ui(app: &Application) {
main_hdr.pack_end(&logout_btn);
main_hdr.pack_start(&refresh_btn);
- // ── Return sheet (bottom sheet) ───────────────────────────────────────────
+ // ── Bottom sheet (rent + return) ──────────────────────────────────────────
+
+ // — Rent form —
+ let bike_entry = Entry::builder()
+ .placeholder_text("Bike number")
+ .input_purpose(gtk::InputPurpose::Digits)
+ .build();
+ let rent_err = Label::builder()
+ .css_classes(["error"])
+ .wrap(true)
+ .visible(false)
+ .build();
+ let rent_submit = Button::builder()
+ .label("Rent")
+ .css_classes(["suggested-action", "pill"])
+ .build();
+ let rent_spinner = Spinner::new();
+
+ let rent_sheet = Box::builder()
+ .orientation(Orientation::Vertical)
+ .spacing(16)
+ .build();
+ let rent_sheet_title = Label::builder()
+ .css_classes(["title-4"])
+ .label("Rent Bike")
+ .xalign(0.0)
+ .build();
+ let rent_form = Box::builder()
+ .orientation(Orientation::Vertical)
+ .spacing(12)
+ .build();
+ rent_form.append(&bike_entry);
+ rent_form.append(&rent_err);
+ rent_form.append(&rent_submit);
+ rent_form.append(&rent_spinner);
+ rent_sheet.append(&rent_sheet_title);
+ rent_sheet.append(&rent_form);
+
+ // — Return form —
let station_entry = Entry::builder()
.placeholder_text("Station number")
.input_purpose(gtk::InputPurpose::Digits)
@@ -278,21 +316,31 @@ fn build_ui(app: &Application) {
ret_inner.add_named(&manual_form, Some("manual"));
ret_inner.add_named(&electric_msg, Some("electric"));
- let sheet_title = Label::builder()
+ let ret_sheet = Box::builder()
+ .orientation(Orientation::Vertical)
+ .spacing(16)
+ .build();
+ let ret_sheet_title = Label::builder()
.css_classes(["title-4"])
.label("Return Bike")
.xalign(0.0)
.build();
+ ret_sheet.append(&ret_sheet_title);
+ ret_sheet.append(&ret_inner);
+
+ // — Shared sheet stack —
+ let sheet_stack = Stack::new();
+ sheet_stack.add_named(&rent_sheet, Some("rent"));
+ sheet_stack.add_named(&ret_sheet, Some("return"));
+
let sheet_box = Box::builder()
.orientation(Orientation::Vertical)
- .spacing(16)
.margin_top(8)
.margin_bottom(24)
.margin_start(16)
.margin_end(16)
.build();
- sheet_box.append(&sheet_title);
- sheet_box.append(&ret_inner);
+ sheet_box.append(&sheet_stack);
let bottom_sheet = BottomSheet::builder()
.show_drag_handle(true)
@@ -313,44 +361,6 @@ fn build_ui(app: &Application) {
.child(&main_body)
.build();
- // ── Rent page ─────────────────────────────────────────────────────────────
- let bike_entry = Entry::builder()
- .placeholder_text("Bike number")
- .input_purpose(gtk::InputPurpose::Digits)
- .build();
- let rent_err = Label::builder()
- .css_classes(["error"])
- .wrap(true)
- .visible(false)
- .build();
- let rent_submit = Button::builder()
- .label("Rent")
- .css_classes(["suggested-action", "pill"])
- .build();
- let rent_spinner = Spinner::new();
-
- let rent_form = Box::builder()
- .orientation(Orientation::Vertical)
- .spacing(12)
- .margin_top(24).margin_bottom(24).margin_start(12).margin_end(12)
- .build();
- rent_form.append(&bike_entry);
- rent_form.append(&rent_err);
- rent_form.append(&rent_submit);
- rent_form.append(&rent_spinner);
-
- let rent_clamp = Clamp::builder().maximum_size(400).build();
- rent_clamp.set_child(Some(&rent_form));
-
- let rent_body = Box::builder().orientation(Orientation::Vertical).build();
- rent_body.append(&HeaderBar::new());
- rent_body.append(&rent_clamp);
-
- let rent_page = NavigationPage::builder()
- .title("Rent Bike")
- .child(&rent_body)
- .build();
-
// ── Navigation view ───────────────────────────────────────────────────────
let nav = NavigationView::new();
nav.push(&main_page);
@@ -452,14 +462,17 @@ fn build_ui(app: &Application) {
});
}
- // ── Open rent page ────────────────────────────────────────────────────────
+ // ── Open rent sheet ───────────────────────────────────────────────────────
{
- let nav = nav.clone();
- let rent_page = rent_page.clone();
+ let bottom_sheet = bottom_sheet.clone();
+ let sheet_stack = sheet_stack.clone();
let bike_entry = bike_entry.clone();
+ let rent_err = rent_err.clone();
rent_btn.connect_clicked(move |_| {
bike_entry.set_text("");
- nav.push(&rent_page);
+ rent_err.set_visible(false);
+ sheet_stack.set_visible_child_name("rent");
+ bottom_sheet.set_open(true);
});
}
@@ -470,7 +483,7 @@ fn build_ui(app: &Application) {
let err = rent_err.clone();
let spinner = rent_spinner.clone();
let btn = rent_submit.clone();
- let nav = nav.clone();
+ let bottom_sheet = bottom_sheet.clone();
let bikes = bikes.clone();
let bikes_list = bikes_list.clone();
let list_stack = list_stack.clone();
@@ -489,7 +502,7 @@ fn build_ui(app: &Application) {
let spinner = spinner.clone();
let btn = btn.clone();
let err = err.clone();
- let nav = nav.clone();
+ let bottom_sheet = bottom_sheet.clone();
let bikes = bikes.clone();
let bikes_list = bikes_list.clone();
let list_stack = list_stack.clone();
@@ -505,7 +518,7 @@ fn build_ui(app: &Application) {
err.set_label(&e);
err.set_visible(true);
} else {
- nav.pop();
+ bottom_sheet.set_open(false);
load_rentals(key_reload, bikes, bikes_list, list_stack).await;
}
});
@@ -516,6 +529,7 @@ fn build_ui(app: &Application) {
// ── Click rental row → open return bottom sheet ───────────────────────────
{
let bottom_sheet = bottom_sheet.clone();
+ let sheet_stack = sheet_stack.clone();
let bikes = bikes.clone();
let return_bike = return_bike.clone();
let ret_inner = ret_inner.clone();
@@ -529,6 +543,7 @@ fn build_ui(app: &Application) {
ret_err.set_visible(false);
ret_inner.set_visible_child_name(if bike.electric_lock { "electric" } else { "manual" });
*return_bike.borrow_mut() = Some(bike);
+ sheet_stack.set_visible_child_name("return");
bottom_sheet.set_open(true);
}
});