Commit 53a89ce2 authored by Willard's avatar Willard

Implement favorites and reviews for stalls, improve scrolling on dish ListView

parent 08204b59
......@@ -31,7 +31,7 @@
android:theme="@style/AppTheme.NoActionBar"/>
<activity
android:name=".DishViewActivity"
android:label="@string/title_activity_blahblah"
android:label="@string/title_activity_dish_view"
android:theme="@style/AppTheme"/>
<activity
android:name=".StallViewActivity"
......@@ -41,6 +41,10 @@
android:name=".DishReviewActivity"
android:label="@string/title_activity_add_dish_review"
android:theme="@style/AppTheme"/>
<activity
android:name=".StallReviewActivity"
android:label="@string/title_activity_add_stall_review"
android:theme="@style/AppTheme"/>
<activity android:name=".RegisterActivity">
</activity>
</application>
......
......@@ -84,6 +84,13 @@ public interface CanteeneoApiInterface {
@POST("api/stalls/{id}/reviews")
Call<ResponseBody> newStallReview(@Path("id") int id, @Body StallReview review);
@PUT("api/stalls/{id}/reviews/{review_id}")
Call<ResponseBody> editStallReview(@Path("id") int id, @Path("review_id") int review_id, @Body StallReview review);
@DELETE("api/stalls/{id}/reviews/{review_id}")
Call<ResponseBody> deleteStallReview(@Path("id") int id, @Path("review_id") int review_id);
@GET("api/stalls/{id}/dishes")
Call<List<Dish>> getDishesByStall(@Path("id") int id);
......
......@@ -36,16 +36,29 @@ public class DishAdapter extends BaseAdapter {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = context.getLayoutInflater().inflate(R.layout.dish_row, null);
TextView name = (TextView) v.findViewById(R.id.tvName);
TextView price = (TextView) v.findViewById(R.id.tvPrice);
ImageView image = (ImageView) v.findViewById(R.id.iv);
DishViewHolder holder;
if(convertView == null) {
convertView = context.getLayoutInflater().inflate(R.layout.dish_row, null);
holder = new DishViewHolder();
holder.name = (TextView)convertView.findViewById(R.id.tvName);
holder.price = (TextView)convertView.findViewById(R.id.tvPrice);
holder.image = (ImageView)convertView.findViewById(R.id.iv);
convertView.setTag(holder);
} else {
holder = (DishViewHolder)convertView.getTag();
}
Dish d = dishes.get(position);
name.setText(d.getName());
price.setText(d.getPrice()+"");
Picasso.with(context).load("http://" + parent.getResources().getString(R.string.server_ip) + ":5000/static/uploads/"+ d.getImagePath()).fit().centerCrop().into(image);
holder.name.setText(d.getName());
holder.price.setText(d.getPrice()+"");
Picasso.with(context).load("http://" + parent.getResources().getString(R.string.server_ip) + ":5000/static/uploads/"+ d.getImagePath()).fit().centerCrop().tag(context).into(holder.image);
return v;
return convertView;
}
static class DishViewHolder {
TextView name;
TextView price;
ImageView image;
}
}
......@@ -112,7 +112,6 @@ public class DishReviewAdapter extends BaseAdapter {
deleteButton.setVisibility(View.INVISIBLE);
}
Toast.makeText(v.getContext(), dr.getBody(), Toast.LENGTH_SHORT).show();
return v;
}
}
package com.testapp;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.EditText;
import android.widget.RatingBar;
import android.widget.Toast;
import com.testapp.entities.DishReview;
import com.testapp.entities.StallReview;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class StallReviewActivity extends AppCompatActivity {
private EditText title;
private EditText body;
private RatingBar rating;
private int id;
private int reviewId;
private boolean editing;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_review);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
editing = getIntent().getBooleanExtra("EDITING", false);
title = (EditText) findViewById(R.id.rv_title);
body = (EditText) findViewById(R.id.rv_body);
rating = (RatingBar) findViewById(R.id.rv_rating);
if(editing) {
setTitle("Edit Stall Review");
reviewId = getIntent().getIntExtra("REVIEW_ID", 0);
title.setText(getIntent().getStringExtra("EDIT_TITLE"));
body.setText(getIntent().getStringExtra("EDIT_BODY"));
rating.setRating(getIntent().getFloatExtra("EDIT_RATING", 0f));
} else {
setTitle("Add Stall Review");
}
id = getIntent().getIntExtra("ID", 0);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
StallReview rv = new StallReview();
rv.setTitle(title.getText().toString());
rv.setBody(body.getText().toString());
rv.setRating(rating.getRating());
rv.setStallId(id);
rv.setUserId(AppUtils.userId);
if(editing) {
editReview(reviewId, rv);
} else {
newReview(rv);
}
}
});
}
public void newReview(StallReview review) {
Call<ResponseBody> call = AppUtils.service.newStallReview(id, review);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
setResult(RESULT_OK);
finish();
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getApplicationContext(), "Posting review failed", Toast.LENGTH_SHORT);
}
});
}
public void editReview(int reviewId, StallReview review) {
Call<ResponseBody> call = AppUtils.service.editStallReview(id, reviewId, review);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
setResult(RESULT_OK);
finish();
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getApplicationContext(), "Editing review failed", Toast.LENGTH_SHORT);
}
});
}
}
package com.testapp;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import com.testapp.entities.StallReview;
import java.util.ArrayList;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class StallReviewAdapter extends BaseAdapter {
private Activity context;
ArrayList<StallReview> stallReviews;
......@@ -43,12 +53,65 @@ public class StallReviewAdapter extends BaseAdapter {
TextView body = (TextView) v.findViewById(R.id.body);
TextView username = (TextView) v.findViewById(R.id.user);
StallReview dr = stallReviews.get(position);
title.setText(dr.getTitle());
rating.setRating(dr.getRating());
body.setText(dr.getBody());
username.setText(dr.getUser());
// TODO set username
final StallReview sr = stallReviews.get(position);
title.setText(sr.getTitle());
rating.setRating(sr.getRating());
body.setText(sr.getBody());
username.setText(sr.getUser());
Button editButton = (Button)v.findViewById(R.id.edit_button);
Button deleteButton = (Button)v.findViewById(R.id.delete_button);
if(sr.getUserId() == AppUtils.userId) {
editButton.setVisibility(View.VISIBLE);
editButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Activity context = StallReviewAdapter.this.context;
Intent i = new Intent(context, StallReviewActivity.class);
i.putExtra("ID", sr.getUserId());
i.putExtra("REVIEW_ID", sr.getId());
i.putExtra("EDITING", true);
i.putExtra("EDIT_TITLE", sr.getTitle());
i.putExtra("EDIT_BODY", sr.getBody());
i.putExtra("EDIT_RATING", sr.getRating());
context.startActivityForResult(i, 0);
}
});
deleteButton.setVisibility(View.VISIBLE);
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final StallViewActivity context = (StallViewActivity)StallReviewAdapter.this.context;
new AlertDialog.Builder(context)
.setTitle("Confirm Delete")
.setMessage("Are you sure you want to delete your review? This cannot be undone.")
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Call<ResponseBody> call = AppUtils.service.deleteStallReview(sr.getStallId(), sr.getId());
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Toast.makeText(context, "Review deleted", Toast.LENGTH_SHORT).show();
context.getStallReviews(sr.getStallId());
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
})
.setNegativeButton(R.string.no, null)
.show();
}
});
} else {
editButton.setVisibility(View.INVISIBLE);
deleteButton.setVisibility(View.INVISIBLE);
}
return v;
}
}
......@@ -7,10 +7,12 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.squareup.picasso.Picasso;
import com.testapp.entities.Dish;
......@@ -73,8 +75,8 @@ public class StallViewActivity extends AppCompatActivity {
location.setText(s.getLocation());
TextView description = (TextView) findViewById(R.id.stall_description);
description.setText(s.getDescription());
ImageView image = (ImageView) findViewById(R.id.stall_logo);
Picasso.with(getApplicationContext()).load("http://" + getResources().getString(R.string.server_ip) + ":5000/static/uploads/"+ s.getImagePath()).fit().centerCrop().into(image);
//ImageView image = (ImageView) findViewById(R.id.stall_logo);
//Picasso.with(getApplicationContext()).load("http://" + getResources().getString(R.string.server_ip) + ":5000/static/uploads/"+ s.getImagePath()).fit().centerCrop().into(image);
favoriteCheckbox = (CheckBox)findViewById(R.id.favorite_checkbox);
favoriteCheckbox.setOnClickListener(new View.OnClickListener() {
@Override
......@@ -108,6 +110,16 @@ public class StallViewActivity extends AppCompatActivity {
}
});
Button addReviewBtn = (Button) findViewById(R.id.add_review_button);
addReviewBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(StallViewActivity.this, StallReviewActivity.class);
i.putExtra("ID", id);
startActivityForResult(i, 0);
}
});
ListView lvDishes = (ListView) findViewById(R.id.stall_dishes);
dAdapter = new DishAdapter(StallViewActivity.this, dishes);
getStallDishes(id);
......@@ -157,13 +169,27 @@ public class StallViewActivity extends AppCompatActivity {
}
});
}
private void getStallReviews(int id) {
public void getStallReviews(int id) {
Call<List<StallReview>> call = AppUtils.service.getStallReviews(id);
call.enqueue(new Callback<List<StallReview>>() {
@Override
public void onResponse(Call<List<StallReview>> call, Response<List<StallReview>> response) {
List<StallReview> newReviews = response.body();
StallReview ownedReview = null;
for(StallReview review: newReviews) {
if(review.getUserId() == AppUtils.userId) {
ownedReview = review;
break;
}
}
reviews.clear();
if(ownedReview != null) {
newReviews.remove(ownedReview);
reviews.add(ownedReview);
}
findViewById(R.id.add_review_button).setVisibility(ownedReview != null? View.INVISIBLE: View.VISIBLE);
reviews.addAll(newReviews);
srAdapter.notifyDataSetChanged();
}
......@@ -174,4 +200,14 @@ public class StallViewActivity extends AppCompatActivity {
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 0) {
if (resultCode == RESULT_OK) {
Toast.makeText(this, "Review Posted!", Toast.LENGTH_SHORT).show();
getStallReviews(id);
}
}
}
}
......@@ -5,12 +5,16 @@ public class StallReview {
int id;
String title;
String body;
int rating;
float rating;
String user;
int user_id;
int stall_id;
public StallReview(int id, String title, String body, String user, int rating, int user_id, int stall_id) {
public StallReview() {
}
public StallReview(int id, String title, String body, String user, float rating, int user_id, int stall_id) {
this.id = id;
this.title = title;
this.body = body;
......@@ -32,9 +36,9 @@ public class StallReview {
public void setBody(String body) { this.body = body; }
public int getRating() { return rating; }
public float getRating() { return rating; }
public void setRating(int rating) { this.rating = rating; }
public void setRating(float rating) { this.rating = rating; }
public String getUser() {
return user;
......
......@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.testapp.DishReviewActivity">
tools:context="com.testapp.StallReviewActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_stall_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.testapp.StallViewActivity"
tools:showIn="@layout/activity_stall_view">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_blahblah"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.testapp.StallViewActivity"
tools:showIn="@layout/activity_stall_view">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
android:fillViewport="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@mipmap/canteeneo_logo"
android:id="@+id/stall_logo" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="Location: "
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
/>
<TextView
android:text="Location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/stall_location"
android:layout_weight="1" />
<CheckBox
android:text="Favorite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:id="@+id/favorite_checkbox"
android:layout_weight="1"
android:elevation="0dp"/>
</LinearLayout>
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="10dp"
android:layout_weight="1">
android:layout_height="wrap_content"
android:weightSum="2">
<TextView
android:text="Description:"
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView"
android:textSize="18sp"
android:paddingTop="0dp"
android:paddingLeft="0dp"
android:paddingRight="0dp" />
<TextView
android:text="STOL"
android:layout_weight="1"
android:weightSum="5"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="3">
<TextView
android:text="Name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/dish_name"
android:layout_weight="2"
android:textSize="18sp" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="Location: "
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
/>
<TextView
android:text="Location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/stall_location"
android:layout_weight="1" />
</LinearLayout>
<CheckBox
android:text="Favorite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/favorite_checkbox"
android:button="@drawable/favorite_checkbox"
android:layout_marginBottom="10dp"
android:layout_weight="1" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="78dp"
app:srcCompat="@mipmap/ic_launcher"
android:id="@+id/dish_pic"
android:layout_weight="2" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/stall_description"
android:paddingTop="5dp" />
android:weightSum="10"
android:paddingTop="10dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_weight="1"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<TextView
android:text="Description:"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="18sp" />
<TextView
android:text="This is a foodz"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/stall_description"
android:layout_weight="9"
android:paddingTop="5dp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="Dishes:"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView9"
android:layout_marginTop="10dp"
android:textSize="18sp" />
android:layout_height="wrap_content"
android:layout_weight="3"
android:paddingTop="10dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:weightSum="14"
android:paddingLeft="10dp">
<ListView
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/stall_dishes"
android:fadeScrollbars="false" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:text="Reviews:"
android:layout_height="wrap_content">
<TextView
android:text="Dishes:"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView9"
android:layout_marginTop="10dp"
android:textSize="18sp" />
<ListView
android:layout_width="match_parent"
android:layout_height="125dp"
android:id="@+id/stall_dishes"
android:fadeScrollbars="false" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView10"
android:textSize="18sp"
android:paddingTop="10dp" />
android:layout_weight="1">
<TextView
android:text="Reviews:"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/review_text"
android:textSize="18sp"
android:layout_weight="1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/add_review_button"
android:drawableLeft="@drawable/ic_add_circle_outline_black_24dp"
android:text="Add your own review"
style="@style/Widget.AppCompat.Button.Borderless"/>
</LinearLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/stall_reviews"
android:fadeScrollbars="false" />
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>
......@@ -39,9 +39,10 @@
<item>Item 222</item>
<item>Item 333</item>
</string-array>
<string name="title_activity_blahblah">blahblah</string>
<string name="title_activity_dish_view">DishViewActivity</string>
<string name="title_activity_stall_view">StallViewActivity</string>
<string name="title_activity_add_dish_review">AddDishReviewActivity</string>
<string name="title_activity_add_stall_review">AddStallReviewActivity</string>
<string name="yes">Yes</string>
<string name="no">No</string>
</resources>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment