react-notify-sdk 1.0.62 → 1.0.64
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/FadeWrapper.d.ts
CHANGED
package/dist/FeatureMessage.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FeatureMessages } from './types';
|
|
2
2
|
interface FeatureMessageProps {
|
|
3
|
-
message: FeatureMessages;
|
|
3
|
+
message: FeatureMessages | null;
|
|
4
4
|
onDismiss?: (id: string) => void;
|
|
5
5
|
}
|
|
6
6
|
declare const FeatureMessage: ({ message, onDismiss }: FeatureMessageProps) => import("react/jsx-runtime").JSX.Element;
|
package/dist/FeatureMessage.js
CHANGED
|
@@ -31,16 +31,16 @@ const FeatureMessage = ({ message, onDismiss }) => {
|
|
|
31
31
|
if (e.target.closest('[data-dismiss-button]')) {
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
|
-
const action = message
|
|
34
|
+
const action = message?.click_action || 'none';
|
|
35
35
|
// Perform the action
|
|
36
36
|
switch (action) {
|
|
37
37
|
case 'navigate':
|
|
38
|
-
if (message
|
|
39
|
-
spaNavigate(message
|
|
38
|
+
if (message?.click_url) {
|
|
39
|
+
spaNavigate(message?.click_url);
|
|
40
40
|
}
|
|
41
41
|
break;
|
|
42
42
|
case 'external':
|
|
43
|
-
if (message
|
|
43
|
+
if (message?.click_url) {
|
|
44
44
|
window.open(message.click_url, '_blank', 'noopener,noreferrer');
|
|
45
45
|
}
|
|
46
46
|
break;
|
|
@@ -54,7 +54,7 @@ const FeatureMessage = ({ message, onDismiss }) => {
|
|
|
54
54
|
};
|
|
55
55
|
const handleDismiss = () => {
|
|
56
56
|
if (onDismiss) {
|
|
57
|
-
onDismiss(message.id);
|
|
57
|
+
onDismiss(message?.id ? message.id : '');
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
60
|
const filterButton = (type) => {
|
|
@@ -85,8 +85,8 @@ const FeatureMessage = ({ message, onDismiss }) => {
|
|
|
85
85
|
borderRadius: "0.5rem", // rounded-lg
|
|
86
86
|
backgroundColor: message?.backgroundColor,
|
|
87
87
|
borderWidth: "1px",
|
|
88
|
-
borderColor: hexToRgba(message?.borderColor, 0.3),
|
|
89
|
-
boxShadow: `0 10px 15px -3px ${hexToRgba(message
|
|
88
|
+
borderColor: hexToRgba(message?.borderColor ? message?.borderColor : '', 0.3),
|
|
89
|
+
boxShadow: `0 10px 15px -3px ${hexToRgba(message?.borderColor ? message?.borderColor : '', 0.4)}, 0 4px 6px -4px ${hexToRgba(message?.borderColor ? message?.borderColor : '', 0.4)}`
|
|
90
90
|
}, children: [_jsxs("div", { style: {
|
|
91
91
|
width: message?.click_action === "view only" ? "100%" : "80%", // w-4/5
|
|
92
92
|
height: "100%", // h-full
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { FeatureMessageProviderProps } from './types';
|
|
2
|
-
export declare const FeatureMessageProvider: ({ projectKey, }: FeatureMessageProviderProps) => import("react/jsx-runtime").JSX.Element
|
|
2
|
+
export declare const FeatureMessageProvider: ({ projectKey, }: FeatureMessageProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -6,8 +6,8 @@ import { getSupabaseClient } from './supabase/supabaseClient';
|
|
|
6
6
|
import useDeviceDetection from './useDeviceDetection';
|
|
7
7
|
import FadeWrapper from './FadeWrapper';
|
|
8
8
|
// Wildcard route matching utility
|
|
9
|
-
const routeMatches = (pattern, path
|
|
10
|
-
if (pattern === path
|
|
9
|
+
const routeMatches = (pattern, path) => {
|
|
10
|
+
if (pattern === path)
|
|
11
11
|
return true;
|
|
12
12
|
const escapeRegex = (str) => str.replace(/([.+^=!:${}()|[\]/\\])/g, "\\$1");
|
|
13
13
|
const regexPattern = "^" + pattern.split("*").map(escapeRegex).join(".*") + "$";
|
|
@@ -18,8 +18,16 @@ const routeMatches = (pattern, path, baseUrl) => {
|
|
|
18
18
|
return false;
|
|
19
19
|
}
|
|
20
20
|
};
|
|
21
|
+
const baseUrlMatches = (msgBaseUrl) => {
|
|
22
|
+
if (!msgBaseUrl)
|
|
23
|
+
return true; // backward compatibility
|
|
24
|
+
if (typeof window === "undefined")
|
|
25
|
+
return false;
|
|
26
|
+
return msgBaseUrl === window.location.origin;
|
|
27
|
+
};
|
|
21
28
|
export const FeatureMessageProvider = ({ projectKey, }) => {
|
|
22
29
|
const [message, setMessage] = useState(null);
|
|
30
|
+
const [messages, setMessages] = useState([]);
|
|
23
31
|
const [visible, setVisible] = useState(false);
|
|
24
32
|
const [pathname, setPathname] = useState(() => typeof window !== 'undefined' ? window.location.pathname : '');
|
|
25
33
|
const device = useDeviceDetection();
|
|
@@ -48,11 +56,11 @@ export const FeatureMessageProvider = ({ projectKey, }) => {
|
|
|
48
56
|
setVisible(false);
|
|
49
57
|
};
|
|
50
58
|
const isDismissed = (message) => {
|
|
51
|
-
const dismissed = getDismissedMessages()[message
|
|
59
|
+
const dismissed = getDismissedMessages()[message?.id];
|
|
52
60
|
if (!dismissed)
|
|
53
61
|
return false;
|
|
54
62
|
// Re-show if message changed
|
|
55
|
-
return dismissed.messageUpdatedAt === message
|
|
63
|
+
return dismissed.messageUpdatedAt === message?.updated_at;
|
|
56
64
|
};
|
|
57
65
|
// Create supabase client with project key header
|
|
58
66
|
const supabaseClient = getSupabaseClient(projectKey);
|
|
@@ -87,58 +95,75 @@ export const FeatureMessageProvider = ({ projectKey, }) => {
|
|
|
87
95
|
if (typeof window === 'undefined')
|
|
88
96
|
return; // Skip on server
|
|
89
97
|
let fadeOutTimer = null; // Track the timer
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
fadeOutTimer = setTimeout(() => setMessage(null), 300);
|
|
110
|
-
setVisible(false);
|
|
111
|
-
console.log("match not set");
|
|
98
|
+
const origin = window.location.origin;
|
|
99
|
+
// 🔹 1. Fetch ALL active messages once per project
|
|
100
|
+
const fetchMessages = async () => {
|
|
101
|
+
const response = await fetch("https://dhgnstjrkeuqnsapwcec.functions.supabase.co/get-feature-message", {
|
|
102
|
+
method: "POST",
|
|
103
|
+
headers: {
|
|
104
|
+
"Content-Type": "application/json",
|
|
105
|
+
},
|
|
106
|
+
body: JSON.stringify({
|
|
107
|
+
projectKey,
|
|
108
|
+
pathname: pathname,
|
|
109
|
+
origin: origin,
|
|
110
|
+
}),
|
|
111
|
+
});
|
|
112
|
+
if (!response.ok)
|
|
113
|
+
return null;
|
|
114
|
+
const data = await response.json();
|
|
115
|
+
if (data) {
|
|
116
|
+
setMessages(data);
|
|
112
117
|
}
|
|
113
118
|
};
|
|
114
|
-
|
|
119
|
+
fetchMessages();
|
|
120
|
+
// 🔹 2. Subscribe ONCE per project
|
|
115
121
|
const subscription = supabaseClient
|
|
116
|
-
.channel(
|
|
117
|
-
.on(
|
|
118
|
-
event: '*',
|
|
119
|
-
schema: 'public',
|
|
120
|
-
table: 'feature_messages',
|
|
121
|
-
}, (payload) => {
|
|
122
|
+
.channel("feature_messages_channel")
|
|
123
|
+
.on("postgres_changes", { event: "*", schema: "public", table: "feature_messages" }, (payload) => {
|
|
122
124
|
const msg = payload.new;
|
|
123
|
-
if (msg.project_key
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
console.log("does not render message");
|
|
133
|
-
fadeOutTimer = setTimeout(() => setMessage(null), 300);
|
|
134
|
-
}
|
|
125
|
+
if (msg.project_key !== projectKey)
|
|
126
|
+
return;
|
|
127
|
+
setMessages((prev) => {
|
|
128
|
+
const filtered = prev.filter((m) => m.id !== msg.id);
|
|
129
|
+
if (msg.is_active) {
|
|
130
|
+
return [msg, ...filtered];
|
|
131
|
+
}
|
|
132
|
+
return filtered;
|
|
133
|
+
});
|
|
135
134
|
})
|
|
136
135
|
.subscribe();
|
|
137
136
|
return () => {
|
|
137
|
+
if (fadeOutTimer)
|
|
138
|
+
clearTimeout(fadeOutTimer);
|
|
138
139
|
supabaseClient.removeChannel(subscription);
|
|
139
140
|
};
|
|
140
|
-
}, [
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
}, [projectKey]);
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
if (!pathname || !messages.length)
|
|
144
|
+
return;
|
|
145
|
+
let fadeOutTimer = null;
|
|
146
|
+
const origin = typeof window !== "undefined" ? window.location.origin : "";
|
|
147
|
+
const match = messages.find((msg) => routeMatches(msg.route, pathname) &&
|
|
148
|
+
baseUrlMatches(msg.base_url) &&
|
|
149
|
+
!isDismissed(msg));
|
|
150
|
+
if (match) {
|
|
151
|
+
if (fadeOutTimer)
|
|
152
|
+
clearTimeout(fadeOutTimer);
|
|
153
|
+
setMessage(match);
|
|
154
|
+
setVisible(true);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
setVisible(false);
|
|
158
|
+
fadeOutTimer = setTimeout(() => setMessage(null), 300);
|
|
159
|
+
}
|
|
160
|
+
return () => {
|
|
161
|
+
if (fadeOutTimer)
|
|
162
|
+
clearTimeout(fadeOutTimer);
|
|
163
|
+
};
|
|
164
|
+
}, [pathname, messages]);
|
|
165
|
+
return (_jsx(FadeWrapper, { visible: visible, device: device, message: message, children: _jsx(FeatureMessage, { message: message, onDismiss: () => {
|
|
166
|
+
if (message)
|
|
167
|
+
dismissMessage(message);
|
|
168
|
+
} }) }));
|
|
144
169
|
};
|