sharing as per whatsapp figma

This commit is contained in:
ShriPrakashBajpai
2023-09-22 17:35:26 +05:30
parent f8fd8a724f
commit 504f4588db
11 changed files with 228 additions and 90 deletions

View File

@@ -21,6 +21,9 @@ import org.json.JSONObject;
import java.util.List;
import android.net.Uri;
import android.util.Log;
public class DeviceUtilsModule extends ReactContextBaseJavaModule implements ActivityEventListener {
private ReactApplicationContext RNContext;
@@ -77,4 +80,40 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule implements Act
promise.reject( err);
}
}
// @ReactMethod
// public void sendFeedbackToWhatsapp(String encodedMessage, String encodedImageUri, String mimeType) {
// log.d("Native Function is called");
// log.d("sendFeedbackToWhatsapp", encodedMessage, encodedImageUri, mimeType);
// Intent sendIntent = new Intent();
// sendIntent.setAction(Intent.ACTION_SEND);
// sendIntent.putExtra(Intent.EXTRA_TEXT, encodedMessage);
// sendIntent.setType(mimeType);
// sendIntent.putExtra(Intent.EXTRA_STREAM, encodedImageUri);
// sendIntent.setPackage("com.whatsapp");
// startActivity(sendIntent);
// return;
// }
@ReactMethod
public void sendFeedbackToWhatsapp(String encodedMessage, String encodedImageUri, String mimeType) {
Log.d("Native Function called","string eg");
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, encodedMessage);
sendIntent.setType(mimeType);
// Convert the encodedImageUri to a URI and set it as an EXTRA_STREAM
Uri uri = Uri.parse(encodedImageUri);
sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
sendIntent.setPackage("com.whatsapp");
// Start the activity
getCurrentActivity().startActivity(sendIntent);
return;
}
}

View File

@@ -72,6 +72,7 @@
"react-native-qrcode-svg": "^6.2.0",
"react-native-safe-area-context": "4.4.1",
"react-native-screens": "3.18.2",
"react-native-send-intent": "^1.3.0",
"react-native-share": "^9.4.1",
"react-native-svg": "^13.9.0",
"react-native-tab-view": "3.3.2",

View File

@@ -1,6 +1,5 @@
import * as React from 'react';
import Svg, { Rect, Mask, Path, G } from 'react-native-svg';
const ChevronDown = (props) => (
<Svg xmlns="http://www.w3.org/2000/svg" fill="none" {...props}>
<Rect width={24} height={24} fill="#F5F9FF" rx={12} />

View File

@@ -0,0 +1,2 @@
export const expandAccordianPath =
'M8.466 1.233a.63.63 0 0 0-.183.465.63.63 0 0 0 .183.465l3.057 3.055a.587.587 0 0 0 .216.141.742.742 0 0 0 .25.041c.088 0 .171-.013.249-.04.077-.029.15-.076.216-.142l3.073-3.072a.609.609 0 0 0 .183-.448.637.637 0 0 0-.2-.465.63.63 0 0 0-.465-.183.63.63 0 0 0-.465.183l-2.592 2.59-2.608-2.607a.61.61 0 0 0-.449-.182.638.638 0 0 0-.465.199Z';

View File

@@ -0,0 +1,2 @@
export const shrinkAccordianPath =
'M8.466 13.767a.63.63 0 0 1-.183-.465.63.63 0 0 1 .183-.465l3.057-3.055a.587.587 0 0 1 .216-.141.742.742 0 0 1 .25-.041c.088 0 .171.013.249.04.077.029.15.076.216.142l3.073 3.072a.609.609 0 0 1 .183.448.637.637 0 0 1-.2.465.63.63 0 0 1-.465.183.63.63 0 0 1-.465-.183l-2.592-2.59-2.608 2.607a.61.61 0 0 1-.449.182.638.638 0 0 1-.465-.199Z';

View File

@@ -206,8 +206,9 @@ const CollectionCaseDetails: React.FC<ICaseDetails> = (props) => {
const commonParams = {
loanAccountNumber: caseDetail.loanAccountNumber,
customerReferenceId: caseDetail.customerReferenceId,
caseId,
caseId: caseId,
};
console.log(caseId);
navigateToScreen(route, { ...params, ...commonParams });
};
@@ -454,6 +455,7 @@ const CollectionCaseDetails: React.FC<ICaseDetails> = (props) => {
<FeedbackListContainer
feedbackList={[...getUnSyncedFeedback(), ...feedbackList]?.splice(0, 5)}
loanAccountNumber={caseDetail?.loanAccountNumber as string}
caseID={caseId}
/>
</View>
</Animated.View>

View File

@@ -4,6 +4,7 @@ import Accordion from '../../../../RN-UI-LIB/src/components/accordian/Accordian'
import NavigationHeader from '../../../../RN-UI-LIB/src/components/NavigationHeader';
import Text from '../../../../RN-UI-LIB/src/components/Text';
import { GenericStyles, SCREEN_HEIGHT, getShadowStyle } from '../../../../RN-UI-LIB/src/styles';
import Chevron from '../../../../RN-UI-LIB/src/Icons/Chevron';
import { COLORS } from '../../../../RN-UI-LIB/src/styles/colors';
import { getPastFeedbacks, getPastFeedbacksOnAddresses } from '../../../action/feedbackActions';
import { GenericType } from '../../../common/GenericTypes';
@@ -25,6 +26,8 @@ import { setFeedbackHistoryLoading } from '../../../reducer/feedbackHistorySlice
import SuspenseLoader from '../../../../RN-UI-LIB/src/components/suspense_loader/SuspenseLoader';
import LineLoader from '../../../../RN-UI-LIB/src/components/suspense_loader/LineLoader';
import NoPastFeedbackIcon from '../../../assets/icons/NoPastFeedbackIcon';
import { expandAccordianPath } from '../../../constants/icons/ExpandAccordian';
import { shrinkAccordianPath } from '../../../constants/icons/ShrinkAccordian';
const FEEDBACK_PAGE_TITLE = 'All feedbacks';
const ADDRESS_FEEDBACK_PAGE_TITLE = 'Address feedback';
@@ -32,6 +35,22 @@ const ADDRESS_FEEDBACK_PAGE_TITLE = 'Address feedback';
const SCROLL_LAYOUT_OFFSET = 10;
const FEEDBACK_PER_PAGE = 5;
const shrinkAccordianProps = {
width: 24,
height: 24,
fillColor: '#0276FE',
rotateY: 0,
path: shrinkAccordianPath,
};
const expandAccordianProps = {
width: 24,
height: 24,
fillColor: '#0276FE',
rotateY: 0,
path: expandAccordianPath,
};
interface IFeedbackDetailContainer {
route: {
params: {
@@ -39,15 +58,24 @@ interface IFeedbackDetailContainer {
addressReferenceIds?: string[];
addressText?: string;
activeFeedbackReferenceId?: string;
caseID: string;
};
};
}
const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: routeParams }) => {
const {
params: { loanAccountNumber, activeFeedbackReferenceId, addressReferenceIds, addressText },
params: {
loanAccountNumber,
activeFeedbackReferenceId,
addressReferenceIds,
addressText,
caseID,
},
} = routeParams;
console.log({ routeParams });
const isPastFeedbackOnAddress = addressText || addressReferenceIds?.length;
const [isExpanded, setIsExpanded] = useState<boolean>(false);
@@ -221,11 +249,12 @@ const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: ro
key={feedback.referenceId}
feedbackItem={feedback}
isExpanded={isExpanded}
caseID={caseID}
/>
}
customExpandUi={{
whenCollapsed: <Text style={styles.accordionExpandBtn}>View more</Text>,
whenExpanded: <Text style={styles.accordionExpandBtn}>View less</Text>,
whenCollapsed: <Chevron {...expandAccordianProps} />,
whenExpanded: <Chevron {...shrinkAccordianProps} />,
}}
onExpanded={(value) => {
setIsExpanded(value);

View File

@@ -1,5 +1,5 @@
import React, { ReactNode } from 'react';
import { View, StyleSheet, TouchableOpacity, Linking } from 'react-native';
import { View, StyleSheet, TouchableOpacity, Linking, Platform, NativeModules } from 'react-native';
import Text from '../../../../RN-UI-LIB/src/components/Text';
import { GenericStyles } from '../../../../RN-UI-LIB/src/styles';
import { COLORS } from '../../../../RN-UI-LIB/src/styles/colors';
@@ -25,17 +25,21 @@ import IconLabel from '../../../common/IconLabel';
import WhatsAppFeedbackShareIcon from '../../../assets/icons/WhatsAppIcon';
import RNFetchBlob from 'rn-fetch-blob';
import Share from 'react-native-share';
import { useAppSelector } from '../../../hooks';
import { InteractionStatuses } from '../../allCases/interface';
const { DeviceUtilsModule } = NativeModules;
interface IFeedbackDetailItem {
feedbackItem: IFeedback;
isExpanded: boolean;
caseID: string;
}
const feedbackTypeIcon: Record<FEEDBACK_TYPE, ReactNode> = {
FIELD_VISIT: <MapIcon />,
INHOUSE_FIELD_VISIT: <MapIcon />,
SELF_CALL: <CallIcon fillColor={COLORS.TEXT.BLUE} />,
CALL_BRIDGE: <CallIcon fillColor={COLORS.TEXT.BLUE} />,
FIELD_VISIT: <MapIcon fill="#969696" />,
INHOUSE_FIELD_VISIT: <MapIcon fill="#969696" />,
SELF_CALL: <CallIcon fillColor="#969696" />,
CALL_BRIDGE: <CallIcon fillColor="#969696" />,
};
const getAddress = (address?: IAddress) => {
@@ -61,14 +65,26 @@ function getLocationLink(latitude: string, longitude: string): string {
return link;
}
const sendToWhatsapp = (feedbackItem: IFeedback) => {
var message = '';
message += 'Feedback Type: ' + sanitizeString(feedbackItem.type) + '\n\n';
message += 'Disposition: ' + sanitizeString(feedbackItem.interactionStatus) + '\n\n';
const sendToWhatsapp = (feedbackItem: IFeedback, caseDetails: any) => {
var message = '*Visit Feedback for* ' + sanitizeString(caseDetails?.customerName) + '\n';
message +=
'Feedback Date and Time: ' +
sanitizeString(dateFormat(new Date(feedbackItem.createdAt), 'DD MMM YYYY, HH:mm A')) +
'\n\n';
sanitizeString(dateFormat(new Date(feedbackItem.createdAt), 'DD MMM YYYY | HH:mm A')) + '\n\n';
message += 'LAN: ' + sanitizeString(caseDetails?.loanAccountNumber);
message += '| DPD Bucket: ' + sanitizeString(caseDetails?.dpdBucket) + '\n\n';
message += 'Disposition: ' + sanitizeString(feedbackItem.interactionStatus);
console.log('PRIIIIIIIINTINGGGGGGGGGGGGGGGG');
console.log(feedbackItem);
const ptpDate = feedbackItem.answerViews.filter((answer) => answer.questionName === 'PTP Date');
if (ptpDate.length > 0) {
message += ' for ' + sanitizeString(ptpDate[0].inputDate) + '\n\n';
}
const answerList = feedbackItem.answerViews.filter(
(answer) => answer.questionName === 'Comments'
);
if (answerList.length > 0) {
message += 'Comments: ' + sanitizeString(answerList[0].inputText) + '\n\n';
}
{
feedbackItem.metadata?.interactionLatitude &&
feedbackItem.metadata?.interactionLongitude &&
@@ -116,6 +132,7 @@ const sendToWhatsapp = (feedbackItem: IFeedback) => {
console.log(imageUrl);
console.log(url);
//Linking.openURL(url);
//////////////////////////////////////////////////////////////
let shareImage = {
title: 'Agent Feedback',
message: message,
@@ -123,9 +140,9 @@ const sendToWhatsapp = (feedbackItem: IFeedback) => {
social: Share.Social.WHATSAPP,
};
//console.log(shareImage);
Share.open(shareImage);
return RNFetchBlob.fs.unlink(imagePath);
//Share.open(shareImage);
//return RNFetchBlob.fs.unlink(imagePath);
////////////////////////////////////////////////////////////////
// Linking.canOpenURL(url)
// .then(isInstalled => {
// if (!isInstalled) {
@@ -138,80 +155,112 @@ const sendToWhatsapp = (feedbackItem: IFeedback) => {
// }
// })
// .catch(error => console.error('An error occurred', error));
// const sendIntent = Platform.select({
// ios: null,
// android: {
// action: 'android.intent.action.SEND',
// intentType: 'text/plain',
// extras: {
// 'android.intent.extra.TEXT': encodedMessage,
// 'android.intent.extra.STREAM': encodedImageUri,
// 'android.intent.extra.SUBJECT': 'Subject',
// },
// packageName: 'com.whatsapp',
// },
// });
// return Linking.openURL(sendIntent);
const mimeType = 'image/*';
console.log(DeviceUtilsModule);
DeviceUtilsModule.sendFeedbackToWhatsApp(message, imageUri, mimeType);
});
};
const FeedbackDetailItem = ({ feedbackItem, isExpanded }: IFeedbackDetailItem) => {
const FeedbackDetailItem = ({ feedbackItem, isExpanded, caseID }: IFeedbackDetailItem) => {
const caseDetails = useAppSelector((state) => state.allCases.caseDetails[caseID]);
return (
<View style={[GenericStyles.ph8]}>
<View style={[GenericStyles.row, GenericStyles.alignCenter]}>
{feedbackTypeIcon[feedbackItem.type] ? (
<View style={GenericStyles.mr8}>{feedbackTypeIcon[feedbackItem.type]}</View>
) : null}
console.log(caseID),
console.log(caseDetails),
(
<View style={[GenericStyles.ph8]}>
<View style={[GenericStyles.row, GenericStyles.alignCenter]}>
{feedbackTypeIcon[feedbackItem.type] ? (
<View style={GenericStyles.mr8}>{feedbackTypeIcon[feedbackItem.type]}</View>
) : null}
<Text
numberOfLines={1}
ellipsizeMode="tail"
style={[
styles.textContainer,
styles.cardBoldTitle,
GenericStyles.pb4,
GenericStyles.mr16,
]}
>
{sanitizeString(feedbackItem.interactionStatus)}
</Text>
</View>
<Text
numberOfLines={1}
ellipsizeMode="tail"
style={[
styles.textContainer,
styles.cardBoldTitle,
GenericStyles.pb4,
GenericStyles.mr16,
styles.cardFooterText,
GenericStyles.fontSize12,
GenericStyles.mb12,
]}
>
{sanitizeString(feedbackItem.interactionStatus)}
{sanitizeString(dateFormat(new Date(feedbackItem.createdAt), BUSINESS_DATE_FORMAT))}
&nbsp;&nbsp;&#9679;&nbsp;&nbsp;
{sanitizeString(dateFormat(new Date(feedbackItem.createdAt), BUSINESS_TIME_FORMAT))}
</Text>
<Text
numberOfLines={isExpanded ? 100 : 3}
ellipsizeMode="tail"
style={[styles.textContainer, styles.cardLightTitle, GenericStyles.w100]}
>
{FIELD_FEEDBACKS.includes(feedbackItem.type)
? sanitizeString(getAddress(feedbackItem.source as IAddress))
: sanitizeString(
[
(feedbackItem.source as ICallingFeedback)?.recipientNumber,
feedbackItem.sourceText ? `(${feedbackItem.sourceText})` : '',
].join(' ')
)}
</Text>
</View>
<Text
numberOfLines={1}
ellipsizeMode="tail"
style={[styles.textContainer, styles.cardFooterText, GenericStyles.fontSize12]}
>
{sanitizeString(dateFormat(new Date(feedbackItem.createdAt), BUSINESS_DATE_FORMAT))}
&nbsp;&nbsp;&#9679;&nbsp;&nbsp;
{sanitizeString(dateFormat(new Date(feedbackItem.createdAt), BUSINESS_TIME_FORMAT))}
</Text>
<View style={[GenericStyles.borderTop, GenericStyles.w100, GenericStyles.mv16]} />
<Text
numberOfLines={isExpanded ? 100 : 3}
ellipsizeMode="tail"
style={[styles.textContainer, styles.cardLightTitle, GenericStyles.w100]}
>
{FIELD_FEEDBACKS.includes(feedbackItem.type)
? sanitizeString(getAddress(feedbackItem.source as IAddress))
: sanitizeString(
[
(feedbackItem.source as ICallingFeedback)?.recipientNumber,
feedbackItem.sourceText ? `(${feedbackItem.sourceText})` : '',
].join(' ')
)}
</Text>
{feedbackItem.metadata?.interactionLatitude && FIELD_FEEDBACKS.includes(feedbackItem.type) ? (
<>
<View style={styles.container}>
<TouchableOpacity
activeOpacity={0.7}
onPress={() =>
openGeolocation(
feedbackItem.metadata?.interactionLatitude,
feedbackItem.metadata?.interactionLongitude
)
}
style={[GenericStyles.row, GenericStyles.pv12]}
>
<Text style={[styles.textContainer, styles.geolocationBtn]}>Open map</Text>
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.7} onPress={() => sendToWhatsapp(feedbackItem)}>
<IconLabel
text="Share"
icon={<WhatsAppFeedbackShareIcon />}
textStyle={{ color: COLORS.BASE.BLUE }}
/>
</TouchableOpacity>
</View>
</>
) : null}
</View>
{feedbackItem.metadata?.interactionLatitude &&
FIELD_FEEDBACKS.includes(feedbackItem.type) ? (
<>
<View style={styles.container}>
<TouchableOpacity
activeOpacity={0.7}
onPress={() =>
openGeolocation(
feedbackItem.metadata?.interactionLatitude,
feedbackItem.metadata?.interactionLongitude
)
}
style={[GenericStyles.row, GenericStyles.pv12]}
>
<Text style={[styles.textContainer, styles.geolocationBtn]}>Open map</Text>
</TouchableOpacity>
<TouchableOpacity
activeOpacity={0.7}
onPress={() => sendToWhatsapp(feedbackItem, caseDetails)}
>
<IconLabel
text="Share"
icon={<WhatsAppFeedbackShareIcon />}
textStyle={{ color: COLORS.BASE.BLUE }}
/>
</TouchableOpacity>
</View>
</>
) : null}
</View>
)
);
};

View File

@@ -18,6 +18,7 @@ import { getCaseUnifiedData, UnifiedCaseDetailsTypes } from '../../../action/cas
interface IFeedbackListContainer {
loanAccountNumber: string;
feedbackList: (IFeedback | IUnSyncedFeedbackItem)[];
caseID: string;
}
interface IOfflineFeedbackListContainer {
@@ -66,6 +67,7 @@ const OfflineFeedbackListContainer: React.FC<IOfflineFeedbackListContainer> = ({
const FeedbackListContainer: React.FC<IFeedbackListContainer> = ({
loanAccountNumber,
feedbackList,
caseID,
}) => {
const [retryBtnCount, setRetryBtnCount] = useState(0);
@@ -91,15 +93,19 @@ const FeedbackListContainer: React.FC<IFeedbackListContainer> = ({
}
return (
<View>
{feedbackList.map((feedbackItem: IFeedback | IUnSyncedFeedbackItem, idx: number) => (
<FeedbackListItem
feedbackItem={feedbackItem}
loanAccountNumber={loanAccountNumber}
showHorizontalLine={++idx !== feedbackList.length}
/>
))}
</View>
console.log(caseID),
(
<View>
{feedbackList.map((feedbackItem: IFeedback | IUnSyncedFeedbackItem, idx: number) => (
<FeedbackListItem
feedbackItem={feedbackItem}
loanAccountNumber={loanAccountNumber}
showHorizontalLine={++idx !== feedbackList.length}
caseID={caseID}
/>
))}
</View>
)
);
};

View File

@@ -15,11 +15,13 @@ interface IFeedbackListItem {
feedbackItem: IFeedback | IUnSyncedFeedbackItem;
showHorizontalLine?: boolean;
loanAccountNumber: string;
caseID: string;
}
const FeedbackListItem: React.FC<IFeedbackListItem> = ({
feedbackItem,
loanAccountNumber,
caseID,
showHorizontalLine = true,
}) => {
const handleRouting = (route: PageRouteEnum, params: object | undefined = undefined) => {
@@ -27,7 +29,9 @@ const FeedbackListItem: React.FC<IFeedbackListItem> = ({
const commonParams = {
loanAccountNumber,
activeFeedbackReferenceId: (feedbackItem as IFeedback).referenceId,
caseID: caseID,
};
console.log(caseID);
navigateToScreen(route, { ...params, ...commonParams });
};

View File

@@ -7820,6 +7820,11 @@ react-native-screens@3.18.2:
react-freeze "^1.0.0"
warn-once "^0.1.0"
react-native-send-intent@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/react-native-send-intent/-/react-native-send-intent-1.3.0.tgz#d8c7898827da1b8b10e25a645ce6802d1a0b440c"
integrity sha512-ODTX7BHITFxdcAL0K2iHfa3qVYnqG8GPcv1NbLBNC1DyCaOSJiiGtVH6Kc5YBqzQ8+1pV9uN5nfQ5wyFgiq74g==
react-native-share@^9.4.1:
version "9.4.1"
resolved "https://registry.yarnpkg.com/react-native-share/-/react-native-share-9.4.1.tgz#1b6d96015009e3878bfc4346940602c1cffff525"