Improve Item Dialogs!

This commit is contained in:
TheBrokenRail 2024-02-18 02:32:58 -05:00
parent 64f9fe7f63
commit 3895b1c477
8 changed files with 137 additions and 15 deletions

View File

@ -19,6 +19,8 @@ class ListTask extends Task<ListData> {
@Override @Override
protected void startImpl(long id) { protected void startImpl(long id) {
// Cancel Existing HTTP Calls
connection.cancelAll();
// Load Site Info // Load Site Info
Info info = new Info(); Info info = new Info();
connection.send(info, infoResponse -> { connection.send(info, infoResponse -> {

View File

@ -10,16 +10,23 @@ import android.text.style.StyleSpan;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.thebrokenrail.mtudining.R; import com.thebrokenrail.mtudining.R;
import com.thebrokenrail.mtudining.api.method.PeriodDetail; import com.thebrokenrail.mtudining.api.method.PeriodDetail;
import java.util.ArrayList;
import java.util.List;
/** /**
* Dialog for a food item. * Dialog for a food item.
*/ */
public class ItemDialog { public class ItemDialog {
private static final String ALLERGEN_FILTER = "allergen";
private static final String LABEL_FILTER = "label";
/** /**
* Fragment for dialog. * Fragment for dialog.
*/ */
@ -57,30 +64,98 @@ public class ItemDialog {
public static void show(Context context, PeriodDetail.Response.Menu.PeriodData.MenuCategory.MenuItem item) { public static void show(Context context, PeriodDetail.Response.Menu.PeriodData.MenuCategory.MenuItem item) {
// Build Message // Build Message
SpannableStringBuilder message = new SpannableStringBuilder(item.desc != null ? item.desc.trim() : ""); SpannableStringBuilder message = new SpannableStringBuilder(item.desc != null ? item.desc.trim() : "");
if (message.length() > 0) { writeNewline(message, 2);
message.append("\n\n"); for (String filterType : new String[]{LABEL_FILTER, ALLERGEN_FILTER}) {
List<String> filters = getFilters(item, filterType);
if (filters.size() > 0) {
writeNewline(message, 1);
@StringRes int filterName = filterType.equals(LABEL_FILTER) ? R.string.labels : R.string.allergens;
message.append(context.getString(filterName), new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
for (String filter : filters) {
writeBullet(message, null, filter);
} }
message.append(context.getString(R.string.portion), new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); }
}
writeNewline(message, 2);
if (item.portion != null) { if (item.portion != null) {
message.append(context.getString(R.string.portion), new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
message.append(item.portion); message.append(item.portion);
} }
message.append('\n'); writeNewline(message, 1);
message.append(context.getString(R.string.ingredients), new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (item.ingredients != null) { if (item.ingredients != null) {
message.append(context.getString(R.string.ingredients), new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
message.append(item.ingredients); message.append(item.ingredients);
} }
message.append('\n'); writeNewline(message, 2);
if (item.nutrients.size() > 0) {
message.append(context.getString(R.string.nutrients), new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); message.append(context.getString(R.string.nutrients), new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
for (PeriodDetail.Response.Menu.PeriodData.MenuCategory.MenuItem.Nutrient nutrient : item.nutrients) { for (PeriodDetail.Response.Menu.PeriodData.MenuCategory.MenuItem.Nutrient nutrient : item.nutrients) {
message.append('\n'); writeBullet(message, nutrient.name, nutrient.value);
message.append("" + nutrient.name + ": ", new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (nutrient.value != null) {
message.append(nutrient.value);
} }
} }
// Remove Newlines From End
while (message.length() > 0 && message.charAt(message.length() - 1) == '\n') {
message.delete(message.length() - 1, message.length());
}
// Show // Show
Fragment fragment = new Fragment(item.name, message); Fragment fragment = new Fragment(item.name, message);
fragment.show(((MenuActivity) context).getSupportFragmentManager(), "item_" + item.name.hashCode()); fragment.show(((MenuActivity) context).getSupportFragmentManager(), "item_" + item.name.hashCode());
} }
/**
* Get filters of a specific type in food item.
* @param item The item
* @param type The filter type
* @return List of filters
*/
private static List<String> getFilters(PeriodDetail.Response.Menu.PeriodData.MenuCategory.MenuItem item, String type) {
List<String> out = new ArrayList<>();
for (PeriodDetail.Response.Menu.PeriodData.MenuCategory.MenuItem.Filter filter : item.filters) {
if (filter.type.equals(type)) {
out.add(filter.name);
}
}
return out;
}
/**
* Write bullet point to string.
* @param message The string to modify
* @param name The first part
* @param value The second part
*/
private static void writeBullet(SpannableStringBuilder message, String name, String value) {
writeNewline(message, 1);
message.append("", new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (name != null) {
message.append(name + ": ", new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
message.append(value);
}
/**
* Write newline to string.
* @param message The string to modify
* @param count The amount of newlines to write
*/
private static void writeNewline(SpannableStringBuilder message, int count) {
if (message.length() > 0) {
int existingCount = 0;
for (int i = message.length() - 1; i >= 0; i--) {
if (message.charAt(i) == '\n') {
existingCount++;
} else {
break;
}
}
count -= existingCount;
if (count > 0) {
for (int i = 0; i < count; i++) {
message.append('\n');
}
}
}
}
} }

View File

@ -16,6 +16,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.appbar.MaterialToolbar;
import com.thebrokenrail.mtudining.R; import com.thebrokenrail.mtudining.R;
import com.thebrokenrail.mtudining.util.DateUtil;
import com.thebrokenrail.mtudining.util.EdgeToEdgeUtil; import com.thebrokenrail.mtudining.util.EdgeToEdgeUtil;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@ -112,9 +113,11 @@ public class MenuActivity extends AppCompatActivity {
* @param newDate New date * @param newDate New date
*/ */
public void updateDate(Date newDate) { public void updateDate(Date newDate) {
if (!DateUtil.toString(newDate).equals(DateUtil.toString(viewModel.state.getDate()))) {
viewModel.state.setDate(newDate); viewModel.state.setDate(newDate);
viewModel.task.start(); viewModel.task.start();
} }
}
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {

View File

@ -33,6 +33,8 @@ public class MenuTask extends Task<MenuData> {
@Override @Override
protected void startImpl(long id) { protected void startImpl(long id) {
// Cancel Existing HTTP Calls
connection.cancelAll();
// Get Periods // Get Periods
Periods periods = new Periods(Constants.PLATFORM, locationId, state.getDate()); Periods periods = new Periods(Constants.PLATFORM, locationId, state.getDate());
connection.send(periods, periodsResponse -> { connection.send(periods, periodsResponse -> {

View File

@ -34,6 +34,7 @@ public abstract class Task<E> {
// Update Listeners // Update Listeners
sendDataToListeners(); sendDataToListeners();
} }
/** /**
* Implementation of {@link #start()}. * Implementation of {@link #start()}.
* @param id Unique id for each call of {@link #start()} * @param id Unique id for each call of {@link #start()}

View File

@ -10,6 +10,8 @@ import com.squareup.moshi.Moshi;
import com.thebrokenrail.mtudining.util.Constants; import com.thebrokenrail.mtudining.util.Constants;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -39,6 +41,11 @@ public class Connection {
*/ */
private final Handler mainThread = new Handler(Looper.getMainLooper()); private final Handler mainThread = new Handler(Looper.getMainLooper());
/**
* List of current HTTP calls.
*/
private final List<Call> calls = new ArrayList<>();
/** /**
* Send API method. * Send API method.
* @param method API method * @param method API method
@ -56,7 +63,11 @@ public class Connection {
.build(); .build();
// Call // Call
client.newCall(request).enqueue(new Callback() { Call call = client.newCall(request);
synchronized (calls) {
calls.add(call);
}
call.enqueue(new Callback() {
private void error(Exception e) { private void error(Exception e) {
// Print Error // Print Error
e.printStackTrace(); e.printStackTrace();
@ -66,12 +77,20 @@ public class Connection {
@Override @Override
public void onFailure(@NonNull Call call, @NonNull IOException e) { public void onFailure(@NonNull Call call, @NonNull IOException e) {
synchronized (calls) {
calls.remove(call);
}
// Log Error
error(e); error(e);
} }
@Override @Override
public void onResponse(@NonNull Call call, @NonNull Response response) { public void onResponse(@NonNull Call call, @NonNull Response response) {
synchronized (calls) {
calls.remove(call);
}
try { try {
// Read Response
try (ResponseBody responseBody = response.body()) { try (ResponseBody responseBody = response.body()) {
// Check Response // Check Response
if (!response.isSuccessful()) { if (!response.isSuccessful()) {
@ -96,4 +115,16 @@ public class Connection {
} }
}); });
} }
/**
* Cancel all current calls.
*/
public void cancelAll() {
synchronized (calls) {
for (Call call : calls) {
call.cancel();
}
calls.clear();
}
}
} }

View File

@ -40,11 +40,17 @@ public class PeriodDetail implements Method<PeriodDetail.Response> {
public String value; public String value;
} }
public static class Filter {
public String name;
public String type;
}
public String name; public String name;
public String desc; public String desc;
public String ingredients; public String ingredients;
public String portion; public String portion;
public List<Nutrient> nutrients; public List<Nutrient> nutrients;
public List<Filter> filters;
public int sort_order; public int sort_order;
@Override @Override

View File

@ -12,4 +12,6 @@
<string name="portion">Portion:\u0020</string> <string name="portion">Portion:\u0020</string>
<string name="nutrients">Nutrients:</string> <string name="nutrients">Nutrients:</string>
<string name="open_map">Open Map</string> <string name="open_map">Open Map</string>
<string name="labels">Labels:</string>
<string name="allergens">Allergens:</string>
</resources> </resources>