@intentai/react 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +150 -6
- package/dist/index.d.ts +150 -6
- package/dist/index.js +404 -16
- package/dist/index.mjs +398 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21,13 +21,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/index.tsx
|
|
22
22
|
var index_exports = {};
|
|
23
23
|
__export(index_exports, {
|
|
24
|
+
FeedbackButton: () => FeedbackButton,
|
|
25
|
+
IntentAIProvider: () => IntentAIProvider,
|
|
24
26
|
IntentAIWidget: () => IntentAIWidget,
|
|
25
27
|
PremiumVoiceWidget: () => PremiumVoiceWidget,
|
|
26
28
|
default: () => index_default,
|
|
27
|
-
|
|
29
|
+
useIdentify: () => useIdentify,
|
|
30
|
+
useIntentAI: () => useIntentAI,
|
|
31
|
+
useSetMetadata: () => useSetMetadata,
|
|
32
|
+
useWidgetControls: () => useWidgetControls
|
|
28
33
|
});
|
|
29
34
|
module.exports = __toCommonJS(index_exports);
|
|
30
|
-
var
|
|
35
|
+
var import_react4 = require("react");
|
|
31
36
|
|
|
32
37
|
// src/components/PremiumVoiceWidget.tsx
|
|
33
38
|
var import_react = require("react");
|
|
@@ -116,15 +121,33 @@ var useAudioLevel = (isRecording) => {
|
|
|
116
121
|
const [audioLevel, setAudioLevel] = (0, import_react.useState)(0);
|
|
117
122
|
const analyserRef = (0, import_react.useRef)(null);
|
|
118
123
|
const animationRef = (0, import_react.useRef)();
|
|
124
|
+
const streamRef = (0, import_react.useRef)(null);
|
|
125
|
+
const audioContextRef = (0, import_react.useRef)(null);
|
|
119
126
|
(0, import_react.useEffect)(() => {
|
|
120
127
|
if (!isRecording) {
|
|
121
128
|
setAudioLevel(0);
|
|
129
|
+
if (animationRef.current) {
|
|
130
|
+
cancelAnimationFrame(animationRef.current);
|
|
131
|
+
animationRef.current = void 0;
|
|
132
|
+
}
|
|
133
|
+
if (streamRef.current) {
|
|
134
|
+
streamRef.current.getTracks().forEach((track) => track.stop());
|
|
135
|
+
streamRef.current = null;
|
|
136
|
+
}
|
|
137
|
+
if (audioContextRef.current && audioContextRef.current.state !== "closed") {
|
|
138
|
+
audioContextRef.current.close().catch(() => {
|
|
139
|
+
});
|
|
140
|
+
audioContextRef.current = null;
|
|
141
|
+
}
|
|
142
|
+
analyserRef.current = null;
|
|
122
143
|
return;
|
|
123
144
|
}
|
|
124
145
|
const initAudio = async () => {
|
|
125
146
|
try {
|
|
126
147
|
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
148
|
+
streamRef.current = stream;
|
|
127
149
|
const audioContext = new AudioContext();
|
|
150
|
+
audioContextRef.current = audioContext;
|
|
128
151
|
const source = audioContext.createMediaStreamSource(stream);
|
|
129
152
|
const analyser = audioContext.createAnalyser();
|
|
130
153
|
analyser.fftSize = 256;
|
|
@@ -148,6 +171,13 @@ var useAudioLevel = (isRecording) => {
|
|
|
148
171
|
if (animationRef.current) {
|
|
149
172
|
cancelAnimationFrame(animationRef.current);
|
|
150
173
|
}
|
|
174
|
+
if (streamRef.current) {
|
|
175
|
+
streamRef.current.getTracks().forEach((track) => track.stop());
|
|
176
|
+
}
|
|
177
|
+
if (audioContextRef.current && audioContextRef.current.state !== "closed") {
|
|
178
|
+
audioContextRef.current.close().catch(() => {
|
|
179
|
+
});
|
|
180
|
+
}
|
|
151
181
|
};
|
|
152
182
|
}, [isRecording]);
|
|
153
183
|
return audioLevel;
|
|
@@ -367,12 +397,12 @@ var AmbientOrb = ({ audioLevel, isRecording }) => {
|
|
|
367
397
|
]
|
|
368
398
|
}
|
|
369
399
|
) }),
|
|
370
|
-
particles.map((particle) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
400
|
+
particles.filter((p) => p.size != null).map((particle) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
371
401
|
import_framer_motion.motion.circle,
|
|
372
402
|
{
|
|
373
403
|
cx: 70,
|
|
374
404
|
cy: 70,
|
|
375
|
-
r: particle.size,
|
|
405
|
+
r: particle.size || 3,
|
|
376
406
|
fill: particle.color,
|
|
377
407
|
initial: { opacity: 0.8, scale: 1 },
|
|
378
408
|
animate: {
|
|
@@ -1619,6 +1649,359 @@ function adjustColor(color, amount) {
|
|
|
1619
1649
|
return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0")}`;
|
|
1620
1650
|
}
|
|
1621
1651
|
|
|
1652
|
+
// src/components/IntentAIProvider.tsx
|
|
1653
|
+
var import_react2 = require("react");
|
|
1654
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1655
|
+
var IntentAIContext = (0, import_react2.createContext)(null);
|
|
1656
|
+
function useIntentAI() {
|
|
1657
|
+
const context = (0, import_react2.useContext)(IntentAIContext);
|
|
1658
|
+
if (!context) {
|
|
1659
|
+
throw new Error("useIntentAI must be used within an IntentAIProvider");
|
|
1660
|
+
}
|
|
1661
|
+
return context;
|
|
1662
|
+
}
|
|
1663
|
+
function generateSessionId() {
|
|
1664
|
+
return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
1665
|
+
}
|
|
1666
|
+
function getDeviceInfo() {
|
|
1667
|
+
const ua = navigator.userAgent;
|
|
1668
|
+
let browser = "Unknown";
|
|
1669
|
+
let browserVersion = "Unknown";
|
|
1670
|
+
if (ua.includes("Firefox/")) {
|
|
1671
|
+
browser = "Firefox";
|
|
1672
|
+
const match = ua.match(/Firefox\/(\d+(\.\d+)?)/);
|
|
1673
|
+
if (match) browserVersion = match[1];
|
|
1674
|
+
} else if (ua.includes("Edg/")) {
|
|
1675
|
+
browser = "Edge";
|
|
1676
|
+
const match = ua.match(/Edg\/(\d+(\.\d+)?)/);
|
|
1677
|
+
if (match) browserVersion = match[1];
|
|
1678
|
+
} else if (ua.includes("Chrome/")) {
|
|
1679
|
+
browser = "Chrome";
|
|
1680
|
+
const match = ua.match(/Chrome\/(\d+(\.\d+)?)/);
|
|
1681
|
+
if (match) browserVersion = match[1];
|
|
1682
|
+
} else if (ua.includes("Safari/") && !ua.includes("Chrome")) {
|
|
1683
|
+
browser = "Safari";
|
|
1684
|
+
const match = ua.match(/Version\/(\d+(\.\d+)?)/);
|
|
1685
|
+
if (match) browserVersion = match[1];
|
|
1686
|
+
}
|
|
1687
|
+
let os = "Unknown";
|
|
1688
|
+
if (ua.includes("Windows NT 10")) os = "Windows 10";
|
|
1689
|
+
else if (ua.includes("Windows")) os = "Windows";
|
|
1690
|
+
else if (ua.includes("Mac OS X")) os = "macOS";
|
|
1691
|
+
else if (ua.includes("Android")) os = "Android";
|
|
1692
|
+
else if (ua.includes("iPhone") || ua.includes("iPad")) os = "iOS";
|
|
1693
|
+
else if (ua.includes("Linux")) os = "Linux";
|
|
1694
|
+
let device = "Desktop";
|
|
1695
|
+
if (/iPhone|iPad|iPod/.test(ua)) device = "iOS Device";
|
|
1696
|
+
else if (/Android.*Mobile/.test(ua)) device = "Android Phone";
|
|
1697
|
+
else if (/Android/.test(ua)) device = "Android Tablet";
|
|
1698
|
+
return { browser, browserVersion, os, device };
|
|
1699
|
+
}
|
|
1700
|
+
var DEFAULT_API_URL = "https://api-production-5b88.up.railway.app";
|
|
1701
|
+
function IntentAIProvider({
|
|
1702
|
+
apiKey,
|
|
1703
|
+
apiUrl = DEFAULT_API_URL,
|
|
1704
|
+
user: initialUser,
|
|
1705
|
+
metadata: initialMetadata,
|
|
1706
|
+
widgetConfig,
|
|
1707
|
+
children,
|
|
1708
|
+
disableWidget = false,
|
|
1709
|
+
onFeedbackSubmitted,
|
|
1710
|
+
onError
|
|
1711
|
+
}) {
|
|
1712
|
+
const userRef = (0, import_react2.useRef)(initialUser);
|
|
1713
|
+
const metadataRef = (0, import_react2.useRef)(initialMetadata || {});
|
|
1714
|
+
const sessionIdRef = (0, import_react2.useRef)(generateSessionId());
|
|
1715
|
+
(0, import_react2.useEffect)(() => {
|
|
1716
|
+
if (initialUser) {
|
|
1717
|
+
userRef.current = initialUser;
|
|
1718
|
+
}
|
|
1719
|
+
}, [initialUser]);
|
|
1720
|
+
(0, import_react2.useEffect)(() => {
|
|
1721
|
+
if (initialMetadata) {
|
|
1722
|
+
metadataRef.current = { ...metadataRef.current, ...initialMetadata };
|
|
1723
|
+
}
|
|
1724
|
+
}, [initialMetadata]);
|
|
1725
|
+
const identify = (0, import_react2.useCallback)((user) => {
|
|
1726
|
+
userRef.current = { ...userRef.current, ...user };
|
|
1727
|
+
}, []);
|
|
1728
|
+
const setMetadata = (0, import_react2.useCallback)((metadata) => {
|
|
1729
|
+
metadataRef.current = { ...metadataRef.current, ...metadata };
|
|
1730
|
+
}, []);
|
|
1731
|
+
const clearUser = (0, import_react2.useCallback)(() => {
|
|
1732
|
+
userRef.current = void 0;
|
|
1733
|
+
}, []);
|
|
1734
|
+
const handleSubmit = (0, import_react2.useCallback)(async (feedback) => {
|
|
1735
|
+
const deviceInfo = getDeviceInfo();
|
|
1736
|
+
const user = userRef.current;
|
|
1737
|
+
const customMetadata = metadataRef.current;
|
|
1738
|
+
const categoryMap = {
|
|
1739
|
+
bug: "BUG",
|
|
1740
|
+
feature: "FEATURE",
|
|
1741
|
+
improvement: "IMPROVEMENT",
|
|
1742
|
+
praise: "PRAISE",
|
|
1743
|
+
other: "OTHER"
|
|
1744
|
+
};
|
|
1745
|
+
const payload = {
|
|
1746
|
+
sessionId: sessionIdRef.current,
|
|
1747
|
+
type: feedback.type === "voice" ? "VOICE" : "TEXT",
|
|
1748
|
+
category: categoryMap[feedback.category.toLowerCase()] || feedback.category.toUpperCase(),
|
|
1749
|
+
rawText: feedback.type === "text" ? feedback.content : void 0,
|
|
1750
|
+
transcription: feedback.type === "voice" ? feedback.transcription || feedback.content : void 0,
|
|
1751
|
+
pageUrl: typeof window !== "undefined" ? window.location.href : "",
|
|
1752
|
+
pageTitle: typeof document !== "undefined" ? document.title : "",
|
|
1753
|
+
userId: user?.id,
|
|
1754
|
+
userEmail: user?.email,
|
|
1755
|
+
userName: user?.name,
|
|
1756
|
+
customData: {
|
|
1757
|
+
...customMetadata,
|
|
1758
|
+
...feedback.metadata
|
|
1759
|
+
},
|
|
1760
|
+
browser: deviceInfo.browser,
|
|
1761
|
+
browserVersion: deviceInfo.browserVersion,
|
|
1762
|
+
os: deviceInfo.os,
|
|
1763
|
+
device: deviceInfo.device,
|
|
1764
|
+
screenWidth: typeof window !== "undefined" ? window.screen.width : void 0,
|
|
1765
|
+
screenHeight: typeof window !== "undefined" ? window.screen.height : void 0
|
|
1766
|
+
};
|
|
1767
|
+
try {
|
|
1768
|
+
const response = await fetch(`${apiUrl}/feedback`, {
|
|
1769
|
+
method: "POST",
|
|
1770
|
+
headers: {
|
|
1771
|
+
"Content-Type": "application/json",
|
|
1772
|
+
"X-API-Key": apiKey
|
|
1773
|
+
},
|
|
1774
|
+
body: JSON.stringify(payload)
|
|
1775
|
+
});
|
|
1776
|
+
if (!response.ok) {
|
|
1777
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1778
|
+
throw new Error(errorData.error || `Failed to submit feedback: ${response.status}`);
|
|
1779
|
+
}
|
|
1780
|
+
onFeedbackSubmitted?.();
|
|
1781
|
+
} catch (error) {
|
|
1782
|
+
const err = error instanceof Error ? error : new Error("Failed to submit feedback");
|
|
1783
|
+
onError?.(err);
|
|
1784
|
+
throw err;
|
|
1785
|
+
}
|
|
1786
|
+
}, [apiKey, apiUrl, onFeedbackSubmitted, onError]);
|
|
1787
|
+
const contextValue = (0, import_react2.useMemo)(() => ({
|
|
1788
|
+
identify,
|
|
1789
|
+
setMetadata,
|
|
1790
|
+
clearUser,
|
|
1791
|
+
isConfigured: Boolean(apiKey)
|
|
1792
|
+
}), [identify, setMetadata, clearUser, apiKey]);
|
|
1793
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(IntentAIContext.Provider, { value: contextValue, children: [
|
|
1794
|
+
children,
|
|
1795
|
+
!disableWidget && apiKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1796
|
+
PremiumVoiceWidget,
|
|
1797
|
+
{
|
|
1798
|
+
...widgetConfig,
|
|
1799
|
+
onSubmit: handleSubmit
|
|
1800
|
+
}
|
|
1801
|
+
)
|
|
1802
|
+
] });
|
|
1803
|
+
}
|
|
1804
|
+
function useIdentify() {
|
|
1805
|
+
const { identify } = useIntentAI();
|
|
1806
|
+
return identify;
|
|
1807
|
+
}
|
|
1808
|
+
function useSetMetadata() {
|
|
1809
|
+
const { setMetadata } = useIntentAI();
|
|
1810
|
+
return setMetadata;
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
// src/components/FeedbackButton.tsx
|
|
1814
|
+
var import_react3 = require("react");
|
|
1815
|
+
var import_framer_motion2 = require("framer-motion");
|
|
1816
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1817
|
+
var FeedbackIcon = ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1818
|
+
"svg",
|
|
1819
|
+
{
|
|
1820
|
+
width: size,
|
|
1821
|
+
height: size,
|
|
1822
|
+
viewBox: "0 0 24 24",
|
|
1823
|
+
fill: "none",
|
|
1824
|
+
stroke: "currentColor",
|
|
1825
|
+
strokeWidth: "2",
|
|
1826
|
+
strokeLinecap: "round",
|
|
1827
|
+
strokeLinejoin: "round",
|
|
1828
|
+
children: [
|
|
1829
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }),
|
|
1830
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "9", cy: "10", r: "1", fill: "currentColor" }),
|
|
1831
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "15", cy: "10", r: "1", fill: "currentColor" })
|
|
1832
|
+
]
|
|
1833
|
+
}
|
|
1834
|
+
);
|
|
1835
|
+
function FeedbackButton({
|
|
1836
|
+
variant = "primary",
|
|
1837
|
+
size = "md",
|
|
1838
|
+
showIcon = true,
|
|
1839
|
+
icon,
|
|
1840
|
+
label = "Feedback",
|
|
1841
|
+
className,
|
|
1842
|
+
style,
|
|
1843
|
+
primaryColor = "#10b981",
|
|
1844
|
+
onClick,
|
|
1845
|
+
disabled = false
|
|
1846
|
+
}) {
|
|
1847
|
+
const [isHovered, setIsHovered] = (0, import_react3.useState)(false);
|
|
1848
|
+
const [isPressed, setIsPressed] = (0, import_react3.useState)(false);
|
|
1849
|
+
const buttonRef = (0, import_react3.useRef)(null);
|
|
1850
|
+
const sizes = {
|
|
1851
|
+
sm: {
|
|
1852
|
+
padding: "8px 14px",
|
|
1853
|
+
fontSize: 13,
|
|
1854
|
+
iconSize: 14,
|
|
1855
|
+
gap: 6,
|
|
1856
|
+
borderRadius: 8
|
|
1857
|
+
},
|
|
1858
|
+
md: {
|
|
1859
|
+
padding: "10px 18px",
|
|
1860
|
+
fontSize: 14,
|
|
1861
|
+
iconSize: 16,
|
|
1862
|
+
gap: 8,
|
|
1863
|
+
borderRadius: 10
|
|
1864
|
+
},
|
|
1865
|
+
lg: {
|
|
1866
|
+
padding: "14px 24px",
|
|
1867
|
+
fontSize: 15,
|
|
1868
|
+
iconSize: 18,
|
|
1869
|
+
gap: 10,
|
|
1870
|
+
borderRadius: 12
|
|
1871
|
+
}
|
|
1872
|
+
};
|
|
1873
|
+
const sizeConfig = sizes[size];
|
|
1874
|
+
const variants = {
|
|
1875
|
+
primary: {
|
|
1876
|
+
background: `linear-gradient(145deg, ${primaryColor} 0%, ${adjustColor2(primaryColor, -20)} 100%)`,
|
|
1877
|
+
color: "white",
|
|
1878
|
+
border: "none",
|
|
1879
|
+
boxShadow: `0 4px 16px -4px ${primaryColor}66, 0 2px 4px rgba(0, 0, 0, 0.1)`
|
|
1880
|
+
},
|
|
1881
|
+
secondary: {
|
|
1882
|
+
background: "white",
|
|
1883
|
+
color: "#374151",
|
|
1884
|
+
border: "1px solid #e5e7eb",
|
|
1885
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.05)"
|
|
1886
|
+
},
|
|
1887
|
+
ghost: {
|
|
1888
|
+
background: "transparent",
|
|
1889
|
+
color: "#6b7280",
|
|
1890
|
+
border: "1px solid transparent",
|
|
1891
|
+
boxShadow: "none"
|
|
1892
|
+
},
|
|
1893
|
+
minimal: {
|
|
1894
|
+
background: "transparent",
|
|
1895
|
+
color: primaryColor,
|
|
1896
|
+
border: "none",
|
|
1897
|
+
boxShadow: "none"
|
|
1898
|
+
}
|
|
1899
|
+
};
|
|
1900
|
+
const variantStyle = variants[variant];
|
|
1901
|
+
const handleClick = (0, import_react3.useCallback)(() => {
|
|
1902
|
+
if (disabled) return;
|
|
1903
|
+
if (onClick) {
|
|
1904
|
+
onClick();
|
|
1905
|
+
return;
|
|
1906
|
+
}
|
|
1907
|
+
const widget = document.querySelector(".fiq-premium-widget");
|
|
1908
|
+
if (widget) {
|
|
1909
|
+
const trigger = widget.querySelector('button[aria-label="Open feedback widget"]');
|
|
1910
|
+
if (trigger) {
|
|
1911
|
+
trigger.click();
|
|
1912
|
+
return;
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
const scriptWidget = document.getElementById("feedbackiq-widget");
|
|
1916
|
+
if (scriptWidget?.shadowRoot) {
|
|
1917
|
+
const trigger = scriptWidget.shadowRoot.querySelector(".fiq-trigger");
|
|
1918
|
+
if (trigger) {
|
|
1919
|
+
trigger.click();
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
}, [onClick, disabled]);
|
|
1923
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1924
|
+
import_framer_motion2.motion.button,
|
|
1925
|
+
{
|
|
1926
|
+
ref: buttonRef,
|
|
1927
|
+
onClick: handleClick,
|
|
1928
|
+
onMouseEnter: () => setIsHovered(true),
|
|
1929
|
+
onMouseLeave: () => {
|
|
1930
|
+
setIsHovered(false);
|
|
1931
|
+
setIsPressed(false);
|
|
1932
|
+
},
|
|
1933
|
+
onMouseDown: () => setIsPressed(true),
|
|
1934
|
+
onMouseUp: () => setIsPressed(false),
|
|
1935
|
+
disabled,
|
|
1936
|
+
animate: {
|
|
1937
|
+
scale: isPressed ? 0.97 : isHovered ? 1.02 : 1,
|
|
1938
|
+
y: isHovered ? -1 : 0
|
|
1939
|
+
},
|
|
1940
|
+
transition: {
|
|
1941
|
+
type: "spring",
|
|
1942
|
+
stiffness: 400,
|
|
1943
|
+
damping: 25
|
|
1944
|
+
},
|
|
1945
|
+
className,
|
|
1946
|
+
style: {
|
|
1947
|
+
display: "inline-flex",
|
|
1948
|
+
alignItems: "center",
|
|
1949
|
+
justifyContent: "center",
|
|
1950
|
+
gap: sizeConfig.gap,
|
|
1951
|
+
padding: sizeConfig.padding,
|
|
1952
|
+
fontSize: sizeConfig.fontSize,
|
|
1953
|
+
fontWeight: 600,
|
|
1954
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
1955
|
+
borderRadius: sizeConfig.borderRadius,
|
|
1956
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
1957
|
+
opacity: disabled ? 0.5 : 1,
|
|
1958
|
+
transition: "all 0.2s ease",
|
|
1959
|
+
position: "relative",
|
|
1960
|
+
overflow: "hidden",
|
|
1961
|
+
...variantStyle,
|
|
1962
|
+
...style
|
|
1963
|
+
},
|
|
1964
|
+
children: [
|
|
1965
|
+
variant === "primary" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1966
|
+
import_framer_motion2.motion.div,
|
|
1967
|
+
{
|
|
1968
|
+
initial: { opacity: 0 },
|
|
1969
|
+
animate: { opacity: isHovered ? 0.1 : 0 },
|
|
1970
|
+
style: {
|
|
1971
|
+
position: "absolute",
|
|
1972
|
+
inset: 0,
|
|
1973
|
+
background: "white",
|
|
1974
|
+
pointerEvents: "none"
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
),
|
|
1978
|
+
variant === "primary" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1979
|
+
"div",
|
|
1980
|
+
{
|
|
1981
|
+
style: {
|
|
1982
|
+
position: "absolute",
|
|
1983
|
+
inset: 0,
|
|
1984
|
+
background: "linear-gradient(180deg, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0) 50%)",
|
|
1985
|
+
borderRadius: "inherit",
|
|
1986
|
+
pointerEvents: "none"
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
),
|
|
1990
|
+
showIcon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { display: "flex", alignItems: "center", position: "relative", zIndex: 1 }, children: icon || /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FeedbackIcon, { size: sizeConfig.iconSize }) }),
|
|
1991
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { position: "relative", zIndex: 1 }, children: label })
|
|
1992
|
+
]
|
|
1993
|
+
}
|
|
1994
|
+
);
|
|
1995
|
+
}
|
|
1996
|
+
function adjustColor2(color, amount) {
|
|
1997
|
+
const hex = color.replace("#", "");
|
|
1998
|
+
const num = parseInt(hex, 16);
|
|
1999
|
+
const r = Math.min(255, Math.max(0, (num >> 16) + amount));
|
|
2000
|
+
const g = Math.min(255, Math.max(0, (num >> 8 & 255) + amount));
|
|
2001
|
+
const b = Math.min(255, Math.max(0, (num & 255) + amount));
|
|
2002
|
+
return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0")}`;
|
|
2003
|
+
}
|
|
2004
|
+
|
|
1622
2005
|
// src/index.tsx
|
|
1623
2006
|
function IntentAIWidget({
|
|
1624
2007
|
apiKey,
|
|
@@ -1637,9 +2020,9 @@ function IntentAIWidget({
|
|
|
1637
2020
|
onFeedbackSubmitted: _onFeedbackSubmitted,
|
|
1638
2021
|
onError
|
|
1639
2022
|
}) {
|
|
1640
|
-
const widgetRef = (0,
|
|
1641
|
-
const scriptLoadedRef = (0,
|
|
1642
|
-
const initWidget = (0,
|
|
2023
|
+
const widgetRef = (0, import_react4.useRef)(null);
|
|
2024
|
+
const scriptLoadedRef = (0, import_react4.useRef)(false);
|
|
2025
|
+
const initWidget = (0, import_react4.useCallback)(() => {
|
|
1643
2026
|
if (!window.FeedbackIQ || widgetRef.current) return;
|
|
1644
2027
|
try {
|
|
1645
2028
|
widgetRef.current = new window.FeedbackIQ({
|
|
@@ -1662,7 +2045,7 @@ function IntentAIWidget({
|
|
|
1662
2045
|
void _onClose;
|
|
1663
2046
|
void _onFeedbackSubmitted;
|
|
1664
2047
|
}, [apiKey, apiUrl, widgetUrl, position, theme, primaryColor, allowVoice, allowText, allowScreenshot, customMetadata, user, onError]);
|
|
1665
|
-
(0,
|
|
2048
|
+
(0, import_react4.useEffect)(() => {
|
|
1666
2049
|
if (!widgetUrl) {
|
|
1667
2050
|
onError?.(new Error("widgetUrl is required for IntentAIWidget"));
|
|
1668
2051
|
return;
|
|
@@ -1693,39 +2076,39 @@ function IntentAIWidget({
|
|
|
1693
2076
|
}
|
|
1694
2077
|
};
|
|
1695
2078
|
}, [initWidget, onError, widgetUrl]);
|
|
1696
|
-
(0,
|
|
2079
|
+
(0, import_react4.useEffect)(() => {
|
|
1697
2080
|
if (widgetRef.current && user) {
|
|
1698
2081
|
widgetRef.current.identify(user);
|
|
1699
2082
|
}
|
|
1700
2083
|
}, [user]);
|
|
1701
|
-
(0,
|
|
2084
|
+
(0, import_react4.useEffect)(() => {
|
|
1702
2085
|
if (widgetRef.current && customMetadata) {
|
|
1703
2086
|
widgetRef.current.setMetadata(customMetadata);
|
|
1704
2087
|
}
|
|
1705
2088
|
}, [customMetadata]);
|
|
1706
2089
|
return null;
|
|
1707
2090
|
}
|
|
1708
|
-
function
|
|
1709
|
-
const open = (0,
|
|
2091
|
+
function useWidgetControls() {
|
|
2092
|
+
const open = (0, import_react4.useCallback)(() => {
|
|
1710
2093
|
const widget = document.getElementById("feedbackiq-widget");
|
|
1711
2094
|
if (widget) {
|
|
1712
2095
|
const trigger = widget.shadowRoot?.querySelector(".fiq-trigger");
|
|
1713
2096
|
trigger?.click();
|
|
1714
2097
|
}
|
|
1715
2098
|
}, []);
|
|
1716
|
-
const close = (0,
|
|
2099
|
+
const close = (0, import_react4.useCallback)(() => {
|
|
1717
2100
|
const widget = document.getElementById("feedbackiq-widget");
|
|
1718
2101
|
if (widget) {
|
|
1719
2102
|
const closeBtn = widget.shadowRoot?.querySelector(".fiq-close");
|
|
1720
2103
|
closeBtn?.click();
|
|
1721
2104
|
}
|
|
1722
2105
|
}, []);
|
|
1723
|
-
const identify = (0,
|
|
2106
|
+
const identify = (0, import_react4.useCallback)((user) => {
|
|
1724
2107
|
if (window.IntentAI?.widget) {
|
|
1725
2108
|
window.IntentAI.widget.identify(user);
|
|
1726
2109
|
}
|
|
1727
2110
|
}, []);
|
|
1728
|
-
const setMetadata = (0,
|
|
2111
|
+
const setMetadata = (0, import_react4.useCallback)((metadata) => {
|
|
1729
2112
|
if (window.IntentAI?.widget) {
|
|
1730
2113
|
window.IntentAI.widget.setMetadata(metadata);
|
|
1731
2114
|
}
|
|
@@ -1735,7 +2118,12 @@ function useIntentAI() {
|
|
|
1735
2118
|
var index_default = IntentAIWidget;
|
|
1736
2119
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1737
2120
|
0 && (module.exports = {
|
|
2121
|
+
FeedbackButton,
|
|
2122
|
+
IntentAIProvider,
|
|
1738
2123
|
IntentAIWidget,
|
|
1739
2124
|
PremiumVoiceWidget,
|
|
1740
|
-
|
|
2125
|
+
useIdentify,
|
|
2126
|
+
useIntentAI,
|
|
2127
|
+
useSetMetadata,
|
|
2128
|
+
useWidgetControls
|
|
1741
2129
|
});
|