More Improvements!
This commit is contained in:
parent
2da59312c5
commit
64f9fe7f63
@ -32,7 +32,6 @@ android {
|
||||
dependencies {
|
||||
implementation("androidx.appcompat:appcompat:1.6.1")
|
||||
implementation("com.google.android.material:material:1.11.0")
|
||||
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
||||
// OkHttp (For HTTP)
|
||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||
// Moshi (For JSON)
|
||||
|
@ -36,6 +36,7 @@ public class ListActivity extends AppCompatActivity {
|
||||
|
||||
// Setup RecyclerView
|
||||
adapter = new ListAdapter(viewModel.task);
|
||||
viewModel.task.sendDataToListeners();
|
||||
RecyclerView recyclerView = findViewById(R.id.recycler_view);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
@ -61,7 +61,9 @@ public class ItemDialog {
|
||||
message.append("\n\n");
|
||||
}
|
||||
message.append(context.getString(R.string.portion), new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
message.append(item.portion);
|
||||
if (item.portion != null) {
|
||||
message.append(item.portion);
|
||||
}
|
||||
message.append('\n');
|
||||
message.append(context.getString(R.string.ingredients), new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
if (item.ingredients != null) {
|
||||
|
@ -61,15 +61,14 @@ public class MenuActivity extends AppCompatActivity {
|
||||
String name = getIntent().getStringExtra(NAME_EXTRA);
|
||||
toolbar.setTitle(name);
|
||||
String id = getIntent().getStringExtra(ID_EXTRA);
|
||||
if (!viewModel.task.isSetup()) {
|
||||
viewModel.task.setup(id, new Date());
|
||||
}
|
||||
viewModel.task.setup(id);
|
||||
latitude = getIntent().getDoubleExtra(LATITUDE_EXTRA, 0);
|
||||
longitude = getIntent().getDoubleExtra(LONGITUDE_EXTRA, 0);
|
||||
street = getIntent().getStringExtra(STREET_EXTRA);
|
||||
|
||||
// Setup RecyclerView
|
||||
adapter = new MenuAdapter(viewModel.task);
|
||||
adapter = new MenuAdapter(viewModel.task, viewModel.state);
|
||||
viewModel.task.sendDataToListeners();
|
||||
RecyclerView recyclerView = findViewById(R.id.recycler_view);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setAdapter(adapter);
|
||||
@ -113,7 +112,7 @@ public class MenuActivity extends AppCompatActivity {
|
||||
* @param newDate New date
|
||||
*/
|
||||
public void updateDate(Date newDate) {
|
||||
viewModel.task.setup(null, newDate);
|
||||
viewModel.state.setDate(newDate);
|
||||
viewModel.task.start();
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,14 @@ import java.util.Date;
|
||||
* Adapter for listing dining halls.
|
||||
*/
|
||||
class MenuAdapter extends TaskAdapter<MenuData> {
|
||||
MenuAdapter(Task<MenuData> task) {
|
||||
/**
|
||||
* Current state.
|
||||
*/
|
||||
private final MenuState state;
|
||||
|
||||
MenuAdapter(Task<MenuData> task, MenuState state) {
|
||||
super(task);
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -43,8 +49,9 @@ class MenuAdapter extends TaskAdapter<MenuData> {
|
||||
*/
|
||||
private MenuData.Meal getMeal() {
|
||||
if (getResult() != null) {
|
||||
String selectedMeal = state.getSelectedMeal();
|
||||
for (MenuData.Meal meal : getResult().meals) {
|
||||
if (meal.name.equals(getResult().selectedMeal)) {
|
||||
if (meal.name.equals(selectedMeal)) {
|
||||
// Found Meal
|
||||
return meal;
|
||||
}
|
||||
@ -93,8 +100,7 @@ class MenuAdapter extends TaskAdapter<MenuData> {
|
||||
// Set Date
|
||||
CustomDropDownView dateField = view.findViewById(R.id.menu_date_field);
|
||||
MaterialAutoCompleteTextView date = view.findViewById(R.id.menu_date);
|
||||
// Retrieve from Task as this must show even when result is not available.
|
||||
Date current = ((MenuTask) getTask()).getDate();
|
||||
Date current = state.getDate();
|
||||
date.setText(DateUtil.toString(current));
|
||||
// Handle Click
|
||||
dateField.setup();
|
||||
@ -104,26 +110,28 @@ class MenuAdapter extends TaskAdapter<MenuData> {
|
||||
});
|
||||
|
||||
// Set Meal
|
||||
boolean hasMeal = getResult() != null;
|
||||
boolean isLoaded = getResult() != null;
|
||||
TextInputLayout mealField = view.findViewById(R.id.menu_meal_field);
|
||||
MaterialAutoCompleteTextView meal = view.findViewById(R.id.menu_meal);
|
||||
if (hasMeal) {
|
||||
if (isLoaded) {
|
||||
// Enable/Disable Field
|
||||
hasMeal = getResult().meals.size() > 0;
|
||||
mealField.setEnabled(hasMeal);
|
||||
if (hasMeal) {
|
||||
isLoaded = getResult().meals.size() > 0;
|
||||
mealField.setEnabled(isLoaded);
|
||||
if (isLoaded) {
|
||||
// Set Dropdown Options
|
||||
meal.setSimpleItems(getResult().meals.stream().map(x -> x.name).toArray(String[]::new));
|
||||
// Set Selection
|
||||
meal.setText(getResult().selectedMeal, false);
|
||||
meal.setText(state.getSelectedMeal(), 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);
|
||||
if (!newMeal.equals(state.getSelectedMeal())) {
|
||||
int oldItemCount = getItemCount();
|
||||
state.setSelectedMeal(newMeal);
|
||||
reloadUI(oldItemCount);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Show N/A
|
||||
|
@ -17,8 +17,5 @@ class MenuData {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public final List<Meal> meals = new ArrayList<>();
|
||||
// This may be changed at runtime.
|
||||
public String selectedMeal = null;
|
||||
}
|
||||
|
@ -0,0 +1,61 @@
|
||||
package com.thebrokenrail.mtudining.activity.menu;
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Current state of menu screen.
|
||||
*/
|
||||
public class MenuState {
|
||||
private static final String DATE_KEY = "date";
|
||||
private static final String SELECTED_MEAL_KEY = "selected_meal";
|
||||
|
||||
/**
|
||||
* Data that should survive process-death.
|
||||
*/
|
||||
private final SavedStateHandle savedStateHandle;
|
||||
|
||||
public MenuState(SavedStateHandle savedStateHandle) {
|
||||
this.savedStateHandle = savedStateHandle;
|
||||
if (!savedStateHandle.contains(DATE_KEY)) {
|
||||
setDate(new Date());
|
||||
}
|
||||
if (!savedStateHandle.contains(SELECTED_MEAL_KEY)) {
|
||||
setSelectedMeal("");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get currently selected date.
|
||||
* @return The data
|
||||
*/
|
||||
@SuppressWarnings({"DataFlowIssue"})
|
||||
public Date getDate() {
|
||||
return new Date((long) savedStateHandle.get(DATE_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set selected date.
|
||||
* @param date The new date
|
||||
*/
|
||||
public void setDate(Date date) {
|
||||
savedStateHandle.set(DATE_KEY, date.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get currently selected meal.
|
||||
* @return The meal
|
||||
*/
|
||||
public String getSelectedMeal() {
|
||||
return savedStateHandle.get(SELECTED_MEAL_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set selected meal.
|
||||
* @param selectedMeal The new meal
|
||||
*/
|
||||
public void setSelectedMeal(String selectedMeal) {
|
||||
savedStateHandle.set(SELECTED_MEAL_KEY, selectedMeal);
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@ import com.thebrokenrail.mtudining.util.Category;
|
||||
import com.thebrokenrail.mtudining.util.Constants;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Task for loading menu information.
|
||||
@ -17,44 +16,25 @@ public class MenuTask extends Task<MenuData> {
|
||||
private final Connection connection;
|
||||
|
||||
private String locationId;
|
||||
private Date date;
|
||||
private final MenuState state;
|
||||
|
||||
public MenuTask(Connection connection) {
|
||||
public MenuTask(Connection connection, MenuState state) {
|
||||
this.connection = connection;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup task.
|
||||
* @param locationId Location ID (or null to use existing)
|
||||
* @param date Date
|
||||
* @param locationId Location ID
|
||||
*/
|
||||
void setup(String locationId, Date date) {
|
||||
if (locationId != null) {
|
||||
this.locationId = locationId;
|
||||
}
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if task is setup.
|
||||
* @return If the task is setup
|
||||
*/
|
||||
boolean isSetup() {
|
||||
return locationId != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get date.
|
||||
* @return The date
|
||||
*/
|
||||
public Date getDate() {
|
||||
return date;
|
||||
void setup(String locationId) {
|
||||
this.locationId = locationId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startImpl(long id) {
|
||||
// Get Periods
|
||||
Periods periods = new Periods(Constants.PLATFORM, locationId, date);
|
||||
Periods periods = new Periods(Constants.PLATFORM, locationId, state.getDate());
|
||||
connection.send(periods, periodsResponse -> {
|
||||
// Loaded Periods
|
||||
|
||||
@ -69,7 +49,7 @@ public class MenuTask extends Task<MenuData> {
|
||||
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);
|
||||
PeriodDetail periodDetail = new PeriodDetail(Constants.PLATFORM, locationId, state.getDate(), period.id);
|
||||
connection.send(periodDetail, periodDetailResponse -> {
|
||||
// Loaded Period Details
|
||||
|
||||
@ -104,8 +84,6 @@ public class MenuTask extends Task<MenuData> {
|
||||
});
|
||||
data.meals.add(meal);
|
||||
}
|
||||
// Set Selected Meal
|
||||
data.selectedMeal = data.meals.get(0).name;
|
||||
} else {
|
||||
// No Periods To Load
|
||||
done(id, data);
|
||||
@ -115,4 +93,29 @@ public class MenuTask extends Task<MenuData> {
|
||||
done(id, null);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done(long id, MenuData obj) {
|
||||
// Update Selected Meal If Needed
|
||||
if (obj != null && obj.meals.size() > 0) {
|
||||
boolean currentSelectedMealIsValid = false;
|
||||
String selectedMeal = state.getSelectedMeal();
|
||||
if (selectedMeal != null) {
|
||||
// Check If Current Selection Is Valid
|
||||
for (MenuData.Meal meal : obj.meals) {
|
||||
if (selectedMeal.equals(meal.name)) {
|
||||
currentSelectedMealIsValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!currentSelectedMealIsValid) {
|
||||
// Current Selection Is Invalid, Change It
|
||||
state.setSelectedMeal(obj.meals.get(0).name);
|
||||
}
|
||||
}
|
||||
|
||||
// Call Parent
|
||||
super.done(id, obj);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.thebrokenrail.mtudining.activity.menu;
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import com.thebrokenrail.mtudining.activity.task.Task;
|
||||
import com.thebrokenrail.mtudining.api.Connection;
|
||||
|
||||
/**
|
||||
@ -10,5 +10,11 @@ import com.thebrokenrail.mtudining.api.Connection;
|
||||
*/
|
||||
public class MenuViewModel extends ViewModel {
|
||||
private final Connection connection = new Connection();
|
||||
public final MenuTask task = new MenuTask(connection);
|
||||
public final MenuState state;
|
||||
public final MenuTask task;
|
||||
|
||||
public MenuViewModel(SavedStateHandle savedStateHandle) {
|
||||
state = new MenuState(savedStateHandle);
|
||||
task = new MenuTask(connection, state);
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ public abstract class Task<E> {
|
||||
public void start() {
|
||||
lastStart = System.currentTimeMillis();
|
||||
status = Status.IN_PROGRESS;
|
||||
result = null;
|
||||
startImpl(lastStart);
|
||||
// Update Listeners
|
||||
sendDataToListeners();
|
||||
@ -95,25 +96,15 @@ public abstract class Task<E> {
|
||||
public void addListener(Listener<E> listener) {
|
||||
if (!listeners.contains(listener)) {
|
||||
listeners.add(listener);
|
||||
// Send Data
|
||||
sendDataToListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send data to specific listener.
|
||||
* @param listener The listener
|
||||
*/
|
||||
private void sendDataToListener(Listener<E> listener) {
|
||||
listener.update(status, status == Status.DONE ? result : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send data to all listeners.
|
||||
*/
|
||||
private void sendDataToListeners() {
|
||||
public void sendDataToListeners() {
|
||||
for (Listener<E> listener : listeners) {
|
||||
sendDataToListener(listener);
|
||||
listener.update(status, status == Status.DONE ? result : null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,12 +208,4 @@ public abstract class TaskAdapter<E> extends RecyclerView.Adapter<RecyclerView.V
|
||||
// Add Items
|
||||
notifyItemRangeInserted(1, getItemCount() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get task.
|
||||
* @return The task
|
||||
*/
|
||||
public Task<E> getTask() {
|
||||
return task;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user