diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/BaseActivity.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/BaseActivity.java index 62e13a9..06e2236 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/BaseActivity.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/BaseActivity.java @@ -24,16 +24,16 @@ import android.view.MenuItem; import android.view.View; import android.widget.FrameLayout; import android.widget.Toast; - import com.uam.wmi.findmytutor.R; import com.uam.wmi.findmytutor.service.BackgroundLocalizationService; import com.uam.wmi.findmytutor.utils.ActiveFragment; +import com.uam.wmi.findmytutor.utils.FeedbackUtils; import com.uam.wmi.findmytutor.utils.PrefUtils; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; + import static com.uam.wmi.findmytutor.utils.PrefUtils.storeBackgroundLocationStatus; @@ -55,7 +55,7 @@ public abstract class BaseActivity protected DrawerLayout sideDrawer; protected Toolbar toolbar; protected boolean isTutor; - + protected FeedbackUtils feedbackUtils; private ActionBarDrawerToggle actionBarDrawerToggle; private SharingFragment sharingFragment; @@ -68,7 +68,7 @@ public abstract class BaseActivity setContentView(getContentViewId()); drawerNavigationView = findViewById(R.id.nav_view); sideDrawer = findViewById(R.id.activity_container); - + feedbackUtils = new FeedbackUtils(BaseActivity.this); drawerNavigationView.setNavigationItemSelectedListener( item -> { String itemName = (String) item.getTitle(); @@ -76,17 +76,17 @@ public abstract class BaseActivity if (itemName.equals(getResources().getString(R.string.navigation_item_whitelist))) { /* launchIntent = new Intent(getApplicationContext(), WhitelistActivity.class); startActivity(launchIntent);*/ - } else if (itemName.equals(getResources().getString(R.string.navigation_item_blacklist))) { + } else if (itemName.equals(getResources().getString(R.string.navigation_item_blacklist))) { /* launchIntent = new Intent(getApplicationContext(), BlacklistActivity.class); startActivity(launchIntent);*/ - } else if (itemName.equals(getResources().getString(R.string.navigation_item_profile))) { + } else if (itemName.equals(getResources().getString(R.string.navigation_item_profile))) { /* launchIntent = new Intent(getApplicationContext(), ProfileActivity.class); startActivity(launchIntent);*/ - } else if (itemName.equals(getResources().getString(R.string.navigation_item_settings))) { + } else if (itemName.equals(getResources().getString(R.string.navigation_item_settings))) { launchIntent = new Intent(getApplicationContext(), SettingsActivity.class); startActivity(launchIntent); - } else if (itemName.equals(getResources().getString(R.string.navigation_item_logout))) { + } else if (itemName.equals(getResources().getString(R.string.navigation_item_logout))) { if(PrefUtils.isBackgroundLocationServiceRunning(getApplicationContext())) { stopBackgroundLocalizationTask(); } @@ -101,8 +101,14 @@ public abstract class BaseActivity } startActivity(i); finish(); + } else if (itemName.equals(getResources().getString(R.string.navigation_item_feedback))) { + feedbackUtils.showNoteDialog("FEEDBACK"); - } + /*showNoteDialog(BaseActivity.this, );*/ + } else if (itemName.equals(getResources().getString(R.string.navigation_item_bug))) { + feedbackUtils.showNoteDialog("BUG REPORT"); + /*showNoteDialog(BaseActivity.this, "BUG REPORT");*/ + } sideDrawer.closeDrawers(); @@ -351,6 +357,8 @@ public abstract class BaseActivity item.setChecked(true); } + + abstract int getNavigationMenuItemId(); abstract int getContentViewId(); diff --git a/app/src/main/java/com/uam/wmi/findmytutor/model/Feedback.java b/app/src/main/java/com/uam/wmi/findmytutor/model/Feedback.java new file mode 100644 index 0000000..1726c75 --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/model/Feedback.java @@ -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; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/uam/wmi/findmytutor/service/FeedbackService.java b/app/src/main/java/com/uam/wmi/findmytutor/service/FeedbackService.java new file mode 100644 index 0000000..a6d166c --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/service/FeedbackService.java @@ -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> postFeedback(@Body Feedback feedback); + + @GET("api/Feedback") + Single getFeedback(); +} diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/FeedbackUtils.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/FeedbackUtils.java new file mode 100644 index 0000000..afb3acd --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/FeedbackUtils.java @@ -0,0 +1,122 @@ +package com.uam.wmi.findmytutor.utils; + +import android.content.Context; +import android.content.DialogInterface; +import android.content.pm.PackageManager; +import android.os.Build; +import android.support.v7.app.AlertDialog; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; +import com.uam.wmi.findmytutor.R; +import com.uam.wmi.findmytutor.activity.BaseActivity; +import com.uam.wmi.findmytutor.model.Feedback; +import com.uam.wmi.findmytutor.network.ApiClient; +import com.uam.wmi.findmytutor.service.FeedbackService; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.schedulers.Schedulers; +import okhttp3.ResponseBody; +import retrofit2.Response; + +public class FeedbackUtils { + private Context activityContext; + public FeedbackUtils(Context context){ + activityContext = context; + } + public void showNoteDialog(String subject) { + + LayoutInflater layoutInflaterAndroid = LayoutInflater.from(activityContext); + View view = layoutInflaterAndroid.inflate(R.layout.feedback_modal, null); + AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(activityContext); + alertDialogBuilderUserInput.setView(view).setPositiveButton("SEND",null); + final AlertDialog alertDialog = alertDialogBuilderUserInput.create(); + + EditText modalUserInput = view.findViewById(R.id.feedback_input); + CheckBox modalIsAnonymous = view.findViewById(R.id.feedback_is_anonymous); + TextView modalTitle = view.findViewById(R.id.feedback_modal_title); + TextView modalSubtitle = view.findViewById(R.id.feedback_modal_subtitle); + modalTitle.setText(subject); + if( subject == "BUG REPORT"){ + modalSubtitle.setText("Tell us what you noticed!(max 1000 characters)"); + } else if (subject == "FEEDBACK") + { + modalSubtitle.setText("Tell us what you think!(max 1000 characters)"); + } + alertDialog.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface dialogInterface) { + Button sendButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); + sendButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + String body = modalUserInput.getText().toString(); + if(TextUtils.isEmpty(body)){ + Toast.makeText(activityContext, "Please describe your insights.", Toast.LENGTH_SHORT).show(); + modalUserInput.requestFocus(); + }else{ + boolean mode = modalIsAnonymous.isChecked(); + sendFeedback(subject,body,mode); + alertDialog.dismiss(); + } + } + }); + } + }); + alertDialog.show(); + } + + private void sendFeedback(String header, String body, boolean mode) { + String appVersion = null; + String metadata = null; + try { + appVersion = activityContext.getPackageManager().getPackageInfo(activityContext.getPackageName(), 0).versionName; + if( !mode ){ + metadata = "\n-----------------------------\n" + + "User ID: " + PrefUtils.getUserId(activityContext) + "\n" + + "Device OS: Android\n" + + "Device OS version: " + Build.VERSION.RELEASE + "\n" + + "App Version: " + appVersion + "\n" + + "Device Model: " + Build.MODEL + "\n" + + "Device Manufacturer: " + Build.MANUFACTURER + "\n" + + "-----------------------------\n"; + body = metadata + body; + header = header + " - " + PrefUtils.getUserFirstName(activityContext) + " " + PrefUtils.getUserLastName(activityContext); + } + } catch (PackageManager.NameNotFoundException e) { + } + FeedbackService feedbackService = ApiClient.getClient(activityContext).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)); + } + private void handleResponse(Response resp) { + Toast.makeText(activityContext, "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(activityContext, + RestApiHelper.getErrorMessage(responseBody), Toast.LENGTH_SHORT).show(); + + } else { + Toast.makeText(activityContext, + "Network error " + error.getMessage(), Toast.LENGTH_SHORT).show(); + Log.d("FEEDBACK",error.getMessage()); + } + } +} diff --git a/app/src/main/res/drawable/bug_icon.xml b/app/src/main/res/drawable/bug_icon.xml new file mode 100644 index 0000000..c3458e1 --- /dev/null +++ b/app/src/main/res/drawable/bug_icon.xml @@ -0,0 +1,4 @@ + + + diff --git a/app/src/main/res/layout/feedback_modal.xml b/app/src/main/res/layout/feedback_modal.xml new file mode 100644 index 0000000..c3b8aa2 --- /dev/null +++ b/app/src/main/res/layout/feedback_modal.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml index d9c6b19..90a85ef 100644 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -1,6 +1,6 @@ - + - + + + + + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 2c4cc2b..ec438d4 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -127,6 +127,8 @@ Ta aplikacja potrzebuje uprawnień do lokalizacji. Ustawienia statusu Ręczny wybór lokalizacji + Wyślij nam feedback + Zgłoś błąd Bounds OFF diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b45da5c..69f5ad4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,9 +12,19 @@ Drawer Closed Blacklist Whitelist + Send us feedback + Report a bug Settings Profile Log out + + + Find My Tutor - feedback + Find My Tutor - bug report + Please input your feedback. + Send anonymously + + Settings Notes @@ -34,6 +44,7 @@ White List Settings + findmytutorwmi@gmail.com