Menu Viewing!
This commit is contained in:
parent
5bfc54ccd8
commit
b1b2ab5a60
@ -3,7 +3,20 @@
|
|||||||
<component name="deploymentTargetDropDown">
|
<component name="deploymentTargetDropDown">
|
||||||
<value>
|
<value>
|
||||||
<entry key="app">
|
<entry key="app">
|
||||||
<State />
|
<State>
|
||||||
|
<runningDeviceTargetSelectedWithDropDown>
|
||||||
|
<Target>
|
||||||
|
<type value="RUNNING_DEVICE_TARGET" />
|
||||||
|
<deviceKey>
|
||||||
|
<Key>
|
||||||
|
<type value="SERIAL_NUMBER" />
|
||||||
|
<value value="R5CRB1GE0RY" />
|
||||||
|
</Key>
|
||||||
|
</deviceKey>
|
||||||
|
</Target>
|
||||||
|
</runningDeviceTargetSelectedWithDropDown>
|
||||||
|
<timeTargetWasSelectedWithDropDown value="2024-02-17T18:39:39.847936576Z" />
|
||||||
|
</State>
|
||||||
</entry>
|
</entry>
|
||||||
</value>
|
</value>
|
||||||
</component>
|
</component>
|
||||||
|
@ -25,6 +25,7 @@ public class MenuActivity extends AppCompatActivity {
|
|||||||
public static final String NAME_EXTRA = "mtu_name";
|
public static final String NAME_EXTRA = "mtu_name";
|
||||||
public static final String ID_EXTRA = "mtu_id";
|
public static final String ID_EXTRA = "mtu_id";
|
||||||
|
|
||||||
|
private MenuViewModel viewModel;
|
||||||
private MenuAdapter adapter;
|
private MenuAdapter adapter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -41,13 +42,15 @@ public class MenuActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
// Get View Model
|
// Get View Model
|
||||||
ViewModelProvider viewModelProvider = new ViewModelProvider(this);
|
ViewModelProvider viewModelProvider = new ViewModelProvider(this);
|
||||||
MenuViewModel viewModel = viewModelProvider.get(MenuViewModel.class);
|
viewModel = viewModelProvider.get(MenuViewModel.class);
|
||||||
|
|
||||||
// Get Info
|
// Get Info
|
||||||
String name = getIntent().getStringExtra(NAME_EXTRA);
|
String name = getIntent().getStringExtra(NAME_EXTRA);
|
||||||
String id = getIntent().getStringExtra(ID_EXTRA);
|
|
||||||
toolbar.setTitle(name);
|
toolbar.setTitle(name);
|
||||||
viewModel.task.setup(id, new Date());
|
String id = getIntent().getStringExtra(ID_EXTRA);
|
||||||
|
if (!viewModel.task.isSetup()) {
|
||||||
|
viewModel.task.setup(id, new Date());
|
||||||
|
}
|
||||||
|
|
||||||
// Setup RecyclerView
|
// Setup RecyclerView
|
||||||
adapter = new MenuAdapter(viewModel.task);
|
adapter = new MenuAdapter(viewModel.task);
|
||||||
@ -55,6 +58,9 @@ public class MenuActivity extends AppCompatActivity {
|
|||||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||||
recyclerView.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
EdgeToEdgeUtil.setup(this, recyclerView);
|
EdgeToEdgeUtil.setup(this, recyclerView);
|
||||||
|
|
||||||
|
// Handle Existing Date Picker
|
||||||
|
MenuDatePicker.setupListeners(getSupportFragmentManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -73,4 +79,13 @@ public class MenuActivity extends AppCompatActivity {
|
|||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update selected date.
|
||||||
|
* @param newDate New date
|
||||||
|
*/
|
||||||
|
public void updateDate(Date newDate) {
|
||||||
|
viewModel.task.setup(null, newDate);
|
||||||
|
viewModel.task.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.thebrokenrail.mtudining.activity.menu;
|
package com.thebrokenrail.mtudining.activity.menu;
|
||||||
|
|
||||||
import android.text.InputType;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -9,13 +8,15 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.material.textfield.MaterialAutoCompleteTextView;
|
import com.google.android.material.textfield.MaterialAutoCompleteTextView;
|
||||||
import com.google.android.material.textfield.TextInputEditText;
|
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
import com.thebrokenrail.mtudining.R;
|
import com.thebrokenrail.mtudining.R;
|
||||||
import com.thebrokenrail.mtudining.activity.task.Task;
|
import com.thebrokenrail.mtudining.activity.task.Task;
|
||||||
import com.thebrokenrail.mtudining.activity.task.TaskAdapter;
|
import com.thebrokenrail.mtudining.activity.task.TaskAdapter;
|
||||||
import com.thebrokenrail.mtudining.util.DateUtil;
|
import com.thebrokenrail.mtudining.util.DateUtil;
|
||||||
import com.thebrokenrail.mtudining.widget.CategoryView;
|
import com.thebrokenrail.mtudining.widget.CategoryView;
|
||||||
|
import com.thebrokenrail.mtudining.widget.CustomDropDownView;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter for listing dining halls.
|
* Adapter for listing dining halls.
|
||||||
@ -34,32 +35,57 @@ class MenuAdapter extends TaskAdapter<MenuData> {
|
|||||||
return category;
|
return category;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get currently selected meal.
|
||||||
|
* @return A meal menu
|
||||||
|
*/
|
||||||
|
private MenuData.Meal getMeal() {
|
||||||
|
if (getResult() != null) {
|
||||||
|
for (MenuData.Meal meal : getResult().meals) {
|
||||||
|
if (meal.name.equals(getResult().selectedMeal)) {
|
||||||
|
// Found Meal
|
||||||
|
return meal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Could Not Find Meal
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void bindItemView(View view, int position) {
|
protected void bindItemView(View view, int position) {
|
||||||
/*ListData.Category data = getResult().categories.get(position);
|
MenuData.Meal meal = getMeal();
|
||||||
|
assert meal != null;
|
||||||
|
MenuData.Meal.Category data = meal.categories.get(position - getFirstElementPosition());
|
||||||
// Setup View
|
// Setup View
|
||||||
CategoryView category = (CategoryView) view;
|
CategoryView category = (CategoryView) view;
|
||||||
category.setup(data.isOpen, data.name, () -> {
|
category.setup(data.isOpen, data.name, () -> {
|
||||||
// Open/Close Category
|
// Open/Close Category
|
||||||
data.isOpen = !data.isOpen;
|
data.isOpen = !data.isOpen;
|
||||||
notifyItemChanged(getResult().categories.indexOf(data));
|
notifyItemChanged(meal.categories.indexOf(data) + getFirstElementPosition());
|
||||||
});
|
});
|
||||||
// Add Locations
|
// Add Locations
|
||||||
category.clearItems();
|
category.clearItems();
|
||||||
for (ListData.Category.Element location : data.locations) {
|
for (MenuData.Meal.Category.Element item : data.items) {
|
||||||
category.addItem(location.name, () -> {
|
category.addItem(item.name, () -> {
|
||||||
// Do Something!
|
// Do Something!
|
||||||
});
|
});
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getDataSize() {
|
protected int getDataSize() {
|
||||||
return 0;
|
MenuData.Meal meal = getMeal();
|
||||||
|
if (meal != null) {
|
||||||
|
return meal.categories.size();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected View createHeader(@NonNull ViewGroup parent) {
|
protected View createHeader(@NonNull ViewGroup parent) {
|
||||||
|
// Inflate Header XML
|
||||||
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
|
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
|
||||||
return layoutInflater.inflate(R.layout.menu_header, parent, false);
|
return layoutInflater.inflate(R.layout.menu_header, parent, false);
|
||||||
}
|
}
|
||||||
@ -67,16 +93,49 @@ class MenuAdapter extends TaskAdapter<MenuData> {
|
|||||||
@Override
|
@Override
|
||||||
protected void bindHeader(View view) {
|
protected void bindHeader(View view) {
|
||||||
// Set Date
|
// Set Date
|
||||||
|
CustomDropDownView dateField = view.findViewById(R.id.menu_date_field);
|
||||||
MaterialAutoCompleteTextView date = view.findViewById(R.id.menu_date);
|
MaterialAutoCompleteTextView date = view.findViewById(R.id.menu_date);
|
||||||
// Retrieve from Task as this must show even when result is not available.
|
// Retrieve from Task as this must show even when result is not available.
|
||||||
date.setText(DateUtil.toString(((MenuTask) getTask()).getDate()));
|
Date current = ((MenuTask) getTask()).getDate();
|
||||||
|
date.setText(DateUtil.toString(current));
|
||||||
|
// Handle Click
|
||||||
|
dateField.setup();
|
||||||
|
dateField.setOnDropDown(() -> {
|
||||||
|
// Open Date Picker
|
||||||
|
MenuDatePicker.show(current, ((MenuActivity) view.getContext()).getSupportFragmentManager());
|
||||||
|
});
|
||||||
|
|
||||||
// Set Meal
|
// Set Meal
|
||||||
boolean hasMeal = getResult() != null;
|
boolean hasMeal = getResult() != null;
|
||||||
TextInputLayout meal = view.findViewById(R.id.menu_meal_field);
|
TextInputLayout mealField = view.findViewById(R.id.menu_meal_field);
|
||||||
meal.setEnabled(hasMeal);
|
MaterialAutoCompleteTextView meal = view.findViewById(R.id.menu_meal);
|
||||||
if (hasMeal) {
|
if (hasMeal) {
|
||||||
|
// Enable/Disable Field
|
||||||
|
hasMeal = getResult().meals.size() > 0;
|
||||||
|
mealField.setEnabled(hasMeal);
|
||||||
|
if (hasMeal) {
|
||||||
|
// Set Dropdown Options
|
||||||
|
meal.setSimpleItems(getResult().meals.stream().map(x -> x.name).toArray(String[]::new));
|
||||||
|
// Set Selection
|
||||||
|
meal.setText(getResult().selectedMeal, false);
|
||||||
|
// Handle Meal Selection
|
||||||
|
meal.setOnItemClickListener((parent, view1, position, id) -> {
|
||||||
|
// Get New Meal
|
||||||
|
String newMeal = (String) parent.getAdapter().getItem(position);
|
||||||
|
// Update UI
|
||||||
|
int oldItemCount = getItemCount();
|
||||||
|
getResult().selectedMeal = newMeal;
|
||||||
|
reloadUI(oldItemCount);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Show N/A
|
||||||
|
meal.setText(meal.getResources().getString(R.string.not_available), false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Disable Field
|
||||||
|
mealField.setEnabled(false);
|
||||||
|
// Show No Text
|
||||||
|
meal.setText("", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,10 @@ class MenuData {
|
|||||||
public static class Meal {
|
public static class Meal {
|
||||||
public static class Category {
|
public static class Category {
|
||||||
public static class Element {
|
public static class Element {
|
||||||
public final String id;
|
|
||||||
public final String name;
|
public final String name;
|
||||||
public final String description;
|
public final String description;
|
||||||
|
|
||||||
public Element(String id, String name, String description) {
|
public Element(String name, String description) {
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
@ -20,7 +18,7 @@ class MenuData {
|
|||||||
|
|
||||||
public final String name;
|
public final String name;
|
||||||
public boolean isOpen = true;
|
public boolean isOpen = true;
|
||||||
public final List<Element> locations = new ArrayList<>();
|
public final List<Element> items = new ArrayList<>();
|
||||||
|
|
||||||
public Category(String name) {
|
public Category(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -38,5 +36,6 @@ class MenuData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final List<Meal> meals = new ArrayList<>();
|
public final List<Meal> meals = new ArrayList<>();
|
||||||
public String selectedMeal;
|
// This may be changed at runtime.
|
||||||
|
public String selectedMeal = null;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.thebrokenrail.mtudining.activity.menu;
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
|
import com.google.android.material.datepicker.MaterialDatePicker;
|
||||||
|
import com.thebrokenrail.mtudining.R;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date picker for menu selection.
|
||||||
|
*/
|
||||||
|
public class MenuDatePicker {
|
||||||
|
private final static String TAG = "menu_date_picker";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show date picker.
|
||||||
|
* @param current Currently selected date
|
||||||
|
* @param fragmentManager Support fragment manager
|
||||||
|
*/
|
||||||
|
public static void show(Date current, FragmentManager fragmentManager) {
|
||||||
|
// Get Date In UTC
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTime(current);
|
||||||
|
Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
|
copyDateFromCalender(calendar, utcCalendar);
|
||||||
|
// Build Picker
|
||||||
|
MaterialDatePicker<Long> datePicker = MaterialDatePicker.Builder.datePicker()
|
||||||
|
.setTitleText(R.string.select_date)
|
||||||
|
.setSelection(utcCalendar.getTimeInMillis())
|
||||||
|
.build();
|
||||||
|
// Show
|
||||||
|
datePicker.show(fragmentManager, TAG);
|
||||||
|
// Handle Selection
|
||||||
|
setupListeners(datePicker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup event listeners on existing date picker.
|
||||||
|
* @param datePicker The date picker
|
||||||
|
*/
|
||||||
|
private static void setupListeners(MaterialDatePicker<Long> datePicker) {
|
||||||
|
datePicker.addOnPositiveButtonClickListener(selection -> {
|
||||||
|
// Get Selection
|
||||||
|
if (selection != null) {
|
||||||
|
// Get New Date
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
|
Date selectedDate = new Date(selection);
|
||||||
|
utcCalendar.setTime(selectedDate);
|
||||||
|
copyDateFromCalender(utcCalendar, calendar);
|
||||||
|
Date newDate = calendar.getTime();
|
||||||
|
// Get Activity
|
||||||
|
MenuActivity activity = (MenuActivity) datePicker.requireActivity();
|
||||||
|
// Update Date
|
||||||
|
activity.updateDate(newDate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup event listeners on existing date picker.
|
||||||
|
* @param fragmentManager Support fragment manager
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public static void setupListeners(FragmentManager fragmentManager) {
|
||||||
|
// Get Picker
|
||||||
|
Fragment fragment = fragmentManager.findFragmentByTag(TAG);
|
||||||
|
if (fragment != null) {
|
||||||
|
MaterialDatePicker<Long> datePicker = (MaterialDatePicker<Long>) fragment;
|
||||||
|
setupListeners(datePicker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void copyDateFromCalender(Calendar src, Calendar dst) {
|
||||||
|
int year = src.get(Calendar.YEAR);
|
||||||
|
int month = src.get(Calendar.MONTH);
|
||||||
|
int day = src.get(Calendar.DAY_OF_MONTH);
|
||||||
|
dst.set(Calendar.YEAR, year);
|
||||||
|
dst.set(Calendar.MONTH, month);
|
||||||
|
dst.set(Calendar.DAY_OF_MONTH, day);
|
||||||
|
}
|
||||||
|
}
|
@ -2,11 +2,16 @@ package com.thebrokenrail.mtudining.activity.menu;
|
|||||||
|
|
||||||
import com.thebrokenrail.mtudining.activity.task.Task;
|
import com.thebrokenrail.mtudining.activity.task.Task;
|
||||||
import com.thebrokenrail.mtudining.api.Connection;
|
import com.thebrokenrail.mtudining.api.Connection;
|
||||||
|
import com.thebrokenrail.mtudining.api.method.PeriodDetail;
|
||||||
import com.thebrokenrail.mtudining.api.method.Periods;
|
import com.thebrokenrail.mtudining.api.method.Periods;
|
||||||
import com.thebrokenrail.mtudining.util.Constants;
|
import com.thebrokenrail.mtudining.util.Constants;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task for loading menu information.
|
||||||
|
*/
|
||||||
public class MenuTask extends Task<MenuData> {
|
public class MenuTask extends Task<MenuData> {
|
||||||
private final Connection connection;
|
private final Connection connection;
|
||||||
|
|
||||||
@ -29,6 +34,14 @@ public class MenuTask extends Task<MenuData> {
|
|||||||
this.date = date;
|
this.date = date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if task is setup.
|
||||||
|
* @return If the task is setup
|
||||||
|
*/
|
||||||
|
boolean isSetup() {
|
||||||
|
return locationId != null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get date.
|
* Get date.
|
||||||
* @return The date
|
* @return The date
|
||||||
@ -43,10 +56,61 @@ public class MenuTask extends Task<MenuData> {
|
|||||||
Periods periods = new Periods(Constants.PLATFORM, locationId, date);
|
Periods periods = new Periods(Constants.PLATFORM, locationId, date);
|
||||||
connection.send(periods, periodsResponse -> {
|
connection.send(periods, periodsResponse -> {
|
||||||
// Loaded Periods
|
// Loaded Periods
|
||||||
for (Periods.Response.Period period : periodsResponse.periods) {
|
|
||||||
System.out.println("Period: " + period.name);
|
// Sort Periods/Meals
|
||||||
|
periodsResponse.periods.sort(Comparator.comparingInt(a -> a.sort_order));
|
||||||
|
|
||||||
|
// Load Menu For Each Period
|
||||||
|
MenuData data = new MenuData();
|
||||||
|
int[] remaining = {periodsResponse.periods.size()};
|
||||||
|
if (remaining[0] > 0) {
|
||||||
|
// Start Loading Menus
|
||||||
|
for (Periods.Response.Period period : periodsResponse.periods) {
|
||||||
|
// Load Period Details
|
||||||
|
MenuData.Meal meal = new MenuData.Meal(period.id, period.name);
|
||||||
|
PeriodDetail periodDetail = new PeriodDetail(Constants.PLATFORM, locationId, date, period.id);
|
||||||
|
connection.send(periodDetail, periodDetailResponse -> {
|
||||||
|
// Loaded Period Details
|
||||||
|
|
||||||
|
// Sort Categories
|
||||||
|
periodDetailResponse.menu.periods.categories.sort(Comparator.comparingInt(a -> a.sort_order));
|
||||||
|
|
||||||
|
// Add Data
|
||||||
|
for (PeriodDetail.Response.Menu.PeriodData.MenuCategory category : periodDetailResponse.menu.periods.categories) {
|
||||||
|
MenuData.Meal.Category menuCategory = new MenuData.Meal.Category(category.name);
|
||||||
|
|
||||||
|
// Sort Items
|
||||||
|
category.items.sort(Comparator.comparingInt(a -> a.sort_order));
|
||||||
|
|
||||||
|
// Add Items To Category
|
||||||
|
for (PeriodDetail.Response.Menu.PeriodData.MenuCategory.MenuItem item : category.items) {
|
||||||
|
menuCategory.items.add(new MenuData.Meal.Category.Element(item.name, item.desc));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip Empty Category
|
||||||
|
if (menuCategory.items.size() > 0) {
|
||||||
|
meal.categories.add(menuCategory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check If All Data Has Been Loaded
|
||||||
|
remaining[0]--;
|
||||||
|
if (remaining[0] == 0) {
|
||||||
|
// All Data Loaded
|
||||||
|
done(id, data);
|
||||||
|
}
|
||||||
|
}, () -> {
|
||||||
|
// Error
|
||||||
|
done(id, null);
|
||||||
|
});
|
||||||
|
data.meals.add(meal);
|
||||||
|
}
|
||||||
|
// Set Selected Meal
|
||||||
|
data.selectedMeal = data.meals.get(0).name;
|
||||||
|
} else {
|
||||||
|
// No Periods To Load
|
||||||
|
done(id, data);
|
||||||
}
|
}
|
||||||
done(id, null);
|
|
||||||
}, () -> {
|
}, () -> {
|
||||||
// Error
|
// Error
|
||||||
done(id, null);
|
done(id, null);
|
||||||
|
@ -21,7 +21,7 @@ public abstract class Task<E> {
|
|||||||
/**
|
/**
|
||||||
* Last time when {@link #start()} was called.
|
* Last time when {@link #start()} was called.
|
||||||
*/
|
*/
|
||||||
private long lastStart;
|
private Long lastStart = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start task.
|
* Start task.
|
||||||
@ -67,6 +67,8 @@ public abstract class Task<E> {
|
|||||||
}
|
}
|
||||||
// Update Listeners
|
// Update Listeners
|
||||||
sendDataToListeners();
|
sendDataToListeners();
|
||||||
|
// Ignore Future Responses From This API Call
|
||||||
|
lastStart = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -198,12 +198,15 @@ public abstract class TaskAdapter<E> extends RecyclerView.Adapter<RecyclerView.V
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reload UI.
|
* Reload UI.
|
||||||
|
* @param oldItemCount Amount of visible items before UI change
|
||||||
*/
|
*/
|
||||||
private void reloadUI(int oldItemCount) {
|
protected void reloadUI(int oldItemCount) {
|
||||||
|
// Reload Header Without Animation
|
||||||
|
notifyItemChanged(0, new Object());
|
||||||
// Remove Existing Items
|
// Remove Existing Items
|
||||||
notifyItemRangeRemoved(0, oldItemCount);
|
notifyItemRangeRemoved(1, oldItemCount - 1);
|
||||||
// Add Items
|
// Add Items
|
||||||
notifyItemRangeInserted(0, getItemCount());
|
notifyItemRangeInserted(1, getItemCount() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.thebrokenrail.mtudining.api.method;
|
||||||
|
|
||||||
|
import com.thebrokenrail.mtudining.api.Method;
|
||||||
|
import com.thebrokenrail.mtudining.util.DateUtil;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PeriodDetail implements Method<PeriodDetail.Response> {
|
||||||
|
private final int platform;
|
||||||
|
private final String locationId;
|
||||||
|
private final String date;
|
||||||
|
private final String period;
|
||||||
|
|
||||||
|
public PeriodDetail(int platform, String locationId, Date date, String period) {
|
||||||
|
this.platform = platform;
|
||||||
|
this.locationId = locationId;
|
||||||
|
this.date = DateUtil.toString(date);
|
||||||
|
this.period = period;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPath() {
|
||||||
|
return "/location/" + locationId + "/periods/" + period + "?platform=" + platform + "&date=" + date;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Response> getResponseClass() {
|
||||||
|
return Response.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Response {
|
||||||
|
public static class Menu {
|
||||||
|
public static class PeriodData {
|
||||||
|
public static class MenuCategory {
|
||||||
|
public static class MenuItem {
|
||||||
|
public String name;
|
||||||
|
public String desc;
|
||||||
|
public int sort_order;
|
||||||
|
}
|
||||||
|
public String name;
|
||||||
|
public List<MenuItem> items;
|
||||||
|
public int sort_order;
|
||||||
|
}
|
||||||
|
public List<MenuCategory> categories;
|
||||||
|
}
|
||||||
|
public PeriodData periods;
|
||||||
|
}
|
||||||
|
public Menu menu;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.thebrokenrail.mtudining.widget;
|
||||||
|
|
||||||
|
import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_CLICKED;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link TextInputLayout} with support for custom dropdown handling.
|
||||||
|
*/
|
||||||
|
public class CustomDropDownView extends TextInputLayout {
|
||||||
|
public CustomDropDownView(@NonNull Context context, @Nullable AttributeSet attributeSet) {
|
||||||
|
super(context, attributeSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current handler.
|
||||||
|
*/
|
||||||
|
private Runnable onDropDown = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set new dropdown handler.
|
||||||
|
* @param onDropDown New handler
|
||||||
|
*/
|
||||||
|
public void setOnDropDown(Runnable onDropDown) {
|
||||||
|
this.onDropDown = onDropDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
|
||||||
|
super.onPopulateAccessibilityEvent(event);
|
||||||
|
// Run Callback
|
||||||
|
// https://github.com/material-components/material-components-android/blob/dd8f6bebdd45c2875fab6574376a604a7d40061a/lib/java/com/google/android/material/textfield/DropdownMenuEndIconDelegate.java#L249-L252
|
||||||
|
if (event.getEventType() == TYPE_VIEW_CLICKED && onDropDown != null) {
|
||||||
|
onDropDown.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup touch handler.
|
||||||
|
*/
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
public void setup() {
|
||||||
|
EditText editText = getEditText();
|
||||||
|
if (editText != null) {
|
||||||
|
// https://github.com/material-components/material-components-android/blob/dd8f6bebdd45c2875fab6574376a604a7d40061a/lib/java/com/google/android/material/textfield/DropdownMenuEndIconDelegate.java#L285-L291
|
||||||
|
editText.setOnTouchListener((v, event) -> {
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_UP && onDropDown != null) {
|
||||||
|
onDropDown.run();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<!-- Date -->
|
<!-- Date -->
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.thebrokenrail.mtudining.widget.CustomDropDownView
|
||||||
android:id="@+id/menu_date_field"
|
android:id="@+id/menu_date_field"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -21,7 +21,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="none" />
|
android:inputType="none" />
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.thebrokenrail.mtudining.widget.CustomDropDownView>
|
||||||
|
|
||||||
<!-- Meal -->
|
<!-- Meal -->
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
@ -5,4 +5,6 @@
|
|||||||
<string name="load_error">Unable to load data!</string>
|
<string name="load_error">Unable to load data!</string>
|
||||||
<string name="date">Date</string>
|
<string name="date">Date</string>
|
||||||
<string name="meal">Meal</string>
|
<string name="meal">Meal</string>
|
||||||
|
<string name="select_date">Select Date</string>
|
||||||
|
<string name="not_available">N/A</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user