Skip to content

Commit

Permalink
Report feedback widget manually (#242)
Browse files Browse the repository at this point in the history
* Report Feedback Widget Manually

* removing unused functions

* feedback module has been added.

* added changelog entry

* Updated changelog

* deleted d.ts file

* added react native module to countly state

* changed return type

* deprecated old calls

* rounding up

* Update Feedback.js

changed some names and definitions

* Update CHANGELOG.md

* Update Feedback.js

* Updated SDK version to 23.8.0

* Update Feedback.js

---------

Co-authored-by: turtledreams <[email protected]>
Co-authored-by: ijunaid <[email protected]>
  • Loading branch information
3 people authored Oct 5, 2023
1 parent bbad4dc commit a9f72ec
Show file tree
Hide file tree
Showing 9 changed files with 535 additions and 100 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## 23.8.0
* Added new Feedback interface (`Countly.feedback`) on the SDK interface that exposes the calls for feedback widgets.
* Added Manual Reporting feature for the Feedback Widgets. This includes two new methods under the new Feedback interface:
* 'getFeedbackWidgetData'
* 'reportFeedbackWidgetManually'

* Fixed bug on Android devices for unhandled promise rejection on `getRemoteConfigValueForKeyP`.

* Underlying Android SDK version is 23.8.2
* Underlying iOS SDK version is 23.8.2

## 23.6.1
* Fixed bug for Android devices where "getRemoteConfigValueForKey" and "getRemoteConfigValueForKeyP" methods would return the RCData object.

Expand Down
218 changes: 123 additions & 95 deletions Countly.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion CountlyReactNative.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'CountlyReactNative'
s.version = '23.6.1'
s.version = '23.8.0'
s.license = {
:type => 'COMMUNITY',
:text => <<-LICENSE
Expand Down
6 changes: 6 additions & 0 deletions CountlyState.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const CountlyState = {};

CountlyState.isInitialized = false
CountlyState.CountlyReactNative = null;

export default CountlyState;
156 changes: 156 additions & 0 deletions Feedback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
const Feedback = {};
/**
* Get a list of available feedback widgets as an array of objects.
* @param {callback listener} onFinished - returns (retrievedWidgets, error)
* @return {Object} Object {error: String or Null, data: Array or null }
*/
async function getAvailableFeedbackWidgets(onFinished) {
if (!Feedback.state.isInitialized) {
const message = "'init' must be called before 'getAvailableFeedbackWidgets'";
Feedback.instance.logError('getAvailableFeedbackWidgets', message);
return { error: message, data: null };
}

let result = null;
let error = null;
try {
result = await Feedback.state.CountlyReactNative.getFeedbackWidgets();
} catch (e) {
error = e.message;
}
if (onFinished) {
onFinished(result, error);
}
return { error: error, data: result };
}

/**
* Present a chosen feedback widget
*
* @param {Object} feedbackWidget - feedback Widget with id, type and name
* @param {String} closeButtonText - text for cancel/close button
* @param {callback listener} widgetShownCallback - Callback to be executed when feedback widget is displayed
* @param {callback listener} widgetClosedCallback - Callback to be executed when feedback widget is closed
*
* @return {Object} Object {error: String or null}
*/
function presentFeedbackWidget(feedbackWidget, closeButtonText, widgetShownCallback, widgetClosedCallback) {
if (!Feedback.state.isInitialized) {
const message = "'init' must be called before 'presentFeedbackWidget'";
Feedback.instance.logError('presentFeedbackWidget', msg);
return { error: message };
}
let message = null;
if (!feedbackWidget) {
message = 'feedbackWidget should not be null or undefined';
Feedback.instance.logError('presentFeedbackWidget', message);
return { error: message };
}
if (!feedbackWidget.id) {
message = 'FeedbackWidget id should not be null or empty';
Feedback.instance.logError('presentFeedbackWidget', message);
return { error: message };
}
if (!feedbackWidget.type) {
message = 'FeedbackWidget type should not be null or empty';
Feedback.instance.logError('presentFeedbackWidget', message);
return { error: message };
}
if (typeof closeButtonText !== 'string') {
closeButtonText = '';
Feedback.instance.logWarning('presentFeedbackWidget', `unsupported data type of closeButtonText : '${typeof args}'`);
}

if (widgetShownCallback) {
_widgetShownCallback = eventEmitter.addListener(widgetShownCallbackName, () => {
widgetShownCallback();
_widgetShownCallback.remove();
});
}
if (widgetClosedCallback) {
_widgetClosedCallback = eventEmitter.addListener(widgetClosedCallbackName, () => {
widgetClosedCallback();
_widgetClosedCallback.remove();
});
}

feedbackWidget.name = feedbackWidget.name || '';
closeButtonText = closeButtonText || '';
Feedback.state.CountlyReactNative.presentFeedbackWidget([feedbackWidget.id, feedbackWidget.type, feedbackWidget.name, closeButtonText]);
return { error: null };
}

/**
* Get a feedback widget's data as an Object.
* @param {Object} widgetInfo - widget to get data for. You should get this from 'getAvailableFeedbackWidgets' method.
* @param {callback listener} onFinished - returns (Object retrievedWidgetData, error)
* @return {Object} Object {error: String, data: Object or null}
*/
async function getFeedbackWidgetData(widgetInfo, onFinished) {
if (!Feedback.state.isInitialized) {
const message = "'initWithConfig' must be called before 'getFeedbackWidgetData'";
Feedback.instance.logError('getFeedbackWidgetData', message);
onFinished(null, message);
return { error: message, data: null };
}
const widgetId = widgetInfo.id;
const widgetType = widgetInfo.type;
Feedback.instance.logInfo('getFeedbackWidgetData', 'Calling "getFeedbackWidgetData" with Type:[' + widgetType + ']');
const args = [];
args.push(widgetId);
args.push(widgetType);
args.push(widgetInfo.name);
let result = null;
let error = null;
try {
result = await Feedback.state.CountlyReactNative.getFeedbackWidgetData(args);
} catch (e) {
error = e.message;
}
if (onFinished) {
onFinished(result, error);
}
return { error: error, data: result };
}

/**
* Report manually for a feedback widget.
* @param {Object} widgetInfo - the widget you are targeting. You should get this from 'getAvailableFeedbackWidgets' method.
* @param {Object} widgetData - data of that widget. You should get this from 'getFeedbackWidgetData' method.
* @param {Object} widgetResult - Information you want to report.
* @return {Object} Object {error: String}
*/
function reportFeedbackWidgetManually(widgetInfo, widgetData, widgetResult) {
if (!Feedback.state.isInitialized) {
const message = "'initWithConfig' must be called before 'reportFeedbackWidgetManually'";
Feedback.instance.logError('reportFeedbackWidgetManually', message);
return { error: message };
}
const widgetId = widgetInfo.id;
const widgetType = widgetInfo.type;
Feedback.instance.logInfo('reportFeedbackWidgetManually', 'Calling "reportFeedbackWidgetManually" with Type:[' + widgetType + ']');
const widgetInfoList = [];
widgetInfoList.push(widgetId);
widgetInfoList.push(widgetType);
widgetInfoList.push(widgetInfo.name);

const args = [];
args.push(widgetInfoList);
args.push(widgetData);
args.push(widgetResult);

let error = null;
try {
Feedback.state.CountlyReactNative.reportFeedbackWidgetManually(args);
} catch (e) {
error = e.message;
}
return { error: error };
}

Feedback.getAvailableFeedbackWidgets = getAvailableFeedbackWidgets;
Feedback.presentFeedbackWidget = presentFeedbackWidget;
Feedback.getFeedbackWidgetData = getFeedbackWidgetData;
Feedback.reportFeedbackWidgetManually = reportFeedbackWidgetManually;

export default Feedback;
Loading

0 comments on commit a9f72ec

Please sign in to comment.