added feedback model and service, added sending feedback

This commit is contained in:
Marcin Jedynski 2018-11-13 12:16:01 +01:00
parent c9b4548f45
commit f89971d059
6 changed files with 187 additions and 73 deletions

View File

@ -8,6 +8,7 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
@ -22,33 +23,48 @@ import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView; import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.annimon.stream.Stream; import com.annimon.stream.Stream;
import com.auth0.android.jwt.Claim;
import com.auth0.android.jwt.JWT;
import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
import com.uam.wmi.findmytutor.R; import com.uam.wmi.findmytutor.R;
import com.uam.wmi.findmytutor.model.DutyHourViewModel; import com.uam.wmi.findmytutor.model.DutyHourViewModel;
import com.uam.wmi.findmytutor.model.Feedback;
import com.uam.wmi.findmytutor.model.JwtToken;
import com.uam.wmi.findmytutor.model.TutorTabViewModel; import com.uam.wmi.findmytutor.model.TutorTabViewModel;
import com.uam.wmi.findmytutor.model.User; import com.uam.wmi.findmytutor.model.User;
import com.uam.wmi.findmytutor.network.ApiClient;
import com.uam.wmi.findmytutor.service.BackgroundLocalizationService; import com.uam.wmi.findmytutor.service.BackgroundLocalizationService;
import com.uam.wmi.findmytutor.service.FeedbackService;
import com.uam.wmi.findmytutor.utils.ActiveFragment; import com.uam.wmi.findmytutor.utils.ActiveFragment;
import com.uam.wmi.findmytutor.utils.PrefUtils; import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RestApiHelper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableSingleObserver; import io.reactivex.observers.DisposableSingleObserver;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import retrofit2.Response;
import static com.uam.wmi.findmytutor.utils.PrefUtils.storeBackgroundLocationStatus; import static com.uam.wmi.findmytutor.utils.PrefUtils.storeBackgroundLocationStatus;
@ -118,9 +134,9 @@ public abstract class BaseActivity
startActivity(i); startActivity(i);
finish(); finish();
} else if (itemName.equals(getResources().getString(R.string.navigation_item_feedback))) { } else if (itemName.equals(getResources().getString(R.string.navigation_item_feedback))) {
showNoteDialog(BaseActivity.this, R.string.email_subject_feedback); showNoteDialog(BaseActivity.this, "Feedback");
} else if (itemName.equals(getResources().getString(R.string.navigation_item_bug))) { } else if (itemName.equals(getResources().getString(R.string.navigation_item_bug))) {
showNoteDialog(BaseActivity.this, R.string.email_subject_bug); showNoteDialog(BaseActivity.this, "Bug report");
} }
sideDrawer.closeDrawers(); sideDrawer.closeDrawers();
@ -370,73 +386,94 @@ public abstract class BaseActivity
MenuItem item = navigationView.getMenu().findItem(itemId); MenuItem item = navigationView.getMenu().findItem(itemId);
item.setChecked(true); item.setChecked(true);
} }
/**
* Email client intent to send support mail
* Appends the necessary device information to email body
* useful when providing support
*/
private void sendFeedback(Context context, int subject, String mode) {
String appVersion = null;
String body = null;
try {
appVersion = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
if( mode == "full"){
body = "\n\n-----------------------------\nPlease don't remove this information\n Device OS: Android \n Device OS version: " +
Build.VERSION.RELEASE + "\n App Version: " + appVersion + "\n Device Brand: " + Build.BRAND +
"\n Device Model: " + Build.MODEL + "\n Device Manufacturer: " + Build.MANUFACTURER + "\n Marian Kowalski!!!";
} else if ( mode == "anonymous"){
body = "\n\n-----------------------------\nPlease don't remove this information\n Device OS: Android \n Device OS version: " +
Build.VERSION.RELEASE + "\n App Version: " + appVersion + "\n Device Brand: " + Build.BRAND +
"\n Device Model: " + Build.MODEL + "\n Device Manufacturer: " + Build.MANUFACTURER;
}
} catch (PackageManager.NameNotFoundException e) {
}
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{context.getString(R.string.fmt_email)});
intent.putExtra(Intent.EXTRA_SUBJECT, context.getString(subject));
intent.putExtra(Intent.EXTRA_TEXT, body);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(Intent.createChooser(intent, context.getString(R.string.choose_email_client)));
}
private void showNoteDialog(Context context, int subject) { private void showNoteDialog(Context context, String subject) {
LayoutInflater layoutInflaterAndroid = LayoutInflater.from(BaseActivity.this); LayoutInflater layoutInflaterAndroid = LayoutInflater.from(BaseActivity.this);
//View view = layoutInflaterAndroid.inflate(R.layout.feedback_modal, null); View view = layoutInflaterAndroid.inflate(R.layout.feedback_modal, null);
AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(BaseActivity.this); AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(BaseActivity.this);
//alertDialogBuilderUserInput.setView(view); alertDialogBuilderUserInput.setView(view);
alertDialogBuilderUserInput.setNegativeButton(R.string.cancel, (dialog, id) -> {
// User cancelled the dialog
});
final AlertDialog alertDialog = alertDialogBuilderUserInput.create(); final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE,"OK", new DialogInterface.OnClickListener() {
EditText userInput = view.findViewById(R.id.feedback_input);
CheckBox isAnonymous = view.findViewById(R.id.feedback_is_anonymous);
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE,"SEND", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
// Write your code here to execute after dialog String body = userInput.getText().toString();
// closed boolean mode = isAnonymous.isChecked();
Toast.makeText(getApplicationContext(), sendFeedback(context,subject,body,mode);
"You clicked on OK", Toast.LENGTH_SHORT).show();
}
});
/* Button yes = (Button) alertDialog.findViewById(R.id.feedback_modal_yes);
Button no = (Button) alertDialog.findViewById(R.id.feedback_modal_no);*/
/* yes.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
sendFeedback(context,subject,"full");
} }
}); });
no.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
sendFeedback(context,subject,"anonymous");
}
});*/
alertDialog.show(); alertDialog.show();
}
/**
* Email client intent to send support mail
* Appends the necessary device information to email body
* useful when providing support
*/
private void sendFeedback(Context context, String header, String body, boolean mode) {
String appVersion = null;
String metadata = null;
try {
appVersion = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
if( !mode ){
metadata = "\n-----------------------------\n" +
"User ID: " + PrefUtils.getUserId(context) + "\n" +
"Device OS: Android\n" +
"Device OS version: " + Build.VERSION.RELEASE +
"App Version: " + appVersion + "\n" +
"Device Brand: " + Build.BRAND + "\n" +
"Device Model: " + Build.MODEL + "\n" +
"Device Manufacturer: " + Build.MANUFACTURER + "\n" +
"-----------------------------\n";
body = metadata + body;
header = header + " - " + PrefUtils.getUserFirstName(context) + " " + PrefUtils.getUserLastName(context);
}
} catch (PackageManager.NameNotFoundException e) {
}
FeedbackService feedbackService = ApiClient.getClient(context).create(FeedbackService.class);
Feedback userFeedback = new Feedback(mode,header,body);
CompositeDisposable disposable = new CompositeDisposable();
disposable.add(feedbackService.postFeedback(userFeedback)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponse, this::handleError));
/* Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{context.getString(R.string.fmt_email)});
intent.putExtra(Intent.EXTRA_SUBJECT, context.getString(subject));
intent.putExtra(Intent.EXTRA_TEXT, body);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(Intent.createChooser(intent, context.getString(R.string.choose_email_client)));*/
}
private void handleResponse(Response<Void> resp) {
Toast.makeText(getApplicationContext(), "Thank you for subbmiting your feedback", Toast.LENGTH_SHORT).show();
}
private void handleError(Throwable error) {
if (error instanceof HttpException) {
ResponseBody responseBody = ((HttpException) error).response().errorBody();
Toast.makeText(getApplicationContext(),
RestApiHelper.getErrorMessage(responseBody), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(),
"Network error " + error.getMessage(), Toast.LENGTH_SHORT).show();
Log.d("FEEDBACK",error.getMessage());
}
} }
abstract int getNavigationMenuItemId(); abstract int getNavigationMenuItemId();

View File

@ -0,0 +1,47 @@
package com.uam.wmi.findmytutor.model;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Feedback {
@SerializedName("isAnonymous")
@Expose
private Boolean isAnonymous;
@SerializedName("header")
@Expose
private String header;
@SerializedName("body")
@Expose
private String body;
public Feedback(boolean isAnonymous, String header, String body){
this.isAnonymous = isAnonymous;
this.header = header;
this.body = body;
}
public Boolean getIsAnonymous() {
return isAnonymous;
}
public void setIsAnonymous(Boolean isAnonymous) {
this.isAnonymous = isAnonymous;
}
public String getHeader() {
return header;
}
public void setHeader(String header) {
this.header = header;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}

View File

@ -0,0 +1,17 @@
package com.uam.wmi.findmytutor.service;
import com.uam.wmi.findmytutor.model.Feedback;
import io.reactivex.Observable;
import io.reactivex.Single;
import retrofit2.Response;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
public interface FeedbackService {
@POST("api/Feedback")
Observable<Response<Void>> postFeedback(@Body Feedback feedback);
@GET("api/Feedback")
Single<Feedback> getFeedback();
}

View File

@ -1,37 +1,48 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"> android:paddingTop="@dimen/activity_vertical_margin">
<TextView <EditText
android:id="@+id/feedback_modal_question" android:id="@+id/feedback_input"
android:layout_width="wrap_content" android:layout_width="315dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:layout_marginTop="46dp" android:layout_marginTop="50dp"
android:text="Do you want to send it anonymously?" /> android:ems="10"
android:maxLength="1000"
android:hint="@string/modal_feedback_hint"
android:inputType="textMultiLine"
android:maxLines="10"
android:scrollbars="vertical"
android:requiresFadingEdge="vertical"
/>
<Button <TextView
android:id="@+id/feedback_modal_yes" android:id="@+id/textView5"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_below="@+id/feedback_input"
android:layout_marginTop="69dp" android:layout_alignStart="@+id/feedback_input"
android:layout_toStartOf="@+id/feedback_modal_question" android:layout_marginStart="3dp"
android:text="Yes" /> android:layout_marginTop="23dp"
android:text="@string/modal_feedback_question"
android:textSize="16sp" />
<Button <CheckBox
android:id="@+id/feedback_modal_no" android:id="@+id/feedback_is_anonymous"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignTop="@id/feedback_modal_yes" android:layout_alignBaseline="@+id/textView5"
android:layout_toEndOf="@+id/feedback_modal_question" android:layout_alignEnd="@+id/feedback_input"
android:text="No" /> android:textSize="14sp" />
</RelativeLayout> </RelativeLayout>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<group> <group android:id="@+id/drawer_group_tutor">
<item <item
android:id="@+id/nav_item_one" android:id="@+id/nav_item_one"
android:icon="@drawable/ic_people_white" android:icon="@drawable/ic_people_white"
@ -14,7 +14,7 @@
android:icon="@drawable/outline_person_white_24dp" android:icon="@drawable/outline_person_white_24dp"
android:title="@string/navigation_item_profile" /> android:title="@string/navigation_item_profile" />
</group> </group>
<group> <group android:id="@+id/drawer_group_feedback">
<item <item
android:id="@+id/nav_item_four" android:id="@+id/nav_item_four"
android:icon="@android:drawable/ic_dialog_email" android:icon="@android:drawable/ic_dialog_email"
@ -24,7 +24,7 @@
android:icon="@drawable/bug_icon" android:icon="@drawable/bug_icon"
android:title="@string/navigation_item_bug" /> android:title="@string/navigation_item_bug" />
</group> </group>
<group> <group android:id="@+id/drawer_group_utilities">
<item <item
android:id="@+id/nav_item_six" android:id="@+id/nav_item_six"
android:icon="@drawable/ic_menu_settings_key" android:icon="@drawable/ic_menu_settings_key"

View File

@ -21,6 +21,8 @@
<!--Feedback/Bug report--> <!--Feedback/Bug report-->
<string name="email_subject_feedback">Find My Tutor - feedback</string> <string name="email_subject_feedback">Find My Tutor - feedback</string>
<string name="email_subject_bug">Find My Tutor - bug report</string> <string name="email_subject_bug">Find My Tutor - bug report</string>
<string name="modal_feedback_hint">Please input your feedback.</string>
<string name="modal_feedback_question">Do you want to send it anonymously ?</string>
<!-- Tutors list --> <!-- Tutors list -->