diff --git a/README.md b/README.md index 19708d7..c4fd739 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,10 @@ # ScoutingApp2025 Ridgebotics 2024 scouting app in Android + +TODO: +- QR Code data transfer +- Data Saving and transmitting +- Format event selector page better on mobile. +- Scouting +- Data Visualization +- Testing on new tablets \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 42834b8..1e39859 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + { + + private Function resultFunction = null; + + @Override + protected String doInBackground(String... uri) { + try { + URL url = new URL(uri[0]); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + String[] headers = uri[1].split(", "); + for(String header : headers){ + String[] split = header.split(": "); + conn.setRequestProperty(split[0], split[1]); + } + if(conn.getResponseCode() == HttpsURLConnection.HTTP_OK){ +// ByteArrayOutputStream out = new ByteArrayOutputStream(); + + return readStream(conn.getInputStream()); + // Do normal input or output stream reading + } + else { + return null; // See documentation for more info on response handling + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + private static String readStream(InputStream in) { + BufferedReader reader = null; + StringBuffer response = new StringBuffer(); + try { + reader = new BufferedReader(new InputStreamReader(in)); + String line = ""; + while ((line = reader.readLine()) != null) { + response.append(line); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return response.toString(); + } + + public void onResult(Function func) { + this.resultFunction = func; + } + + @Override + protected void onPostExecute(String result) { + super.onPostExecute(result); + if(resultFunction != null){ + resultFunction.apply(result); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/ui/JSONUtil.java b/app/src/main/java/com/astatin3/scoutingapp2025/ui/JSONUtil.java new file mode 100644 index 0000000..a743fd6 --- /dev/null +++ b/app/src/main/java/com/astatin3/scoutingapp2025/ui/JSONUtil.java @@ -0,0 +1,24 @@ +package com.astatin3.scoutingapp2025.ui; + +import org.json.JSONArray; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class JSONUtil { + public static JSONArray sort(JSONArray array, Comparator c){ + List asList = new ArrayList(array.length()); + for (int i=0; i() { + @Override + public String apply(String s) { + eventTable(s); + return null; + } + }); + rq.execute(TBAAddress + "events/2024", TBAHeader); + } + }); + + alert.create().show(); + } + + private void addTableText(TableRow tr, String textStr){ + TextView text = new TextView(getContext()); + text.setTextSize(18); + text.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); // Text align center + text.setText(textStr); + tr.addView(text); + } + + public void eventTable(String dataString){ + try { + JSONArray data = new JSONArray(dataString); + + Table.setStretchAllColumns(true); + Table.bringToFront(); + + boolean toggle = false; + + TableRow tr = new TableRow(getContext()); + addTableText(tr, "Key"); + addTableText(tr, "Title"); + addTableText(tr, "Type"); + + Table.addView(tr); + + for(int i=0;i() { + @Override + public String apply(String s) { + matchTable(s); + return null; + } + }); + rq.execute((TBAAddress + "event/" + matchKey + "/matches"), TBAHeader); + } + }); + button.setText(matchKey); + tr.addView(button); + + String name = j.getString("short_name"); + + // Sometimes, a short name is not present on TBA Events + if(name.isEmpty()){ + name = j.getString("name"); + } + + addTableText(tr, name); + addTableText(tr, j.getString("event_type_string")); + +// tr.addView(text); + Table.addView(tr); + + toggle = !toggle; + } + }catch (JSONException j){ + alert("Error", "Invalid JSON"); + } + } + + class matchComparator implements Comparator + { + + public int compare(JSONObject a, JSONObject b) + { + try { + return a.getInt("match_number") - b.getInt("match_number"); + }catch (JSONException j){ + return 0; + } + } + } + + + public void matchTable(String dataString){ + try { + JSONArray data = new JSONArray(dataString); + + Table.removeAllViews(); + Table.setStretchAllColumns(true); + Table.bringToFront(); + + + + if(data.length() == 0){ + TableRow tr = new TableRow(getContext()); + addTableText(tr, "This event has no matches released yet..."); + Table.addView(tr); + tr = new TableRow(getContext()); + addTableText(tr, "Try manually adding practice matches."); + Table.addView(tr); + return; + } + + + TableRow tr = new TableRow(getContext()); + addTableText(tr, "#"); + addTableText(tr, "Red-1"); + addTableText(tr, "Red-2"); + addTableText(tr, "Red-3"); + addTableText(tr, "Blue-1"); + addTableText(tr, "Blue-2"); + addTableText(tr, "Blue-3"); + Table.addView(tr); + + + data = JSONUtil.sort(data, new Comparator(){ + public int compare(Object a, Object b){ + JSONObject ja = (JSONObject)a; + JSONObject jb = (JSONObject)b; + try { + return ja.getInt("match_number") - jb.getInt("match_number"); + }catch (JSONException j){ + return 0; + } + } + }); + + + boolean toggle = false; + int matchCount = 1; + + for(int a=0;a mText; + + public TBAViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("This is dashboard fragment"); + + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/ui/dashboard/DashboardFragment.java b/app/src/main/java/com/astatin3/scoutingapp2025/ui/dashboard/DashboardFragment.java deleted file mode 100644 index b148fd5..0000000 --- a/app/src/main/java/com/astatin3/scoutingapp2025/ui/dashboard/DashboardFragment.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.astatin3.scoutingapp2025.ui.dashboard; - -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.graphics.Color; -import android.os.Bundle; -import android.util.Log; -import android.util.TypedValue; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TableLayout; -import android.widget.TableRow; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProvider; - -import com.astatin3.scoutingapp2025.R; -import com.astatin3.scoutingapp2025.databinding.FragmentDashboardBinding; - -public class DashboardFragment extends Fragment { - - private FragmentDashboardBinding binding; - private TableLayout Table; - - public View onCreateView(@NonNull LayoutInflater inflater, - ViewGroup container, Bundle savedInstanceState) { - DashboardViewModel dashboardViewModel = - new ViewModelProvider(this).get(DashboardViewModel.class); - - binding = FragmentDashboardBinding.inflate(inflater, container, false); - View root = binding.getRoot(); - - Table = binding.matchTable; - - warnPopup(); - - return root; - } - - public void warnPopup(){ - AlertDialog.Builder alert = new AlertDialog.Builder(getContext()); - alert.setMessage("This is an alert with no consequence"); - alert.setTitle("App Title"); - alert.setPositiveButton("OK", null); - alert.setCancelable(false); - - alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - showTableLayout(); - } - }); - - alert.create().show(); - } - - public void showTableLayout(){ -// Date date = new Date(); - int rows = 200; - int columns = 10; - Table.setStretchAllColumns(true); - Table.bringToFront(); - - for(int i = 0; i < rows; i++){ - - TableRow tr = new TableRow(getContext()); - - Button button = new Button(getContext()); - button.setText("test"); - tr.addView(button); - - TextView text = new TextView(getContext()); - text.setTextSize(18); - text.setText("eee"); - tr.addView(text); - - Table.addView(tr); - } - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - binding = null; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/ui/dashboard/DashboardViewModel.java b/app/src/main/java/com/astatin3/scoutingapp2025/ui/dashboard/DashboardViewModel.java deleted file mode 100644 index 44a4362..0000000 --- a/app/src/main/java/com/astatin3/scoutingapp2025/ui/dashboard/DashboardViewModel.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.astatin3.scoutingapp2025.ui.dashboard; - -import android.graphics.Color; -import android.util.TypedValue; -import android.view.Gravity; -import android.widget.TableRow; -import android.widget.TextView; - -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.ViewModel; - -public class DashboardViewModel extends ViewModel { - -// private class row { -// public row() { -// -// } -// } - - private final MutableLiveData mText; - - public DashboardViewModel() { - mText = new MutableLiveData<>(); - mText.setValue("This is dashboard fragment"); -// -// final TextView row = new TextView(getContext()); -//// setContentView() -// -// row.setLayoutParams(new -// TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, -// TableRow.LayoutParams.WRAP_CONTENT)); -// -//// TableLayout list = (TableLayout) this.findViewById(R.id.matchTable); -//// View list = inflater.inflate(inflater, container, findViewById(R.id.toastViewGroup)); -// -// -// row.setGravity(Gravity.END); -// row.setTextSize(TypedValue.COMPLEX_UNIT_PX, 10); -// row.setPadding(5, 1, 0, 5); -// row.setTextColor(Color.parseColor("#aaaaaa")); -// row.setBackgroundColor(Color.parseColor("#f8f8f8")); -// row.setText("testing!!"); -// .addView(row); - } - - public LiveData getText() { - return mText; - } -} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index f3d9b08..eca3b2c 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -4,19 +4,4 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.home.HomeFragment"> - - - \ No newline at end of file + tools:context=".ui.home.HomeFragment"/> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_tba.xml similarity index 70% rename from app/src/main/res/layout/fragment_dashboard.xml rename to app/src/main/res/layout/fragment_tba.xml index 2bbbcdd..34ae460 100644 --- a/app/src/main/res/layout/fragment_dashboard.xml +++ b/app/src/main/res/layout/fragment_tba.xml @@ -4,12 +4,18 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.dashboard.DashboardFragment"> + tools:context=".ui.TBA.TBAFragment"> + android:layout_marginBottom="57dp" + android:fillViewport="true" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> - - - + \ No newline at end of file diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index c3a21ef..c15cd1f 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -11,21 +11,21 @@ android:label="@string/title_home" tools:layout="@layout/fragment_home" > + android:id="@+id/action_navigation_home_to_navigation_tba" + app:destination="@id/navigation_tba" /> + app:destination="@id/navigation_tba" /> + tools:layout="@layout/fragment_tba" >