In app feedback (#4845)

* rebase

* Progress

* Completed UI and POST Request

* removed invalid string resource

* Removed unused code & Added string resources

* Resolved Code style issues

* Javadoc for getters & setters

* Codestyle fixes

* Minor Fixes

* wip

* Tests

* Comments

* Fixed Tests

* Minor changes

* minor change

* Comments

* Minor Fixes

* fixed tests

* Removed Butterknife

* Fixed tests

* Removed Unecessary strings

* Minor chnages

* Minor fix

* Minor changes

* Minor changes

* Implemented Suggestions

* Removed Redundant Toast
This commit is contained in:
Devarsh Mavani 2022-03-20 08:40:25 +05:30 committed by GitHub
parent 00760ba1c6
commit fa0370438b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 777 additions and 5 deletions

View file

@ -0,0 +1,95 @@
package fr.free.nrw.commons.feedback;
import android.content.Context;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.feedback.model.Feedback;
import fr.free.nrw.commons.utils.LangCodeUtils;
import java.util.Locale;
/**
* Creates a wikimedia recognizable format
* from feedback information
*/
public class FeedbackContentCreator {
private StringBuilder stringBuilder;
private Feedback feedback;
private Context context;
public FeedbackContentCreator(Context context, Feedback feedback) {
this.feedback = feedback;
this.context = context;
init();
}
/**
* Initializes the string buffer object to append content from feedback object
*/
public void init() {
// Localization is not needed here, because this ends up on a page where developers read the feedback, so English is the most convenient.
stringBuilder = new StringBuilder();
stringBuilder.append("== ");
stringBuilder.append("Feedback from ~~~ for version ");
stringBuilder.append(feedback.getVersion());
stringBuilder.append(" ==");
stringBuilder.append("\n");
stringBuilder.append(feedback.getTitle());
stringBuilder.append("\n");
stringBuilder.append("\n");
if (feedback.getApiLevel() != null) {
stringBuilder.append("* ");
stringBuilder.append(LangCodeUtils.getLocalizedResources(context,
Locale.ENGLISH).getString(R.string.api_level));
stringBuilder.append(": ");
stringBuilder.append(feedback.getApiLevel());
stringBuilder.append("\n");
}
if (feedback.getAndroidVersion() != null) {
stringBuilder.append("* ");
stringBuilder.append(LangCodeUtils.getLocalizedResources(context,
Locale.ENGLISH).getString(R.string.android_version));
stringBuilder.append(": ");
stringBuilder.append(feedback.getAndroidVersion());
stringBuilder.append("\n");
}
if (feedback.getDeviceManufacturer() != null) {
stringBuilder.append("* ");
stringBuilder.append(LangCodeUtils.getLocalizedResources(context,
Locale.ENGLISH).getString(R.string.device_manufacturer));
stringBuilder.append(": ");
stringBuilder.append(feedback.getDeviceManufacturer());
stringBuilder.append("\n");
}
if (feedback.getDeviceModel() != null) {
stringBuilder.append("* ");
stringBuilder.append(LangCodeUtils.getLocalizedResources(context,
Locale.ENGLISH).getString(R.string.device_model));
stringBuilder.append(": ");
stringBuilder.append(feedback.getDeviceModel());
stringBuilder.append("\n");
}
if (feedback.getDevice() != null) {
stringBuilder.append("* ");
stringBuilder.append(LangCodeUtils.getLocalizedResources(context,
Locale.ENGLISH).getString(R.string.device_name));
stringBuilder.append(": ");
stringBuilder.append(feedback.getDevice());
stringBuilder.append("\n");
}
if (feedback.getNetworkType() != null) {
stringBuilder.append("* ");
stringBuilder.append(LangCodeUtils.getLocalizedResources(context,
Locale.ENGLISH).getString(R.string.network_type));
stringBuilder.append(": ");
stringBuilder.append(feedback.getNetworkType());
stringBuilder.append("\n");
}
stringBuilder.append("~~~~");
stringBuilder.append("\n");
}
@Override
public String toString() {
return stringBuilder.toString();
}
}

View file

@ -0,0 +1,66 @@
package fr.free.nrw.commons.feedback;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.databinding.DialogFeedbackBinding;
import fr.free.nrw.commons.feedback.model.Feedback;
import fr.free.nrw.commons.utils.ConfigUtils;
import fr.free.nrw.commons.utils.DeviceInfoUtil;
/**
* Feedback dialog that asks user for message and
* other device specifications
*/
public class FeedbackDialog extends Dialog {
DialogFeedbackBinding dialogFeedbackBinding;
private OnFeedbackSubmitCallback onFeedbackSubmitCallback;
public FeedbackDialog(Context context, OnFeedbackSubmitCallback onFeedbackSubmitCallback) {
super(context);
this.onFeedbackSubmitCallback = onFeedbackSubmitCallback;
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dialogFeedbackBinding = DialogFeedbackBinding.inflate(getLayoutInflater());
final View view = dialogFeedbackBinding.getRoot();
setContentView(view);
dialogFeedbackBinding.btnSubmitFeedback.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
submitFeedback();
}
});
}
/**
* When the button is clicked, it will create a feedback object
* and give a callback to calling activity/fragment
*/
void submitFeedback() {
if(dialogFeedbackBinding.feedbackItemEditText.getText().toString().equals("")) {
dialogFeedbackBinding.feedbackItemEditText.setError(getContext().getString(R.string.enter_description));
return;
}
String appVersion = ConfigUtils.getVersionNameWithSha(getContext());
String androidVersion = dialogFeedbackBinding.androidVersionCheckbox.isChecked() ? DeviceInfoUtil.getAndroidVersion() : null;
String apiLevel = dialogFeedbackBinding.apiLevelCheckbox.isChecked() ? DeviceInfoUtil.getAPILevel() : null;
String deviceManufacturer = dialogFeedbackBinding.deviceManufacturerCheckbox.isChecked() ? DeviceInfoUtil.getDeviceManufacturer() : null;
String deviceModel = dialogFeedbackBinding.deviceModelCheckbox.isChecked() ? DeviceInfoUtil.getDeviceModel() : null;
String deviceName = dialogFeedbackBinding.deviceNameCheckbox.isChecked() ? DeviceInfoUtil.getDevice() : null;
String networkType = dialogFeedbackBinding.networkTypeCheckbox.isChecked() ? DeviceInfoUtil.getConnectionType(getContext()).toString() : null;
Feedback feedback = new Feedback(appVersion, apiLevel
, dialogFeedbackBinding.feedbackItemEditText.getText().toString()
, androidVersion, deviceModel, deviceManufacturer, deviceName, networkType);
onFeedbackSubmitCallback.onFeedbackSubmit(feedback);
dismiss();
}
}

View file

@ -0,0 +1,15 @@
package fr.free.nrw.commons.feedback;
import fr.free.nrw.commons.feedback.model.Feedback;
/**
* This interface is used to provide callback
* from Feedback dialog whenever submit button is clicked
*/
public interface OnFeedbackSubmitCallback {
/**
* callback function, called when user clicks on submit
*/
void onFeedbackSubmit(Feedback feedback);
}

View file

@ -0,0 +1,171 @@
package fr.free.nrw.commons.feedback.model;
/**
* Pojo class for storing information that are required while uploading a feedback
*/
public class Feedback {
/**
* Version of app
*/
private String version;
/**
* API level of user's phone
*/
private String apiLevel;
/**
* Title/Description entered by user
*/
private String title;
/**
* Android version of user's device
*/
private String androidVersion;
/**
* Device Model of user's device
*/
private String deviceModel;
/**
* Device manufacturer name
*/
private String deviceManufacturer;
/**
* Device name stored on user's device
*/
private String device;
/**
* network type user is having (Ex: Wifi)
*/
private String networkType;
public Feedback(final String version, final String apiLevel, final String title, final String androidVersion,
final String deviceModel, final String deviceManufacturer, final String device, final String networkType
) {
this.version = version;
this.apiLevel = apiLevel;
this.title = title;
this.androidVersion = androidVersion;
this.deviceModel = deviceModel;
this.deviceManufacturer = deviceManufacturer;
this.device = device;
this.networkType = networkType;
}
/**
* Get the version from which this piece of feedback is being sent.
* Ex: 3.0.1
*/
public String getVersion() {
return version;
}
/**
* Set the version of app to given version
*/
public void setVersion(final String version) {
this.version = version;
}
/**
* gets api level of device
* Ex: 28
*/
public String getApiLevel() {
return apiLevel;
}
/**
* sets api level value to given value
*/
public void setApiLevel(final String apiLevel) {
this.apiLevel = apiLevel;
}
/**
* gets feedback text entered by user
*/
public String getTitle() {
return title;
}
/**
* sets feedback text
*/
public void setTitle(final String title) {
this.title = title;
}
/**
* gets android version of device
* Ex: 9
*/
public String getAndroidVersion() {
return androidVersion;
}
/**
* sets value of android version
*/
public void setAndroidVersion(final String androidVersion) {
this.androidVersion = androidVersion;
}
/**
* get device model of current device
* Ex: Redmi 6 Pro
*/
public String getDeviceModel() {
return deviceModel;
}
/**
* sets value of device model to a given value
*/
public void setDeviceModel(final String deviceModel) {
this.deviceModel = deviceModel;
}
/**
* get device manufacturer of user's device
* Ex: Redmi
*/
public String getDeviceManufacturer() {
return deviceManufacturer;
}
/**
* set device manufacturer value to a given value
*/
public void setDeviceManufacturer(final String deviceManufacturer) {
this.deviceManufacturer = deviceManufacturer;
}
/**
* get device name of user's device
*/
public String getDevice() {
return device;
}
/**
* sets device name value to a given value
*/
public void setDevice(final String device) {
this.device = device;
}
/**
* get network type of user's network
* Ex: wifi
*/
public String getNetworkType() {
return networkType;
}
/**
* sets network type to a given value
*/
public void setNetworkType(final String networkType) {
this.networkType = networkType;
}
}