Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve resto menu display #883

Merged
merged 8 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.*;
import androidx.annotation.DrawableRes;
import androidx.appcompat.content.res.AppCompatResources;

Expand All @@ -41,6 +39,8 @@
import be.ugent.zeus.hydra.resto.RestoMenu;
import com.google.android.material.textview.MaterialTextView;

import static be.ugent.zeus.hydra.common.utils.ViewUtils.convertDpToPixelInt;

/**
* Helper class to display meals.
* <p>
Expand Down Expand Up @@ -76,7 +76,8 @@ private static ImageView makeImageView(Context context, @DrawableRes int id) {
ImageView imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setImageDrawable(AppCompatResources.getDrawable(context, id));
TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.MATCH_PARENT);
var size = convertDpToPixelInt(16, context);
TableRow.LayoutParams params = new TableRow.LayoutParams(size, size);
imageView.setLayoutParams(params);
return imageView;
}
Expand Down Expand Up @@ -104,27 +105,8 @@ public static int getDrawable(RestoMeal meal) {
* @param parent The view to which the child views will be added. This will be done by calling {@link
* ViewGroup#addView(View)}. This is also the view to get a context from.
*/
void addVegetableViews(ViewGroup parent) {

final Context context = parent.getContext();
final int rowPadding = ViewUtils.convertDpToPixelInt(ROW_PADDING_DP, context);

for (String vegetable : menu.vegetables()) {

TableRow tr = new TableRow(context);
TableRow.LayoutParams lp = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT);
tr.setLayoutParams(lp);
tr.setPadding(0, rowPadding, 0, rowPadding);

ImageView imageView = makeImageView(context, R.drawable.resto_vegetables);

TextView tvCenter = makeCenterTextView(context, vegetable, lp);

tr.addView(imageView);
tr.addView(tvCenter);

parent.addView(tr);
}
void addVegetableViews(ViewGroup parent, boolean showAllergens) {
addMealViews(parent, menu.vegetables(), showAllergens);
}

/**
Expand All @@ -133,8 +115,8 @@ void addVegetableViews(ViewGroup parent) {
* @param parent The view to which the child views will be added. This will be done by calling {@link
* ViewGroup#addView(View)}. This is also the view to get a context from.
*/
void addSoupViews(ViewGroup parent) {
addMealViews(parent, menu.soups(), false);
void addSoupViews(ViewGroup parent, boolean showAllergens) {
addMealViews(parent, menu.soups(), showAllergens);
}

/**
Expand Down Expand Up @@ -190,7 +172,7 @@ boolean hasColdDishes() {
private TextView makeCenterTextView(Context context, String text, TableRow.LayoutParams lp) {
TextView tvCenter = new MaterialTextView(context, null, normalStyle);
tvCenter.setTextIsSelectable(selectable);
tvCenter.setPadding(ViewUtils.convertDpToPixelInt(16, context), 0, 0, 0);
tvCenter.setPadding(convertDpToPixelInt(16, context), 0, 0, 0);
tvCenter.setLayoutParams(lp);
tvCenter.setText(text);
return tvCenter;
Expand All @@ -204,7 +186,7 @@ private TextView makeCenterTextView(Context context, String text, TableRow.Layou
*/
private void addMealViews(ViewGroup parent, List<RestoMeal> meals, boolean showAllergens) {
final Context context = parent.getContext();
final int rowPadding = ViewUtils.convertDpToPixelInt(ROW_PADDING_DP, context);
final int rowPadding = convertDpToPixelInt(ROW_PADDING_DP, context);

TableRow.LayoutParams lp = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT);

Expand All @@ -216,17 +198,22 @@ private void addMealViews(ViewGroup parent, List<RestoMeal> meals, boolean showA
//Set the correct image.
@DrawableRes final int id = getDrawable(meal);

ImageView imageView = makeImageView(context, id);
String name = meal.name();
TextView tvCenter = makeCenterTextView(context, name, lp);
TextView tvRight = new MaterialTextView(context, null, normalStyle);
tvRight.setLayoutParams(lp);
tvRight.setText(meal.price());
tvRight.setGravity(Gravity.END);

tr.addView(imageView);
tr.addView(tvCenter);
tr.addView(tvRight);
tr.addView(makeImageView(context, id));
var center = makeCenterTextView(context, meal.name(), lp);
tr.addView(center);

if (meal.price() != null) {
TextView tvRight = new MaterialTextView(context, null, normalStyle);
tvRight.setLayoutParams(lp);
tvRight.setText(meal.price());
tvRight.setGravity(Gravity.END);
tr.addView(tvRight);
} else {
// Allow the center to span more columns.
TableRow.LayoutParams tlp = (TableRow.LayoutParams) center.getLayoutParams();
tlp.span = 2;
center.setLayoutParams(tlp);
}

parent.addView(tr);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,19 +218,21 @@ private void populate() {
if (showTitles) {
createTitle(getContext().getString(R.string.resto_menu_soup));
}
menu.addSoupViews(this);
menu.addSoupViews(this, showAllergens);
}

if (isSetIn(displayedKinds, DisplayKind.VEGETABLES) && menu.hasVegetables()) {
if (showTitles) {
createTitle(getContext().getString(R.string.resto_menu_vegetables));
}
menu.addVegetableViews(this);
menu.addVegetableViews(this, showAllergens);
}
}

/**
* Flags to indicate what should be displayed by the menu.
* <p>
* Keep in sync with the showKind XML attribute.
*/
@IntDef(flag = true, value = {DisplayKind.HOT, DisplayKind.COLD, DisplayKind.SOUP, DisplayKind.VEGETABLES, DisplayKind.ALL})
@Retention(RetentionPolicy.SOURCE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,12 @@ public void onCreateMenu(Menu menu) {
} else {
menu.add(NONE, KindMenu.SHOW_HOT, NONE, R.string.feed_pref_resto_show_hot);
}

if ((kind & MenuTable.DisplayKind.COLD) == MenuTable.DisplayKind.COLD) {
if (displayed > 1) {
menu.add(NONE, KindMenu.HIDE_COLD, NONE, R.string.feed_pref_resto_hide_cold);
}
} else {
menu.add(NONE, KindMenu.SHOW_COLD, NONE, R.string.feed_pref_resto_show_cold);
}
}

@Override
public boolean onMenuItemClick(MenuItem item) {
return switch (item.getItemId()) {
case KindMenu.HIDE_HOT, KindMenu.HIDE_SOUP, KindMenu.SHOW_HOT, KindMenu.SHOW_SOUP, KindMenu.SHOW_COLD, KindMenu.HIDE_COLD -> {
case KindMenu.HIDE_HOT, KindMenu.HIDE_SOUP, KindMenu.SHOW_HOT, KindMenu.SHOW_SOUP -> {
adapter.companion().executeCommand(new RestoKindCommand(item.getItemId()));
yield true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class HomeFragment extends PreferenceFragment {

public static final String PREF_DATA_SAVER = "pref_home_feed_save_data";
public static final boolean PREF_DATA_SAVER_DEFAULT = false;
private static final String PREF_RESTO_KINDS = "pref_feed_resto_kinds_v2";
private static final String PREF_RESTO_KINDS = "pref_feed_resto_kinds_v3";
@MenuTable.DisplayKind
private static final int PREF_RESTO_KINDS_DEFAULT = MenuTable.DisplayKind.HOT | MenuTable.DisplayKind.SOUP;
private DeleteViewModel viewModel;
Expand Down
11 changes: 10 additions & 1 deletion app/src/main/java/be/ugent/zeus/hydra/resto/RestoMeal.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import android.os.Parcel;
import android.os.Parcelable;

import androidx.annotation.Nullable;

import java.util.List;

/**
Expand All @@ -33,7 +35,7 @@
* @author Niko Strijbol
* @author Mitch
*/
public record RestoMeal(String name, String price, String type, String kind,
public record RestoMeal(String name, @Nullable String price, @Nullable String type, String kind,
List<String> allergens) implements Parcelable {
public static final String MENU_TYPE_COLD = "cold";

Expand All @@ -55,6 +57,13 @@ public void writeToParcel(Parcel dest, int flags) {
dest.writeStringList(this.allergens);
}

public RestoMeal withPrice(String newPrice) {
return new RestoMeal(name, newPrice, type, kind, allergens);
}

public RestoMeal withName(String newName) {
return new RestoMeal(newName, price, type, kind, allergens);
}

public static final Parcelable.Creator<RestoMeal> CREATOR = new Parcelable.Creator<>() {
@Override
Expand Down
53 changes: 38 additions & 15 deletions app/src/main/java/be/ugent/zeus/hydra/resto/RestoMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.core.os.ParcelCompat;

import java.time.LocalDate;
Expand All @@ -44,36 +43,37 @@ public final class RestoMenu implements Parcelable {
private final boolean open;
private final LocalDate date;
private final List<RestoMeal> meals;
private final List<String> vegetables;
private final List<RestoMeal> vegetables2;
private final String message;

private transient CategorizedMeals categorized;

public RestoMenu(boolean open, LocalDate date, List<RestoMeal> meals, List<String> vegetables, String message) {
public RestoMenu(boolean open, LocalDate date, List<RestoMeal> meals, List<RestoMeal> vegetables2, String message) {
this.open = open;
this.date = date;
this.meals = meals;
this.vegetables = vegetables;
this.vegetables2 = vegetables2;
this.message = message;
}

private RestoMenu(Parcel in) {
this.open = in.readByte() != 0;
this.date = ParcelCompat.readSerializable(in, LocalDate.class.getClassLoader(), LocalDate.class);
this.meals = in.createTypedArrayList(RestoMeal.CREATOR);
this.vegetables = in.createStringArrayList();
this.vegetables2 = in.createTypedArrayList(RestoMeal.CREATOR);
this.message = in.readString();
}

/**
* Sort the meals available in the menu.
* This will also fix the soups.
*/
private void fillCategoriesIfNeeded() {
if (categorized != null) {
return;
}

var soups = new ArrayList<RestoMeal>();
List<RestoMeal> soups = new ArrayList<>();
var mainDishes = new ArrayList<RestoMeal>();
var coldDishes = new ArrayList<RestoMeal>();

Expand All @@ -89,12 +89,35 @@ private void fillCategoriesIfNeeded() {
}
}

soups = fixSoups(soups);

this.categorized = new CategorizedMeals(mainDishes, coldDishes, soups);
}

@VisibleForTesting
public RestoMenu withDate(LocalDate date) {
return new RestoMenu(open, date, meals, vegetables, message);
private static String removeSuffix(String word, String suffix) {
if (word.endsWith(suffix)) {
return word.substring(0, word.length() - suffix.length());
} else {
return word;
}
}

private List<RestoMeal> fixSoups(List<RestoMeal> soups) {
// TODO: this is rather ugly...
List<RestoMeal> finalSoups = new ArrayList<>();
var priceBig = "";
for (RestoMeal soup: soups) {
if (soup.name().endsWith("big") || soup.name().endsWith("groot")) {
priceBig = soup.price();
} else {
var name = removeSuffix(soup.name(), " small");
name = removeSuffix(name, " klein");
finalSoups.add(soup.withName(name));
}
}
final String suffix = priceBig;

return finalSoups.stream().map(s -> s.withPrice(s.price() + " / " + suffix)).toList();
}

/**
Expand All @@ -104,8 +127,8 @@ public boolean isClosed() {
return !open;
}

public List<String> vegetables() {
return vegetables;
public List<RestoMeal> vegetables() {
return vegetables2;
}

public LocalDate date() {
Expand Down Expand Up @@ -141,13 +164,13 @@ public boolean equals(Object o) {
return open == restoMenu.open &&
Objects.equals(date, restoMenu.date) &&
Objects.equals(meals, restoMenu.meals) &&
Objects.equals(vegetables, restoMenu.vegetables) &&
Objects.equals(vegetables2, restoMenu.vegetables2) &&
Objects.equals(message, restoMenu.message);
}

@Override
public int hashCode() {
return Objects.hash(open, date, meals, vegetables, message);
return Objects.hash(open, date, meals, vegetables2, message);
}

@Override
Expand All @@ -156,11 +179,11 @@ public int describeContents() {
}

@Override
public void writeToParcel(Parcel dest, int flags) {
public void writeToParcel(@NonNull Parcel dest, int flags) {
ParcelCompat.writeBoolean(dest, this.open);
dest.writeSerializable(this.date);
dest.writeTypedList(this.meals);
dest.writeStringList(this.vegetables);
dest.writeTypedList(this.vegetables2);
dest.writeString(this.message);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public class RestoPreferenceFragment extends PreferenceFragment {
public static final String DEFAULT_CLOSING_TIME = "21:00";
public static final String PREF_RESTO_CLOSING_HOUR = "pref_resto_closing_hour";

public static final String PREF_SHOW_ALLERGENS = "key_show_allergens";

public static String getDefaultRestoEndpoint(Context context) {
return context.getString(R.string.value_resto_default_endpoint);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public void onDestroyView() {
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.menuTable.setMenu(data, showAllergens);
binding.allergenWarningText.setVisibility(showAllergens ? View.VISIBLE : View.GONE);
}

public RestoMenu getData() {
Expand Down
Loading