@fluid-app/portal-sdk 0.1.13 → 0.1.15
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/AccountScreen-B08uxzt6.mjs +2 -0
- package/dist/AccountScreen-CQCwpKEC.mjs +741 -0
- package/dist/AccountScreen-CQCwpKEC.mjs.map +1 -0
- package/dist/AccountScreen-CbhrIAa4.cjs +780 -0
- package/dist/AccountScreen-CbhrIAa4.cjs.map +1 -0
- package/dist/{ContactsScreen-CB6l0Lf1.mjs → ContactsScreen-CHLFZX_N.mjs} +2 -2
- package/dist/{ContactsScreen-CB6l0Lf1.mjs.map → ContactsScreen-CHLFZX_N.mjs.map} +1 -1
- package/dist/{ContactsScreen-Dwn5onLu.cjs → ContactsScreen-CjnCemeI.cjs} +4 -4
- package/dist/{ContactsScreen-Dwn5onLu.cjs.map → ContactsScreen-CjnCemeI.cjs.map} +1 -1
- package/dist/{CoreScreenPlaceholder-Bw8YOPwv.cjs → CoreScreenPlaceholder-C9lBkcyc.cjs} +2 -2
- package/dist/{CoreScreenPlaceholder-Bw8YOPwv.cjs.map → CoreScreenPlaceholder-C9lBkcyc.cjs.map} +1 -1
- package/dist/{CoreScreenPlaceholder-D93ZYKt2.mjs → CoreScreenPlaceholder-DCJ1hFvJ.mjs} +1 -1
- package/dist/{CoreScreenPlaceholder-D93ZYKt2.mjs.map → CoreScreenPlaceholder-DCJ1hFvJ.mjs.map} +1 -1
- package/dist/{CustomersScreen-gQb6cWL5.cjs → CustomersScreen-CqwRJogV.cjs} +4 -4
- package/dist/{CustomersScreen-gQb6cWL5.cjs.map → CustomersScreen-CqwRJogV.cjs.map} +1 -1
- package/dist/{CustomersScreen-BEar6Leg.mjs → CustomersScreen-DBicCB3o.mjs} +2 -2
- package/dist/{CustomersScreen-BEar6Leg.mjs.map → CustomersScreen-DBicCB3o.mjs.map} +1 -1
- package/dist/{MessagingScreen-YyzXdr95.mjs → FluidProvider-BafZw8PJ.mjs} +6 -503
- package/dist/FluidProvider-BafZw8PJ.mjs.map +1 -0
- package/dist/{MessagingScreen-Ca22FObh.cjs → FluidProvider-C6SCZDjX.cjs} +3 -542
- package/dist/FluidProvider-C6SCZDjX.cjs.map +1 -0
- package/dist/MessagingScreen-Bd-1_J9q.cjs +369 -0
- package/dist/MessagingScreen-Bd-1_J9q.cjs.map +1 -0
- package/dist/MessagingScreen-D8W8V2TW.mjs +2 -0
- package/dist/MessagingScreen-DCS0mtbd.mjs +324 -0
- package/dist/MessagingScreen-DCS0mtbd.mjs.map +1 -0
- package/dist/{OrdersScreen-DB1v051q.mjs → OrdersScreen-B6JCMBY5.mjs} +2 -2
- package/dist/{OrdersScreen-DB1v051q.mjs.map → OrdersScreen-B6JCMBY5.mjs.map} +1 -1
- package/dist/{OrdersScreen-DbON-kBA.cjs → OrdersScreen-DBxpXgZ9.cjs} +4 -4
- package/dist/{OrdersScreen-DbON-kBA.cjs.map → OrdersScreen-DBxpXgZ9.cjs.map} +1 -1
- package/dist/{ProductsScreen-CMDGGvE2.cjs → ProductsScreen-BK8cz_MN.cjs} +4 -4
- package/dist/{ProductsScreen-CMDGGvE2.cjs.map → ProductsScreen-BK8cz_MN.cjs.map} +1 -1
- package/dist/{ProductsScreen-nVDsY6kf.mjs → ProductsScreen-DafsauTY.mjs} +2 -2
- package/dist/{ProductsScreen-nVDsY6kf.mjs.map → ProductsScreen-DafsauTY.mjs.map} +1 -1
- package/dist/index.cjs +73 -138
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -22
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +29 -22
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +49 -116
- package/dist/index.mjs.map +1 -1
- package/package.json +19 -13
- package/dist/MessagingScreen-Ca22FObh.cjs.map +0 -1
- package/dist/MessagingScreen-YyzXdr95.mjs.map +0 -1
|
@@ -38,188 +38,8 @@ let _fluid_app_portal_core_data_sources_registry_context = require("@fluid-app/p
|
|
|
38
38
|
let _fluid_app_portal_widgets_contexts = require("@fluid-app/portal-widgets/contexts");
|
|
39
39
|
let _fluid_app_portal_core_widget_utils = require("@fluid-app/portal-core/widget-utils");
|
|
40
40
|
let _fluid_app_portal_widgets_widgets = require("@fluid-app/portal-widgets/widgets");
|
|
41
|
-
let _fluid_app_messaging_core = require("@fluid-app/messaging-core");
|
|
42
|
-
let _fluid_app_messaging_ui_app = require("@fluid-app/messaging-ui/app");
|
|
43
|
-
let _fluid_app_messaging_ui = require("@fluid-app/messaging-ui");
|
|
44
|
-
let _fluid_app_messaging_api_client = require("@fluid-app/messaging-api-client");
|
|
45
41
|
let _fluid_app_auth = require("@fluid-app/auth");
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* API Error class compatible with fluid-admin's ApiError
|
|
49
|
-
*/
|
|
50
|
-
var ApiError$1 = class ApiError$1 extends Error {
|
|
51
|
-
status;
|
|
52
|
-
data;
|
|
53
|
-
constructor(message, status, data) {
|
|
54
|
-
super(message);
|
|
55
|
-
this.name = "ApiError";
|
|
56
|
-
this.status = status;
|
|
57
|
-
this.data = data;
|
|
58
|
-
if ("captureStackTrace" in Error) Error.captureStackTrace(this, ApiError$1);
|
|
59
|
-
}
|
|
60
|
-
toJSON() {
|
|
61
|
-
return {
|
|
62
|
-
name: this.name,
|
|
63
|
-
message: this.message,
|
|
64
|
-
status: this.status,
|
|
65
|
-
data: this.data
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
* Creates a configured fetch client instance
|
|
71
|
-
*/
|
|
72
|
-
function createFetchClient(config) {
|
|
73
|
-
const { baseUrl, getAuthToken, onAuthError, defaultHeaders = {} } = config;
|
|
74
|
-
/**
|
|
75
|
-
* Build headers for a request
|
|
76
|
-
*/
|
|
77
|
-
async function buildHeaders(customHeaders) {
|
|
78
|
-
const headers = {
|
|
79
|
-
Accept: "application/json",
|
|
80
|
-
"Content-Type": "application/json",
|
|
81
|
-
...defaultHeaders,
|
|
82
|
-
...customHeaders
|
|
83
|
-
};
|
|
84
|
-
if (getAuthToken) {
|
|
85
|
-
const token = await getAuthToken();
|
|
86
|
-
if (token) headers.Authorization = `Bearer ${token}`;
|
|
87
|
-
}
|
|
88
|
-
return headers;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Join baseUrl + endpoint via string concatenation (matches fetchApi).
|
|
92
|
-
* Using `new URL(endpoint, baseUrl)` would strip any path prefix from
|
|
93
|
-
* baseUrl (e.g. "/api") when the endpoint starts with "/".
|
|
94
|
-
*/
|
|
95
|
-
function joinUrl(endpoint) {
|
|
96
|
-
return `${baseUrl}${endpoint}`;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Build URL with query parameters for GET requests
|
|
100
|
-
* Compatible with fluid-admin's query param handling
|
|
101
|
-
*/
|
|
102
|
-
function buildUrl(endpoint, params) {
|
|
103
|
-
const fullUrl = joinUrl(endpoint);
|
|
104
|
-
if (!params || Object.keys(params).length === 0) return fullUrl;
|
|
105
|
-
const queryString = new URLSearchParams();
|
|
106
|
-
Object.entries(params).forEach(([key, value]) => {
|
|
107
|
-
if (value === void 0 || value === null) return;
|
|
108
|
-
if (Array.isArray(value)) value.forEach((item) => queryString.append(`${key}[]`, String(item)));
|
|
109
|
-
else if (typeof value === "object") Object.entries(value).forEach(([subKey, subValue]) => {
|
|
110
|
-
if (subValue === void 0 || subValue === null) return;
|
|
111
|
-
if (Array.isArray(subValue)) subValue.forEach((item) => queryString.append(`${key}[${subKey}][]`, String(item)));
|
|
112
|
-
else queryString.append(`${key}[${subKey}]`, String(subValue));
|
|
113
|
-
});
|
|
114
|
-
else queryString.append(key, String(value));
|
|
115
|
-
});
|
|
116
|
-
const qs = queryString.toString();
|
|
117
|
-
return qs ? `${fullUrl}?${qs}` : fullUrl;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Shared response handler for both JSON and FormData requests.
|
|
121
|
-
* Handles auth errors, non-OK responses, 204 No Content, and JSON parsing.
|
|
122
|
-
*/
|
|
123
|
-
async function handleResponse(response, method, _url) {
|
|
124
|
-
if (response.status === 401 && onAuthError) onAuthError();
|
|
125
|
-
if (!response.ok) {
|
|
126
|
-
const errorText = await response.text().catch(() => "");
|
|
127
|
-
if (response.headers.get("content-type")?.includes("application/json")) {
|
|
128
|
-
let data;
|
|
129
|
-
try {
|
|
130
|
-
data = JSON.parse(errorText);
|
|
131
|
-
} catch {
|
|
132
|
-
throw new ApiError$1(errorText.slice(0, 200) || `${method} request failed with status ${response.status}`, response.status, null);
|
|
133
|
-
}
|
|
134
|
-
throw new ApiError$1(data.message || data.error_message || `${method} request failed`, response.status, data.errors || data);
|
|
135
|
-
} else throw new ApiError$1(`${method} request failed with status ${response.status}`, response.status, null);
|
|
136
|
-
}
|
|
137
|
-
if (response.status === 204 || response.headers.get("content-length") === "0") return null;
|
|
138
|
-
if (response.headers.get("content-type")?.includes("application/json")) try {
|
|
139
|
-
return await response.json();
|
|
140
|
-
} catch {
|
|
141
|
-
try {
|
|
142
|
-
return await response.text();
|
|
143
|
-
} catch {
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Main request function
|
|
151
|
-
*/
|
|
152
|
-
async function request(endpoint, options = {}) {
|
|
153
|
-
const { method = "GET", headers: customHeaders, params, body, signal } = options;
|
|
154
|
-
const url = params ? buildUrl(endpoint, params) : joinUrl(endpoint);
|
|
155
|
-
const headers = await buildHeaders(customHeaders);
|
|
156
|
-
let response;
|
|
157
|
-
try {
|
|
158
|
-
const fetchOptions = {
|
|
159
|
-
method,
|
|
160
|
-
headers
|
|
161
|
-
};
|
|
162
|
-
const serializedBody = body && method !== "GET" ? JSON.stringify(body) : null;
|
|
163
|
-
if (serializedBody) fetchOptions.body = serializedBody;
|
|
164
|
-
if (signal) fetchOptions.signal = signal;
|
|
165
|
-
response = await fetch(url, fetchOptions);
|
|
166
|
-
} catch (networkError) {
|
|
167
|
-
throw new ApiError$1(`Network error: ${networkError instanceof Error ? networkError.message : "Unknown network error"}`, 0, null);
|
|
168
|
-
}
|
|
169
|
-
return handleResponse(response, method, url);
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Request with FormData (for file uploads)
|
|
173
|
-
*/
|
|
174
|
-
async function requestWithFormData(endpoint, formData, options = {}) {
|
|
175
|
-
const { method = "POST", headers: customHeaders, signal } = options;
|
|
176
|
-
const url = joinUrl(endpoint);
|
|
177
|
-
const headers = await buildHeaders(customHeaders);
|
|
178
|
-
delete headers["Content-Type"];
|
|
179
|
-
let response;
|
|
180
|
-
try {
|
|
181
|
-
const fetchOptions = {
|
|
182
|
-
method,
|
|
183
|
-
headers,
|
|
184
|
-
body: formData
|
|
185
|
-
};
|
|
186
|
-
if (signal) fetchOptions.signal = signal;
|
|
187
|
-
response = await fetch(url, fetchOptions);
|
|
188
|
-
} catch (networkError) {
|
|
189
|
-
throw new ApiError$1(`Network error: ${networkError instanceof Error ? networkError.message : "Unknown network error"}`, 0, null);
|
|
190
|
-
}
|
|
191
|
-
return handleResponse(response, method, url);
|
|
192
|
-
}
|
|
193
|
-
return {
|
|
194
|
-
request,
|
|
195
|
-
requestWithFormData,
|
|
196
|
-
get: (endpoint, params, options) => request(endpoint, {
|
|
197
|
-
...options,
|
|
198
|
-
method: "GET",
|
|
199
|
-
...params && { params }
|
|
200
|
-
}),
|
|
201
|
-
post: (endpoint, body, options) => request(endpoint, {
|
|
202
|
-
...options,
|
|
203
|
-
method: "POST",
|
|
204
|
-
body
|
|
205
|
-
}),
|
|
206
|
-
put: (endpoint, body, options) => request(endpoint, {
|
|
207
|
-
...options,
|
|
208
|
-
method: "PUT",
|
|
209
|
-
body
|
|
210
|
-
}),
|
|
211
|
-
patch: (endpoint, body, options) => request(endpoint, {
|
|
212
|
-
...options,
|
|
213
|
-
method: "PATCH",
|
|
214
|
-
body
|
|
215
|
-
}),
|
|
216
|
-
delete: (endpoint, options) => request(endpoint, {
|
|
217
|
-
...options,
|
|
218
|
-
method: "DELETE"
|
|
219
|
-
})
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
//#endregion
|
|
42
|
+
let _fluid_app_api_client_core = require("@fluid-app/api-client-core");
|
|
223
43
|
//#region ../../api-clients/fluidos/src/namespaces/fluid_os.ts
|
|
224
44
|
/**
|
|
225
45
|
* Get active Fluid OS definition
|
|
@@ -388,7 +208,7 @@ function extractErrorMessage(data, fallback) {
|
|
|
388
208
|
function createFluidClient(config) {
|
|
389
209
|
const { baseUrl, getAuthToken, onAuthError, defaultHeaders = {} } = config;
|
|
390
210
|
const effectiveOnAuthError = onAuthError ?? (0, _fluid_app_auth.createDefaultAuthRedirect)();
|
|
391
|
-
const fetchClient = createFetchClient({
|
|
211
|
+
const fetchClient = (0, _fluid_app_api_client_core.createFetchClient)({
|
|
392
212
|
baseUrl,
|
|
393
213
|
...getAuthToken ? { getAuthToken } : {},
|
|
394
214
|
onAuthError: effectiveOnAuthError,
|
|
@@ -992,323 +812,6 @@ function useFluidContext() {
|
|
|
992
812
|
return context;
|
|
993
813
|
}
|
|
994
814
|
//#endregion
|
|
995
|
-
//#region src/hooks/use-fluid-api.ts
|
|
996
|
-
/**
|
|
997
|
-
* Hook to access the Fluid API client
|
|
998
|
-
*
|
|
999
|
-
* @example
|
|
1000
|
-
* ```tsx
|
|
1001
|
-
* function ProductList() {
|
|
1002
|
-
* const api = useFluidApi();
|
|
1003
|
-
*
|
|
1004
|
-
* const { data: products } = useQuery({
|
|
1005
|
-
* queryKey: ["products"],
|
|
1006
|
-
* queryFn: () => api.products.list(),
|
|
1007
|
-
* });
|
|
1008
|
-
*
|
|
1009
|
-
* return <ul>{products?.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
|
|
1010
|
-
* }
|
|
1011
|
-
* ```
|
|
1012
|
-
*/
|
|
1013
|
-
function useFluidApi() {
|
|
1014
|
-
const { client } = useFluidContext();
|
|
1015
|
-
return client;
|
|
1016
|
-
}
|
|
1017
|
-
//#endregion
|
|
1018
|
-
//#region src/messaging/use-messaging-auth.ts
|
|
1019
|
-
/**
|
|
1020
|
-
* Bridge hook: maps portal SDK auth context to MessagingAuthContext.
|
|
1021
|
-
*
|
|
1022
|
-
* The messaging system identifies users by `recipient_id`, which is NOT in the
|
|
1023
|
-
* JWT payload or the /reps/me endpoint. It IS returned by GET /api/me.
|
|
1024
|
-
* This hook fetches that data and maps it into the shape MessagingApp expects.
|
|
1025
|
-
*/
|
|
1026
|
-
const USERS_ME_QUERY_KEY = [
|
|
1027
|
-
"fluid",
|
|
1028
|
-
"users",
|
|
1029
|
-
"me"
|
|
1030
|
-
];
|
|
1031
|
-
function useMessagingAuth() {
|
|
1032
|
-
const auth = useFluidAuthContext();
|
|
1033
|
-
const api = useFluidApi();
|
|
1034
|
-
const { data: userMe, isLoading: isUserMeLoading, isError } = (0, _tanstack_react_query.useQuery)({
|
|
1035
|
-
queryKey: USERS_ME_QUERY_KEY,
|
|
1036
|
-
queryFn: () => api.users.me(),
|
|
1037
|
-
enabled: auth.isAuthenticated,
|
|
1038
|
-
staleTime: Infinity,
|
|
1039
|
-
retry: 1
|
|
1040
|
-
});
|
|
1041
|
-
if (auth.isLoading || auth.isAuthenticated && isUserMeLoading) return {
|
|
1042
|
-
recipientId: null,
|
|
1043
|
-
companyId: null,
|
|
1044
|
-
currentUser: null,
|
|
1045
|
-
isLoading: true
|
|
1046
|
-
};
|
|
1047
|
-
if (!auth.isAuthenticated || isError || !userMe) return {
|
|
1048
|
-
recipientId: null,
|
|
1049
|
-
companyId: null,
|
|
1050
|
-
currentUser: null,
|
|
1051
|
-
isLoading: false
|
|
1052
|
-
};
|
|
1053
|
-
const currentUser = userMe.recipient_id ? {
|
|
1054
|
-
id: userMe.id,
|
|
1055
|
-
recipientId: userMe.recipient_id,
|
|
1056
|
-
firstName: userMe.first_name ?? "",
|
|
1057
|
-
lastName: userMe.last_name ?? "",
|
|
1058
|
-
email: userMe.email,
|
|
1059
|
-
...userMe.image_url != null && { imageUrl: userMe.image_url },
|
|
1060
|
-
...userMe.affiliate_id != null && { affiliateId: userMe.affiliate_id }
|
|
1061
|
-
} : null;
|
|
1062
|
-
return {
|
|
1063
|
-
recipientId: userMe.recipient_id,
|
|
1064
|
-
companyId: userMe.company_id ?? null,
|
|
1065
|
-
currentUser,
|
|
1066
|
-
isLoading: false
|
|
1067
|
-
};
|
|
1068
|
-
}
|
|
1069
|
-
//#endregion
|
|
1070
|
-
//#region src/messaging/use-messaging-config.ts
|
|
1071
|
-
/**
|
|
1072
|
-
* Hook that derives MessagingApiConfig from the portal SDK's FluidProvider context.
|
|
1073
|
-
*
|
|
1074
|
-
* Maps FluidSDKConfig fields to the shape expected by MessagingApp:
|
|
1075
|
-
* - baseUrl -> from config.baseUrl
|
|
1076
|
-
* - getHeaders -> builds Authorization header from config.getAuthToken()
|
|
1077
|
-
* - onAuthError -> from config.onAuthError
|
|
1078
|
-
* - websocketUrl -> config.websocketUrl or derived from baseUrl
|
|
1079
|
-
* - token -> from auth context
|
|
1080
|
-
*/
|
|
1081
|
-
function deriveWebsocketUrl(baseUrl) {
|
|
1082
|
-
return `${baseUrl.replace(/\/+$/, "").replace(/\/api$/, "")}/cable`;
|
|
1083
|
-
}
|
|
1084
|
-
function useMessagingConfig() {
|
|
1085
|
-
const { config } = useFluidContext();
|
|
1086
|
-
const auth = useFluidAuthContext();
|
|
1087
|
-
const getHeaders = (0, react.useCallback)(async () => {
|
|
1088
|
-
const headers = {
|
|
1089
|
-
"Content-Type": "application/json",
|
|
1090
|
-
...config.defaultHeaders
|
|
1091
|
-
};
|
|
1092
|
-
if (config.getAuthToken) {
|
|
1093
|
-
const token = await config.getAuthToken();
|
|
1094
|
-
if (token) headers.Authorization = `Bearer ${token}`;
|
|
1095
|
-
}
|
|
1096
|
-
return headers;
|
|
1097
|
-
}, [config]);
|
|
1098
|
-
const apiBaseUrl = (0, react.useMemo)(() => {
|
|
1099
|
-
const base = config.baseUrl.replace(/\/+$/, "");
|
|
1100
|
-
return base.endsWith("/api") ? base : `${base}/api`;
|
|
1101
|
-
}, [config.baseUrl]);
|
|
1102
|
-
return {
|
|
1103
|
-
apiConfig: (0, react.useMemo)(() => ({
|
|
1104
|
-
baseUrl: apiBaseUrl,
|
|
1105
|
-
getHeaders,
|
|
1106
|
-
...config.onAuthError != null && { onAuthError: config.onAuthError }
|
|
1107
|
-
}), [
|
|
1108
|
-
apiBaseUrl,
|
|
1109
|
-
config.onAuthError,
|
|
1110
|
-
getHeaders
|
|
1111
|
-
]),
|
|
1112
|
-
websocketUrl: (0, react.useMemo)(() => config.websocketUrl ?? deriveWebsocketUrl(config.baseUrl), [config.websocketUrl, config.baseUrl]),
|
|
1113
|
-
token: auth.token
|
|
1114
|
-
};
|
|
1115
|
-
}
|
|
1116
|
-
//#endregion
|
|
1117
|
-
//#region src/messaging/fluid-file-uploader.ts
|
|
1118
|
-
const FILESTACK_UPLOAD_URL = "https://www.filestackapi.com/api/store/S3";
|
|
1119
|
-
function getImageDimensions(file) {
|
|
1120
|
-
if (!file.type.startsWith("image/")) return Promise.resolve(null);
|
|
1121
|
-
return new Promise((resolve) => {
|
|
1122
|
-
const img = new Image();
|
|
1123
|
-
const url = URL.createObjectURL(file);
|
|
1124
|
-
img.onload = () => {
|
|
1125
|
-
URL.revokeObjectURL(url);
|
|
1126
|
-
resolve({
|
|
1127
|
-
width: img.naturalWidth,
|
|
1128
|
-
height: img.naturalHeight
|
|
1129
|
-
});
|
|
1130
|
-
};
|
|
1131
|
-
img.onerror = () => {
|
|
1132
|
-
URL.revokeObjectURL(url);
|
|
1133
|
-
resolve(null);
|
|
1134
|
-
};
|
|
1135
|
-
img.src = url;
|
|
1136
|
-
});
|
|
1137
|
-
}
|
|
1138
|
-
function uploadToFilestack(file, apiKey, callbacks) {
|
|
1139
|
-
const xhr = new XMLHttpRequest();
|
|
1140
|
-
let aborted = false;
|
|
1141
|
-
getImageDimensions(file).then((metadata) => {
|
|
1142
|
-
if (aborted) return;
|
|
1143
|
-
const url = `${FILESTACK_UPLOAD_URL}?key=${encodeURIComponent(apiKey)}`;
|
|
1144
|
-
xhr.open("POST", url);
|
|
1145
|
-
xhr.setRequestHeader("Content-Type", file.type);
|
|
1146
|
-
xhr.upload.onprogress = (event) => {
|
|
1147
|
-
if (event.lengthComputable) {
|
|
1148
|
-
const progress = Math.round(event.loaded / event.total * 100);
|
|
1149
|
-
callbacks.onProgress(progress);
|
|
1150
|
-
}
|
|
1151
|
-
};
|
|
1152
|
-
xhr.onload = () => {
|
|
1153
|
-
if (xhr.status >= 200 && xhr.status < 300) try {
|
|
1154
|
-
const result = {
|
|
1155
|
-
url: JSON.parse(xhr.responseText).url,
|
|
1156
|
-
size: file.size,
|
|
1157
|
-
mimetype: file.type,
|
|
1158
|
-
kind: (0, _fluid_app_messaging_core.getFileTypeFromMimetype)(file.type),
|
|
1159
|
-
metadata
|
|
1160
|
-
};
|
|
1161
|
-
callbacks.onSuccess(result);
|
|
1162
|
-
} catch {
|
|
1163
|
-
callbacks.onError(/* @__PURE__ */ new Error("Failed to parse upload response"));
|
|
1164
|
-
}
|
|
1165
|
-
else callbacks.onError(/* @__PURE__ */ new Error(`Upload failed with status ${xhr.status}`));
|
|
1166
|
-
};
|
|
1167
|
-
xhr.onerror = () => {
|
|
1168
|
-
if (!aborted) callbacks.onError(/* @__PURE__ */ new Error("Upload failed due to a network error"));
|
|
1169
|
-
};
|
|
1170
|
-
xhr.onabort = () => {};
|
|
1171
|
-
xhr.send(file);
|
|
1172
|
-
}).catch((error) => {
|
|
1173
|
-
if (!aborted) callbacks.onError(error instanceof Error ? error : /* @__PURE__ */ new Error("Upload preparation failed"));
|
|
1174
|
-
});
|
|
1175
|
-
return { abort: () => {
|
|
1176
|
-
aborted = true;
|
|
1177
|
-
xhr.abort();
|
|
1178
|
-
} };
|
|
1179
|
-
}
|
|
1180
|
-
/**
|
|
1181
|
-
* Creates a FileUploader that uploads to Filestack using the REST API.
|
|
1182
|
-
*
|
|
1183
|
-
* @param apiKey - Filestack API key. If falsy, returns a noop uploader
|
|
1184
|
-
* that rejects uploads with a helpful error message.
|
|
1185
|
-
*/
|
|
1186
|
-
function createFluidFileUploader(apiKey) {
|
|
1187
|
-
if (!apiKey) return { uploadFile: (_file, callbacks) => {
|
|
1188
|
-
callbacks.onError(/* @__PURE__ */ new Error("File uploads are not configured. Set filestackApiKey in your SDK config to enable attachments."));
|
|
1189
|
-
return { abort: () => {} };
|
|
1190
|
-
} };
|
|
1191
|
-
return { uploadFile: (file, callbacks) => uploadToFilestack(file, apiKey, callbacks) };
|
|
1192
|
-
}
|
|
1193
|
-
//#endregion
|
|
1194
|
-
//#region src/screens/MessagingScreen.tsx
|
|
1195
|
-
var MessagingScreen_exports = /* @__PURE__ */ __exportAll({
|
|
1196
|
-
MessagingScreen: () => MessagingScreen,
|
|
1197
|
-
messagingScreenPropertySchema: () => messagingScreenPropertySchema
|
|
1198
|
-
});
|
|
1199
|
-
function renderImage(props) {
|
|
1200
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
1201
|
-
src: props.src,
|
|
1202
|
-
alt: props.alt,
|
|
1203
|
-
width: props.width,
|
|
1204
|
-
height: props.height,
|
|
1205
|
-
className: props.className
|
|
1206
|
-
});
|
|
1207
|
-
}
|
|
1208
|
-
function defaultToast(message, type) {
|
|
1209
|
-
if (type === "error") console.warn("[Messaging]", message);
|
|
1210
|
-
}
|
|
1211
|
-
function MessagingScreen({ onToast, filestackApiKey, websocketUrl: websocketUrlOverride, background, textColor, accentColor, padding, borderRadius, ...divProps }) {
|
|
1212
|
-
const { config } = useFluidContext();
|
|
1213
|
-
const { apiConfig, websocketUrl, token } = useMessagingConfig();
|
|
1214
|
-
const messagingAuth = useMessagingAuth();
|
|
1215
|
-
const effectiveApiKey = filestackApiKey ?? config.filestackApiKey;
|
|
1216
|
-
const uploader = (0, react.useMemo)(() => createFluidFileUploader(effectiveApiKey), [effectiveApiKey]);
|
|
1217
|
-
const effectiveWsUrl = websocketUrlOverride ?? websocketUrl;
|
|
1218
|
-
const effectiveToast = onToast ?? defaultToast;
|
|
1219
|
-
const searchUsers = (0, react.useCallback)(async (query) => {
|
|
1220
|
-
return ((await (0, _fluid_app_messaging_api_client.listConnectedRecipients)(apiConfig, {
|
|
1221
|
-
filterrific: { search_query: query },
|
|
1222
|
-
per_page: 10,
|
|
1223
|
-
page: 1
|
|
1224
|
-
}))?.[1]?.items ?? []).map((user) => {
|
|
1225
|
-
const name = [user.first_name, user.last_name].filter(Boolean).length > 0 ? [user.first_name, user.last_name].filter(Boolean).join(" ") : `User ${user.id}`;
|
|
1226
|
-
return {
|
|
1227
|
-
id: String(user.id),
|
|
1228
|
-
label: name,
|
|
1229
|
-
imageType: "user",
|
|
1230
|
-
userData: {
|
|
1231
|
-
first_name: user.first_name,
|
|
1232
|
-
last_name: user.last_name,
|
|
1233
|
-
image_url: user.avatar_url,
|
|
1234
|
-
phone: user.phone || void 0,
|
|
1235
|
-
email: user.email || void 0
|
|
1236
|
-
},
|
|
1237
|
-
conversationName: name
|
|
1238
|
-
};
|
|
1239
|
-
});
|
|
1240
|
-
}, [apiConfig]);
|
|
1241
|
-
const searchChannels = (0, react.useCallback)(async (query) => {
|
|
1242
|
-
return (await (0, _fluid_app_messaging_api_client.searchConversations)(apiConfig, { filterrific: { search_query: query } }) ?? []).map((channel) => {
|
|
1243
|
-
const { text: nameWithoutEmoji } = (0, _fluid_app_messaging_ui.extractEmoji)(channel.name);
|
|
1244
|
-
return {
|
|
1245
|
-
id: `channel-${channel.id}`,
|
|
1246
|
-
label: (0, _fluid_app_messaging_ui.formatMessageChannelName)(nameWithoutEmoji),
|
|
1247
|
-
imageType: "channel",
|
|
1248
|
-
userData: {
|
|
1249
|
-
first_name: channel.name,
|
|
1250
|
-
last_name: null,
|
|
1251
|
-
image_url: channel.avatar_url
|
|
1252
|
-
},
|
|
1253
|
-
conversationName: channel.name
|
|
1254
|
-
};
|
|
1255
|
-
});
|
|
1256
|
-
}, [apiConfig]);
|
|
1257
|
-
if (messagingAuth.isLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1258
|
-
...divProps,
|
|
1259
|
-
className: `flex h-full items-center justify-center ${divProps.className ?? ""}`,
|
|
1260
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1261
|
-
className: "text-muted-foreground",
|
|
1262
|
-
children: "Loading messaging..."
|
|
1263
|
-
})
|
|
1264
|
-
});
|
|
1265
|
-
if (!messagingAuth.recipientId) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1266
|
-
...divProps,
|
|
1267
|
-
className: `flex h-full items-center justify-center ${divProps.className ?? ""}`,
|
|
1268
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1269
|
-
className: "border-border max-w-sm rounded-lg border border-dashed p-8 text-center",
|
|
1270
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
1271
|
-
className: "text-foreground text-xl font-semibold",
|
|
1272
|
-
children: "Messaging"
|
|
1273
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1274
|
-
className: "text-muted-foreground mt-2",
|
|
1275
|
-
children: "Messaging is not available for your account"
|
|
1276
|
-
})]
|
|
1277
|
-
})
|
|
1278
|
-
});
|
|
1279
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1280
|
-
...divProps,
|
|
1281
|
-
className: `h-full ${divProps.className ?? ""}`,
|
|
1282
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_fluid_app_messaging_ui_app.MessagingApp, {
|
|
1283
|
-
config: apiConfig,
|
|
1284
|
-
auth: messagingAuth,
|
|
1285
|
-
websocketUrl: effectiveWsUrl,
|
|
1286
|
-
token,
|
|
1287
|
-
renderImage,
|
|
1288
|
-
showAdminFeatures: false,
|
|
1289
|
-
onToast: effectiveToast,
|
|
1290
|
-
messagesViewProps: {
|
|
1291
|
-
uploader,
|
|
1292
|
-
saveDrafts: true,
|
|
1293
|
-
onToast: effectiveToast
|
|
1294
|
-
},
|
|
1295
|
-
newMessageViewProps: {
|
|
1296
|
-
searchUsers,
|
|
1297
|
-
searchChannels
|
|
1298
|
-
}
|
|
1299
|
-
})
|
|
1300
|
-
});
|
|
1301
|
-
}
|
|
1302
|
-
const messagingScreenPropertySchema = {
|
|
1303
|
-
widgetType: "MessagingScreen",
|
|
1304
|
-
displayName: "Messaging Screen",
|
|
1305
|
-
tabsConfig: [{
|
|
1306
|
-
id: "styling",
|
|
1307
|
-
label: "Styling"
|
|
1308
|
-
}],
|
|
1309
|
-
fields: []
|
|
1310
|
-
};
|
|
1311
|
-
//#endregion
|
|
1312
815
|
Object.defineProperty(exports, "ApiError", {
|
|
1313
816
|
enumerable: true,
|
|
1314
817
|
get: function() {
|
|
@@ -1339,18 +842,6 @@ Object.defineProperty(exports, "FluidThemeProvider", {
|
|
|
1339
842
|
return FluidThemeProvider;
|
|
1340
843
|
}
|
|
1341
844
|
});
|
|
1342
|
-
Object.defineProperty(exports, "MessagingScreen", {
|
|
1343
|
-
enumerable: true,
|
|
1344
|
-
get: function() {
|
|
1345
|
-
return MessagingScreen;
|
|
1346
|
-
}
|
|
1347
|
-
});
|
|
1348
|
-
Object.defineProperty(exports, "MessagingScreen_exports", {
|
|
1349
|
-
enumerable: true,
|
|
1350
|
-
get: function() {
|
|
1351
|
-
return MessagingScreen_exports;
|
|
1352
|
-
}
|
|
1353
|
-
});
|
|
1354
845
|
Object.defineProperty(exports, "__exportAll", {
|
|
1355
846
|
enumerable: true,
|
|
1356
847
|
get: function() {
|
|
@@ -1369,24 +860,12 @@ Object.defineProperty(exports, "createFluidClient", {
|
|
|
1369
860
|
return createFluidClient;
|
|
1370
861
|
}
|
|
1371
862
|
});
|
|
1372
|
-
Object.defineProperty(exports, "createFluidFileUploader", {
|
|
1373
|
-
enumerable: true,
|
|
1374
|
-
get: function() {
|
|
1375
|
-
return createFluidFileUploader;
|
|
1376
|
-
}
|
|
1377
|
-
});
|
|
1378
863
|
Object.defineProperty(exports, "isApiError", {
|
|
1379
864
|
enumerable: true,
|
|
1380
865
|
get: function() {
|
|
1381
866
|
return isApiError;
|
|
1382
867
|
}
|
|
1383
868
|
});
|
|
1384
|
-
Object.defineProperty(exports, "messagingScreenPropertySchema", {
|
|
1385
|
-
enumerable: true,
|
|
1386
|
-
get: function() {
|
|
1387
|
-
return messagingScreenPropertySchema;
|
|
1388
|
-
}
|
|
1389
|
-
});
|
|
1390
869
|
Object.defineProperty(exports, "normalizeComponentTree", {
|
|
1391
870
|
enumerable: true,
|
|
1392
871
|
get: function() {
|
|
@@ -1417,12 +896,6 @@ Object.defineProperty(exports, "transformManifestToRepAppData", {
|
|
|
1417
896
|
return transformManifestToRepAppData;
|
|
1418
897
|
}
|
|
1419
898
|
});
|
|
1420
|
-
Object.defineProperty(exports, "useFluidApi", {
|
|
1421
|
-
enumerable: true,
|
|
1422
|
-
get: function() {
|
|
1423
|
-
return useFluidApi;
|
|
1424
|
-
}
|
|
1425
|
-
});
|
|
1426
899
|
Object.defineProperty(exports, "useFluidAuthContext", {
|
|
1427
900
|
enumerable: true,
|
|
1428
901
|
get: function() {
|
|
@@ -1435,18 +908,6 @@ Object.defineProperty(exports, "useFluidContext", {
|
|
|
1435
908
|
return useFluidContext;
|
|
1436
909
|
}
|
|
1437
910
|
});
|
|
1438
|
-
Object.defineProperty(exports, "useMessagingAuth", {
|
|
1439
|
-
enumerable: true,
|
|
1440
|
-
get: function() {
|
|
1441
|
-
return useMessagingAuth;
|
|
1442
|
-
}
|
|
1443
|
-
});
|
|
1444
|
-
Object.defineProperty(exports, "useMessagingConfig", {
|
|
1445
|
-
enumerable: true,
|
|
1446
|
-
get: function() {
|
|
1447
|
-
return useMessagingConfig;
|
|
1448
|
-
}
|
|
1449
|
-
});
|
|
1450
911
|
Object.defineProperty(exports, "useThemeContext", {
|
|
1451
912
|
enumerable: true,
|
|
1452
913
|
get: function() {
|
|
@@ -1454,4 +915,4 @@ Object.defineProperty(exports, "useThemeContext", {
|
|
|
1454
915
|
}
|
|
1455
916
|
});
|
|
1456
917
|
|
|
1457
|
-
//# sourceMappingURL=
|
|
918
|
+
//# sourceMappingURL=FluidProvider-C6SCZDjX.cjs.map
|