@sendoracloud/sdk-react-native 1.3.0 → 1.4.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/contact-widget.cjs +83 -2
- package/dist/contact-widget.d.cts +36 -1
- package/dist/contact-widget.d.ts +36 -1
- package/dist/contact-widget.js +80 -1
- package/package.json +1 -1
package/dist/contact-widget.cjs
CHANGED
|
@@ -31,7 +31,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var contact_widget_exports = {};
|
|
32
32
|
__export(contact_widget_exports, {
|
|
33
33
|
ContactWidget: () => ContactWidget,
|
|
34
|
-
|
|
34
|
+
TicketHistory: () => TicketHistory,
|
|
35
|
+
useContactWidget: () => useContactWidget,
|
|
36
|
+
useTicketHistory: () => useTicketHistory
|
|
35
37
|
});
|
|
36
38
|
module.exports = __toCommonJS(contact_widget_exports);
|
|
37
39
|
var React = __toESM(require("react"), 1);
|
|
@@ -134,8 +136,87 @@ function useContactWidget(widgetId, defaults) {
|
|
|
134
136
|
);
|
|
135
137
|
return { open, close, View: View2, lastResult };
|
|
136
138
|
}
|
|
139
|
+
function TicketHistory({
|
|
140
|
+
visible,
|
|
141
|
+
widgetId,
|
|
142
|
+
accessToken,
|
|
143
|
+
workerHost = "https://go.sendoracloud.com",
|
|
144
|
+
theme = "auto",
|
|
145
|
+
onClose
|
|
146
|
+
}) {
|
|
147
|
+
const didFire = React.useRef(false);
|
|
148
|
+
React.useEffect(() => {
|
|
149
|
+
if (visible) didFire.current = false;
|
|
150
|
+
}, [visible]);
|
|
151
|
+
if (!widgetId || !accessToken) return null;
|
|
152
|
+
const params = new URLSearchParams({ widgetId, theme });
|
|
153
|
+
const uri = `${workerHost}/embed/tickets?${params.toString()}#access=${encodeURIComponent(accessToken)}`;
|
|
154
|
+
const handleClose = (result) => {
|
|
155
|
+
if (didFire.current) return;
|
|
156
|
+
didFire.current = true;
|
|
157
|
+
onClose(result);
|
|
158
|
+
};
|
|
159
|
+
const onNav = (req) => {
|
|
160
|
+
const url = req.url || "";
|
|
161
|
+
if (url.startsWith("sendora://close")) {
|
|
162
|
+
handleClose({ ticketId: "", portalUrl: null, submitted: false });
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
if (!url.startsWith("https://") && !url.startsWith("about:")) return false;
|
|
166
|
+
return true;
|
|
167
|
+
};
|
|
168
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
169
|
+
import_react_native.Modal,
|
|
170
|
+
{
|
|
171
|
+
visible,
|
|
172
|
+
animationType: "slide",
|
|
173
|
+
presentationStyle: "pageSheet",
|
|
174
|
+
onRequestClose: () => handleClose({ ticketId: "", portalUrl: null, submitted: false }),
|
|
175
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
176
|
+
import_react_native_webview.WebView,
|
|
177
|
+
{
|
|
178
|
+
source: { uri },
|
|
179
|
+
onShouldStartLoadWithRequest: onNav,
|
|
180
|
+
originWhitelist: ["https://*", "about:*", "sendora://*"],
|
|
181
|
+
setSupportMultipleWindows: false,
|
|
182
|
+
javaScriptEnabled: true,
|
|
183
|
+
domStorageEnabled: true,
|
|
184
|
+
allowsBackForwardNavigationGestures: false
|
|
185
|
+
}
|
|
186
|
+
) })
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
function useTicketHistory(widgetId, getAccessToken, defaults) {
|
|
191
|
+
const [visible, setVisible] = React.useState(false);
|
|
192
|
+
const [token, setToken] = React.useState(null);
|
|
193
|
+
const open = React.useCallback(async () => {
|
|
194
|
+
const t = await getAccessToken();
|
|
195
|
+
if (!t) return;
|
|
196
|
+
setToken(t);
|
|
197
|
+
setVisible(true);
|
|
198
|
+
}, [getAccessToken]);
|
|
199
|
+
const close = React.useCallback(() => setVisible(false), []);
|
|
200
|
+
const View2 = React.useCallback(
|
|
201
|
+
() => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
202
|
+
TicketHistory,
|
|
203
|
+
{
|
|
204
|
+
widgetId,
|
|
205
|
+
visible,
|
|
206
|
+
accessToken: token,
|
|
207
|
+
workerHost: defaults?.workerHost,
|
|
208
|
+
theme: defaults?.theme,
|
|
209
|
+
onClose: () => setVisible(false)
|
|
210
|
+
}
|
|
211
|
+
),
|
|
212
|
+
[widgetId, visible, token, defaults]
|
|
213
|
+
);
|
|
214
|
+
return { open, close, View: View2 };
|
|
215
|
+
}
|
|
137
216
|
// Annotate the CommonJS export names for ESM import in node:
|
|
138
217
|
0 && (module.exports = {
|
|
139
218
|
ContactWidget,
|
|
140
|
-
|
|
219
|
+
TicketHistory,
|
|
220
|
+
useContactWidget,
|
|
221
|
+
useTicketHistory
|
|
141
222
|
});
|
|
@@ -99,5 +99,40 @@ declare function useContactWidget(widgetId: string, defaults?: Omit<ContactWidge
|
|
|
99
99
|
View: () => React.ReactElement | null;
|
|
100
100
|
lastResult: ContactWidgetResult | null;
|
|
101
101
|
};
|
|
102
|
+
interface TicketHistoryProps {
|
|
103
|
+
/** Whether the modal sheet is visible. */
|
|
104
|
+
visible: boolean;
|
|
105
|
+
/** Widget UUID that scopes the org. */
|
|
106
|
+
widgetId: string;
|
|
107
|
+
/**
|
|
108
|
+
* Current SDK access token (from `SendoraCloud.auth.getAccessToken()`).
|
|
109
|
+
* Passed in the URL hash fragment so it never appears in server
|
|
110
|
+
* logs / referer headers. Embed scrubs the hash on load.
|
|
111
|
+
* The widget is no-op when this is null/empty.
|
|
112
|
+
*/
|
|
113
|
+
accessToken: string | null | undefined;
|
|
114
|
+
workerHost?: string;
|
|
115
|
+
theme?: "auto" | "light" | "dark";
|
|
116
|
+
onClose: (result: ContactWidgetResult) => void;
|
|
117
|
+
}
|
|
118
|
+
declare function TicketHistory({ visible, widgetId, accessToken, workerHost, theme, onClose, }: TicketHistoryProps): React.ReactElement | null;
|
|
119
|
+
/**
|
|
120
|
+
* Convenience hook for the ticket history view. Takes the SDK's
|
|
121
|
+
* `getAccessToken` helper (deferred — called lazily on open) so the
|
|
122
|
+
* host doesn't have to thread token state by hand.
|
|
123
|
+
*
|
|
124
|
+
* import SendoraCloud from "@sendoracloud/sdk-react-native";
|
|
125
|
+
* const history = useTicketHistory("widget-uuid", () => SendoraCloud.auth.getAccessToken());
|
|
126
|
+
* <Button onPress={history.open} title="My tickets" />
|
|
127
|
+
* <history.View />
|
|
128
|
+
*/
|
|
129
|
+
declare function useTicketHistory(widgetId: string, getAccessToken: () => Promise<string | null>, defaults?: {
|
|
130
|
+
workerHost?: string;
|
|
131
|
+
theme?: "auto" | "light" | "dark";
|
|
132
|
+
}): {
|
|
133
|
+
open: () => void;
|
|
134
|
+
close: () => void;
|
|
135
|
+
View: () => React.ReactElement | null;
|
|
136
|
+
};
|
|
102
137
|
|
|
103
|
-
export { ContactWidget, type ContactWidgetProps, type ContactWidgetResult, useContactWidget };
|
|
138
|
+
export { ContactWidget, type ContactWidgetProps, type ContactWidgetResult, TicketHistory, type TicketHistoryProps, useContactWidget, useTicketHistory };
|
package/dist/contact-widget.d.ts
CHANGED
|
@@ -99,5 +99,40 @@ declare function useContactWidget(widgetId: string, defaults?: Omit<ContactWidge
|
|
|
99
99
|
View: () => React.ReactElement | null;
|
|
100
100
|
lastResult: ContactWidgetResult | null;
|
|
101
101
|
};
|
|
102
|
+
interface TicketHistoryProps {
|
|
103
|
+
/** Whether the modal sheet is visible. */
|
|
104
|
+
visible: boolean;
|
|
105
|
+
/** Widget UUID that scopes the org. */
|
|
106
|
+
widgetId: string;
|
|
107
|
+
/**
|
|
108
|
+
* Current SDK access token (from `SendoraCloud.auth.getAccessToken()`).
|
|
109
|
+
* Passed in the URL hash fragment so it never appears in server
|
|
110
|
+
* logs / referer headers. Embed scrubs the hash on load.
|
|
111
|
+
* The widget is no-op when this is null/empty.
|
|
112
|
+
*/
|
|
113
|
+
accessToken: string | null | undefined;
|
|
114
|
+
workerHost?: string;
|
|
115
|
+
theme?: "auto" | "light" | "dark";
|
|
116
|
+
onClose: (result: ContactWidgetResult) => void;
|
|
117
|
+
}
|
|
118
|
+
declare function TicketHistory({ visible, widgetId, accessToken, workerHost, theme, onClose, }: TicketHistoryProps): React.ReactElement | null;
|
|
119
|
+
/**
|
|
120
|
+
* Convenience hook for the ticket history view. Takes the SDK's
|
|
121
|
+
* `getAccessToken` helper (deferred — called lazily on open) so the
|
|
122
|
+
* host doesn't have to thread token state by hand.
|
|
123
|
+
*
|
|
124
|
+
* import SendoraCloud from "@sendoracloud/sdk-react-native";
|
|
125
|
+
* const history = useTicketHistory("widget-uuid", () => SendoraCloud.auth.getAccessToken());
|
|
126
|
+
* <Button onPress={history.open} title="My tickets" />
|
|
127
|
+
* <history.View />
|
|
128
|
+
*/
|
|
129
|
+
declare function useTicketHistory(widgetId: string, getAccessToken: () => Promise<string | null>, defaults?: {
|
|
130
|
+
workerHost?: string;
|
|
131
|
+
theme?: "auto" | "light" | "dark";
|
|
132
|
+
}): {
|
|
133
|
+
open: () => void;
|
|
134
|
+
close: () => void;
|
|
135
|
+
View: () => React.ReactElement | null;
|
|
136
|
+
};
|
|
102
137
|
|
|
103
|
-
export { ContactWidget, type ContactWidgetProps, type ContactWidgetResult, useContactWidget };
|
|
138
|
+
export { ContactWidget, type ContactWidgetProps, type ContactWidgetResult, TicketHistory, type TicketHistoryProps, useContactWidget, useTicketHistory };
|
package/dist/contact-widget.js
CHANGED
|
@@ -99,7 +99,86 @@ function useContactWidget(widgetId, defaults) {
|
|
|
99
99
|
);
|
|
100
100
|
return { open, close, View: View2, lastResult };
|
|
101
101
|
}
|
|
102
|
+
function TicketHistory({
|
|
103
|
+
visible,
|
|
104
|
+
widgetId,
|
|
105
|
+
accessToken,
|
|
106
|
+
workerHost = "https://go.sendoracloud.com",
|
|
107
|
+
theme = "auto",
|
|
108
|
+
onClose
|
|
109
|
+
}) {
|
|
110
|
+
const didFire = React.useRef(false);
|
|
111
|
+
React.useEffect(() => {
|
|
112
|
+
if (visible) didFire.current = false;
|
|
113
|
+
}, [visible]);
|
|
114
|
+
if (!widgetId || !accessToken) return null;
|
|
115
|
+
const params = new URLSearchParams({ widgetId, theme });
|
|
116
|
+
const uri = `${workerHost}/embed/tickets?${params.toString()}#access=${encodeURIComponent(accessToken)}`;
|
|
117
|
+
const handleClose = (result) => {
|
|
118
|
+
if (didFire.current) return;
|
|
119
|
+
didFire.current = true;
|
|
120
|
+
onClose(result);
|
|
121
|
+
};
|
|
122
|
+
const onNav = (req) => {
|
|
123
|
+
const url = req.url || "";
|
|
124
|
+
if (url.startsWith("sendora://close")) {
|
|
125
|
+
handleClose({ ticketId: "", portalUrl: null, submitted: false });
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
if (!url.startsWith("https://") && !url.startsWith("about:")) return false;
|
|
129
|
+
return true;
|
|
130
|
+
};
|
|
131
|
+
return /* @__PURE__ */ jsx(
|
|
132
|
+
Modal,
|
|
133
|
+
{
|
|
134
|
+
visible,
|
|
135
|
+
animationType: "slide",
|
|
136
|
+
presentationStyle: "pageSheet",
|
|
137
|
+
onRequestClose: () => handleClose({ ticketId: "", portalUrl: null, submitted: false }),
|
|
138
|
+
children: /* @__PURE__ */ jsx(View, { style: { flex: 1 }, children: /* @__PURE__ */ jsx(
|
|
139
|
+
WebView,
|
|
140
|
+
{
|
|
141
|
+
source: { uri },
|
|
142
|
+
onShouldStartLoadWithRequest: onNav,
|
|
143
|
+
originWhitelist: ["https://*", "about:*", "sendora://*"],
|
|
144
|
+
setSupportMultipleWindows: false,
|
|
145
|
+
javaScriptEnabled: true,
|
|
146
|
+
domStorageEnabled: true,
|
|
147
|
+
allowsBackForwardNavigationGestures: false
|
|
148
|
+
}
|
|
149
|
+
) })
|
|
150
|
+
}
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
function useTicketHistory(widgetId, getAccessToken, defaults) {
|
|
154
|
+
const [visible, setVisible] = React.useState(false);
|
|
155
|
+
const [token, setToken] = React.useState(null);
|
|
156
|
+
const open = React.useCallback(async () => {
|
|
157
|
+
const t = await getAccessToken();
|
|
158
|
+
if (!t) return;
|
|
159
|
+
setToken(t);
|
|
160
|
+
setVisible(true);
|
|
161
|
+
}, [getAccessToken]);
|
|
162
|
+
const close = React.useCallback(() => setVisible(false), []);
|
|
163
|
+
const View2 = React.useCallback(
|
|
164
|
+
() => /* @__PURE__ */ jsx(
|
|
165
|
+
TicketHistory,
|
|
166
|
+
{
|
|
167
|
+
widgetId,
|
|
168
|
+
visible,
|
|
169
|
+
accessToken: token,
|
|
170
|
+
workerHost: defaults?.workerHost,
|
|
171
|
+
theme: defaults?.theme,
|
|
172
|
+
onClose: () => setVisible(false)
|
|
173
|
+
}
|
|
174
|
+
),
|
|
175
|
+
[widgetId, visible, token, defaults]
|
|
176
|
+
);
|
|
177
|
+
return { open, close, View: View2 };
|
|
178
|
+
}
|
|
102
179
|
export {
|
|
103
180
|
ContactWidget,
|
|
104
|
-
|
|
181
|
+
TicketHistory,
|
|
182
|
+
useContactWidget,
|
|
183
|
+
useTicketHistory
|
|
105
184
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sendoracloud/sdk-react-native",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Sendora Cloud React Native + Expo SDK — analytics, identity, push-token registration, auth, deep links (Branch / Firebase Dynamic Links parity). Auth + analytics + deep links work in Expo Go; push token registration requires a Dev Client (EAS Build or `npx expo prebuild`).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|