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
protected void startImpl(long id) {
// Cancel Existing HTTP Calls
connection.cancelAll();
// Load Site Info
Info info = new Info();
connection.send(info, infoResponse -> {

View File

@ -10,16 +10,23 @@ import android.text.style.StyleSpan;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.DialogFragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.thebrokenrail.mtudining.R;
import com.thebrokenrail.mtudining.api.method.PeriodDetail;
import java.util.ArrayList;
import java.util.List;
/**
* Dialog for a food item.
*/
public class ItemDialog {
private static final String ALLERGEN_FILTER = "allergen";
private static final String LABEL_FILTER = "label";
/**
* Fragment for dialog.
*/
@ -57,30 +64,98 @@ public class ItemDialog {
public static void show(Context context, PeriodDetail.Response.Menu.PeriodData.MenuCategory.MenuItem item) {
// Build Message
SpannableStringBuilder message = new SpannableStringBuilder(item.desc != null ? item.desc.trim() : "");
if (message.length() > 0) {
message.append("\n\n");
writeNewline(message, 2);
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) {
message.append(context.getString(R.string.portion), new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
message.append(item.portion);
}
message.append('\n');
message.append(context.getString(R.string.ingredients), new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
writeNewline(message, 1);
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('\n');
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) {
message.append('\n');
message.append("" + nutrient.name + ": ", new StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (nutrient.value != null) {
message.append(nutrient.value);
writeNewline(message, 2);
if (item.nutrients.size() > 0) {
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) {
writeBullet(message, nutrient.name, nutrient.value);
}
}
// Remove Newlines From End
while (message.length() > 0 && message.charAt(message.length() - 1) == '\n') {
message.delete(message.length() - 1, message.length());
}
// Show
Fragment fragment = new Fragment(item.name, message);
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.thebrokenrail.mtudining.R;
import com.thebrokenrail.mtudining.util.DateUtil;
import com.thebrokenrail.mtudining.util.EdgeToEdgeUtil;
import java.io.UnsupportedEncodingException;
@ -112,8 +113,10 @@ public class MenuActivity extends AppCompatActivity {
* @param newDate New date
*/
public void updateDate(Date newDate) {
viewModel.state.setDate(newDate);
viewModel.task.start();
if (!DateUtil.toString(newDate).equals(DateUtil.toString(viewModel.state.getDate()))) {
viewModel.state.setDate(newDate);
viewModel.task.start();
}
}
@Override

View File

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

View File

@ -34,6 +34,7 @@ public abstract class Task<E> {
// Update Listeners
sendDataToListeners();
}
/**
* Implementation 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 java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@ -39,6 +41,11 @@ public class Connection {
*/
private final Handler mainThread = new Handler(Looper.getMainLooper());
/**
* List of current HTTP calls.
*/
private final List<Call> calls = new ArrayList<>();
/**
* Send API method.
* @param method API method
@ -56,7 +63,11 @@ public class Connection {
.build();
// 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) {
// Print Error
e.printStackTrace();
@ -66,12 +77,20 @@ public class Connection {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
synchronized (calls) {
calls.remove(call);
}
// Log Error
error(e);
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
synchronized (calls) {
calls.remove(call);
}
try {
// Read Response
try (ResponseBody responseBody = response.body()) {
// Check Response
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 static class Filter {
public String name;
public String type;
}
public String name;
public String desc;
public String ingredients;
public String portion;
public List<Nutrient> nutrients;
public List<Filter> filters;
public int sort_order;
@Override

View File

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