NTP-7916 | coach mark cosmetic fixes

This commit is contained in:
Aman Chaturvedi
2024-12-16 17:16:14 +05:30
parent 5869b43bf7
commit eb1ec79491
8 changed files with 64 additions and 43 deletions

View File

@@ -2,7 +2,9 @@ import firestore from '@react-native-firebase/firestore';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import { TIMESTAMP_IST } from '@rn-ui-lib/utils/dates';
import { TIMESTAMP_IST, TIMEZONE_ASIA } from '@rn-ui-lib/utils/dates';
import { addClickstreamEvent } from '@services/clickstreamEventService';
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
dayjs.extend(utc);
dayjs.extend(timezone);
@@ -15,7 +17,7 @@ export const showCoachMark = async (
const coachMarkDoc = firestore().collection('coachMarks').doc(agentId);
const userSnapshot = await coachMarkDoc.get();
let coachMarkData = userSnapshot.data()?.coachMarkData;
const dayJsTime = dayjs().tz('Asia/Kolkata').format(TIMESTAMP_IST);
const dayJsTime = dayjs().tz(TIMEZONE_ASIA).format(TIMESTAMP_IST);
const timestamp = serverTimestamp || dayJsTime;
if (!coachMarkData) {
@@ -26,10 +28,11 @@ export const showCoachMark = async (
};
callback().then(
async () => {
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_FILTER_COACHMARKS_LOADED);
await coachMarkDoc.set({ coachMarkData }, { merge: true });
},
(error) => {
console.log('error', error);
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_FILTER_COACHMARKS_FAILED);
}
);
return;
@@ -46,10 +49,11 @@ export const showCoachMark = async (
coachMarkData.lastSeenDate = timestamp;
callback().then(
async () => {
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_FILTER_COACHMARKS_LOADED);
await coachMarkDoc.set({ coachMarkData }, { merge: true });
},
(error) => {
console.log('error', error);
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_FILTER_COACHMARKS_FAILED);
}
);
}

View File

@@ -1385,6 +1385,16 @@ export const CLICKSTREAM_EVENT_NAMES = {
name: 'FA_PERSIST_ORIGINAL_IMAGE_FAILURE',
description: 'Failed to persist original image'
},
// Filter coachmarks
FA_FILTER_COACHMARKS_LOADED: {
name: 'FA_FILTER_COACHMARKS_LOADED',
description: 'Filter coachmarks loaded'
},
FA_FILTER_COACHMARKS_FAILED: {
name: 'FA_FILTER_COACHMARKS_FAILED',
description: 'Filter coachmarks failed'
}
} as const;
export enum MimeType {

View File

@@ -60,6 +60,7 @@ export const CopilotModal = forwardRef<CopilotModalHandle, CopilotOptions>(funct
setStylesForNoHighlightArea(rect);
return;
}
// center of the coachmark element
const center = {
x: rect.x + rect.width / 2,
y: rect.y + rect.height / 2,
@@ -70,24 +71,31 @@ export const CopilotModal = forwardRef<CopilotModalHandle, CopilotOptions>(funct
const relativeToBottom = Math.abs(center.y - SCREEN_HEIGHT);
const relativeToRight = Math.abs(center.x - SCREEN_WIDTH);
// position of tooltip
const verticalPosition = relativeToBottom > relativeToTop ? 'bottom' : 'top';
const horizontalPosition = relativeToLeft > relativeToRight ? 'left' : 'right';
const tooltip: ViewStyle = {};
if (verticalPosition === 'bottom') {
// if the tooltip is at the bottom, we need to add some margin to the bottom
tooltip.top = rect.y + rect.height + margin;
} else {
// if the tooltip is at the top, we need to add some margin to the top
tooltip.bottom = noHighlightArea ? 40 : SCREEN_HEIGHT - rect.y + margin + margin;
}
if (horizontalPosition === 'left') {
// if the tooltip is at the left, we need to add some margin to the left
tooltip.right = Math.min(SCREEN_WIDTH - (rect.x + rect.width), 24);
} else {
// if the tooltip is at the right, we need to add some margin to the right
tooltip.left = noHighlightArea ? 50 : Math.min(rect.x, 24);
}
setTooltipStyles(tooltip);
// highlight area dimensions and position
setMaskRect({
width: rect.width,
height: rect.height,
@@ -144,14 +152,14 @@ export const CopilotModal = forwardRef<CopilotModalHandle, CopilotOptions>(funct
transparent
style={{ backgroundColor: 'transparent' }}
>
<View style={styles.container}>
{showMask ? <AnimatedRenderMask maskRect={maskRect} /> : null}
{showMask ? (
{showMask ? (
<View style={styles.container}>
<AnimatedRenderMask maskRect={maskRect} />
<View style={[styles.tooltip, tooltipStyles, tooltipStyle]}>
<TooltipComponent labels={labels} maskRect={maskRect} />
</View>
) : null}
</View>
</View>
) : null}
</ModalWrapperForAlfredV2>
);
});

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useMemo, useRef } from 'react';
import { View, type NativeMethods } from 'react-native';
import { StyleSheet, View, type NativeMethods } from 'react-native';
import { useCopilot } from '../contexts/CopilotProvider';
import { GenericStyles, SCREEN_HEIGHT, SCREEN_WIDTH } from '@rn-ui-lib/styles';
import { CopilotStepProps } from '../types';
@@ -97,22 +97,17 @@ export const CopilotStep = ({
if (!isNoHighlightAreaStepActive) {
return null;
}
return (
<View
style={[
GenericStyles.centerAlignedRow,
{
width: SCREEN_WIDTH,
height: SCREEN_HEIGHT,
position: 'absolute',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
]}
>
{children}
</View>
);
return <View style={[GenericStyles.centerAlignedRow, styles.wrapper]}>{children}</View>;
}
return React.cloneElement(children, { ...copilotProps, ref: wrapperRef });
};
const styles = StyleSheet.create({
wrapper: {
width: SCREEN_WIDTH,
height: SCREEN_HEIGHT,
position: 'absolute',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
});

View File

@@ -24,7 +24,7 @@ export const Tooltip: React.FC<ITooltip> = ({ labels }) => {
useEffect(() => {
if (currentStepNumber) {
tooltipOpacity.value = 0;
tooltipOpacity.value = withTiming(1, { duration: 1000 });
tooltipOpacity.value = withTiming(1, { duration: 700 });
}
}, [currentStepNumber]);
@@ -50,7 +50,7 @@ export const Tooltip: React.FC<ITooltip> = ({ labels }) => {
};
return (
<Animated.View style={[animatedStyle]}>
<Animated.View style={[animatedStyle, GenericStyles.ph16]}>
<Text testID="stepDescription" style={styles.tooltipText}>
{currentStep?.text}
</Text>
@@ -59,7 +59,7 @@ export const Tooltip: React.FC<ITooltip> = ({ labels }) => {
GenericStyles.row,
GenericStyles.alignCenter,
GenericStyles.mt16,
{ alignSelf: 'flex-end' },
GenericStyles.spaceBetween,
]}
>
{totalStepsNumber > 1 ? (
@@ -67,14 +67,7 @@ export const Tooltip: React.FC<ITooltip> = ({ labels }) => {
{currentStepNumber}/{totalStepsNumber}
</Text>
) : null}
<View style={[GenericStyles.row, GenericStyles.mh12]}>
<Button
onPress={handleStop}
title={isLastStep ? labels?.finish : labels?.skip}
style={GenericStyles.mr10}
buttonStyle={styles.nextBtn}
pressableWidthChange={false}
/>
<View style={[GenericStyles.row]}>
{!isFirstStep ? (
<Button
variant="primaryText"
@@ -87,6 +80,15 @@ export const Tooltip: React.FC<ITooltip> = ({ labels }) => {
underlayColor="transparent"
/>
) : null}
{isLastStep ? (
<Button
onPress={handleStop}
title={labels?.finish}
style={GenericStyles.mr10}
buttonStyle={styles.nextBtn}
pressableWidthChange={false}
/>
) : null}
{!isLastStep ? (
<Button
onPress={handleNext}

View File

@@ -27,7 +27,6 @@ export const styles = StyleSheet.create({
color: COLORS.TEXT.WHITE,
fontSize: 16,
fontWeight: '700',
marginHorizontal: 20,
},
nextBtn: {
paddingHorizontal: 21,

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useEffect } from 'react';
import React, { useEffect, useRef } from 'react';
import { ScrollView, TouchableOpacity, View } from 'react-native';
import { GenericStyles } from '../../../../../RN-UI-LIB/src/styles';
import Heading from '../../../../../RN-UI-LIB/src/components/Heading';
@@ -36,6 +36,7 @@ const FiltersContainer: React.FC<FilterContainerProps> = (props) => {
const selectedFilters = useAppSelector((state: RootState) =>
getSelectedFilters(state, isAgentDashboard, isVisitPlan)
);
const onLayoutHandled = useRef(false);
const [selectedFiltersMap, setSelectedFiltersMap] =
React.useState<Record<string, any>>(selectedFilters);
const filterGroupKeys = Object.keys(filters);
@@ -108,7 +109,9 @@ const FiltersContainer: React.FC<FilterContainerProps> = (props) => {
};
const startCoachMark = async () => {
if(onLayoutHandled.current) return;
if (userId) {
onLayoutHandled.current = true;
showCoachMark(userId, serverTimestamp, copilot.start);
}
};
@@ -132,7 +135,7 @@ const FiltersContainer: React.FC<FilterContainerProps> = (props) => {
};
return (
<View style={[GenericStyles.fill, { flex: 1 }]} onLayout={startCoachMark}>
<View style={GenericStyles.fill} onLayout={startCoachMark}>
<View
style={[
GenericStyles.row,
@@ -204,7 +207,7 @@ const FiltersContainer: React.FC<FilterContainerProps> = (props) => {
text={ENABLE_COACHMARK[filterKey]?.description}
>
<Text
style={[filterKey === selectedFilterKey.filterKey && styles.blueText]}
style={[filterKey === selectedFilterKey.filterKey && styles.blueText, GenericStyles.flex80]}
dark
>
{filters[filterGroupKey].filters[filterKey].displayText}
@@ -212,7 +215,7 @@ const FiltersContainer: React.FC<FilterContainerProps> = (props) => {
</CopilotStep>
) : (
<Text
style={[filterKey === selectedFilterKey.filterKey && styles.blueText]}
style={[filterKey === selectedFilterKey.filterKey && styles.blueText, GenericStyles.flex80]}
dark
>
{filters[filterGroupKey].filters[filterKey].displayText}

View File

@@ -4,11 +4,11 @@ export const ENABLE_COACHMARK: Record<string, ICoachMark> = {
CURRENT_MONTH_INTERACTION_STATUS: {
key: 'CURRENT_MONTH_INTERACTION_STATUS',
order: 1,
description: '👆 You can find latest feedbacks in current month status',
description: '👆 You can find the priority feedback of current month in Current Month Status',
},
LAST_MONTH_INTERACTION_STATUS: {
key: 'LAST_MONTH_INTERACTION_STATUS',
order: 2,
description: "👆 You can find last month's feedbacks here",
description: "👆 You can find the priority feedback of last month in Last Month Status",
},
};