@churchapps/apphelper 0.7.3 → 0.7.5
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/components/conversations/Conversations.d.ts +21 -0
- package/dist/components/conversations/Conversations.d.ts.map +1 -0
- package/dist/components/conversations/Conversations.js +92 -0
- package/dist/components/conversations/Conversations.js.map +1 -0
- package/dist/components/conversations/index.d.ts +2 -0
- package/dist/components/conversations/index.d.ts.map +1 -0
- package/dist/components/conversations/index.js +2 -0
- package/dist/components/conversations/index.js.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/notes/AddNote.d.ts.map +1 -1
- package/dist/components/notes/AddNote.js +19 -1
- package/dist/components/notes/AddNote.js.map +1 -1
- package/dist/components/notes/Notes.d.ts.map +1 -1
- package/dist/components/notes/Notes.js +89 -74
- package/dist/components/notes/Notes.js.map +1 -1
- package/dist/components/notes/SubscriptionToggle.d.ts +38 -0
- package/dist/components/notes/SubscriptionToggle.d.ts.map +1 -0
- package/dist/components/notes/SubscriptionToggle.js +76 -0
- package/dist/components/notes/SubscriptionToggle.js.map +1 -0
- package/dist/components/notes/index.d.ts +1 -0
- package/dist/components/notes/index.d.ts.map +1 -1
- package/dist/components/notes/index.js +1 -0
- package/dist/components/notes/index.js.map +1 -1
- package/dist/components/wrapper/PrivateMessages.d.ts.map +1 -1
- package/dist/components/wrapper/PrivateMessages.js +12 -0
- package/dist/components/wrapper/PrivateMessages.js.map +1 -1
- package/dist/helpers/ConversationStore.d.ts +36 -0
- package/dist/helpers/ConversationStore.d.ts.map +1 -0
- package/dist/helpers/ConversationStore.js +238 -0
- package/dist/helpers/ConversationStore.js.map +1 -0
- package/dist/helpers/NotificationService.d.ts +3 -0
- package/dist/helpers/NotificationService.d.ts.map +1 -1
- package/dist/helpers/NotificationService.js +52 -13
- package/dist/helpers/NotificationService.js.map +1 -1
- package/dist/helpers/PresenceStore.d.ts +34 -0
- package/dist/helpers/PresenceStore.d.ts.map +1 -0
- package/dist/helpers/PresenceStore.js +93 -0
- package/dist/helpers/PresenceStore.js.map +1 -0
- package/dist/helpers/SocketHelper.d.ts +17 -0
- package/dist/helpers/SocketHelper.d.ts.map +1 -1
- package/dist/helpers/SocketHelper.js +70 -3
- package/dist/helpers/SocketHelper.js.map +1 -1
- package/dist/helpers/SubscriptionManager.d.ts +23 -0
- package/dist/helpers/SubscriptionManager.d.ts.map +1 -0
- package/dist/helpers/SubscriptionManager.js +118 -0
- package/dist/helpers/SubscriptionManager.js.map +1 -0
- package/dist/helpers/WebPushHelper.d.ts +36 -0
- package/dist/helpers/WebPushHelper.d.ts.map +1 -0
- package/dist/helpers/WebPushHelper.js +180 -0
- package/dist/helpers/WebPushHelper.js.map +1 -0
- package/dist/helpers/__tests__/WebPushHelper.test.d.ts +13 -0
- package/dist/helpers/__tests__/WebPushHelper.test.d.ts.map +1 -0
- package/dist/helpers/__tests__/WebPushHelper.test.js +99 -0
- package/dist/helpers/__tests__/WebPushHelper.test.js.map +1 -0
- package/dist/helpers/index.d.ts +5 -0
- package/dist/helpers/index.d.ts.map +1 -1
- package/dist/helpers/index.js +4 -0
- package/dist/helpers/index.js.map +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useConversation.d.ts +36 -0
- package/dist/hooks/useConversation.d.ts.map +1 -0
- package/dist/hooks/useConversation.js +152 -0
- package/dist/hooks/useConversation.js.map +1 -0
- package/dist/website/components/admin/DroppableArea.d.ts.map +1 -1
- package/dist/website/components/admin/DroppableArea.js +124 -88
- package/dist/website/components/admin/DroppableArea.js.map +1 -1
- package/package.json +18 -10
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { ApiHelper, UserHelper } from "@churchapps/helpers";
|
|
2
|
+
const OPT_OUT_KEY = "ca-webpush-opt-out";
|
|
3
|
+
const LAST_PROMPT_KEY = "ca-webpush-last-prompt";
|
|
4
|
+
const PROMPT_COOLDOWN_MS = 7 * 24 * 60 * 60 * 1000;
|
|
5
|
+
let scope = "/";
|
|
6
|
+
let appName = "ChurchAppsPwa";
|
|
7
|
+
const urlBase64ToUint8Array = (base64) => {
|
|
8
|
+
const padding = "=".repeat((4 - (base64.length % 4)) % 4);
|
|
9
|
+
const normalized = (base64 + padding).replace(/-/g, "+").replace(/_/g, "/");
|
|
10
|
+
const raw = atob(normalized);
|
|
11
|
+
const out = new Uint8Array(raw.length);
|
|
12
|
+
for (let i = 0; i < raw.length; i++)
|
|
13
|
+
out[i] = raw.charCodeAt(i);
|
|
14
|
+
return out;
|
|
15
|
+
};
|
|
16
|
+
const isSupported = () => typeof window !== "undefined" &&
|
|
17
|
+
"serviceWorker" in navigator &&
|
|
18
|
+
"PushManager" in window &&
|
|
19
|
+
"Notification" in window;
|
|
20
|
+
/**
|
|
21
|
+
* Cross-app helper for registering a Web Push subscription with the MessagingApi.
|
|
22
|
+
* Hosts call WebPushHelper.configure({ scope, appName }) once at boot, then
|
|
23
|
+
* WebPushHelper.subscribe() at login (and on userChurch changes).
|
|
24
|
+
*
|
|
25
|
+
* The server stores the subscription under the active userChurch's churchId, so
|
|
26
|
+
* switching churches without re-enrolling would leave the device tied to the wrong
|
|
27
|
+
* tenant — call subscribe() again after each church switch.
|
|
28
|
+
*/
|
|
29
|
+
export const WebPushHelper = {
|
|
30
|
+
configure(options) {
|
|
31
|
+
if (options.scope)
|
|
32
|
+
scope = options.scope;
|
|
33
|
+
if (options.appName)
|
|
34
|
+
appName = options.appName;
|
|
35
|
+
},
|
|
36
|
+
isSupported,
|
|
37
|
+
isOptedOut() {
|
|
38
|
+
try {
|
|
39
|
+
return localStorage.getItem(OPT_OUT_KEY) === "1";
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
setOptedOut(value) {
|
|
46
|
+
try {
|
|
47
|
+
if (value)
|
|
48
|
+
localStorage.setItem(OPT_OUT_KEY, "1");
|
|
49
|
+
else
|
|
50
|
+
localStorage.removeItem(OPT_OUT_KEY);
|
|
51
|
+
}
|
|
52
|
+
catch { /* ignore */ }
|
|
53
|
+
},
|
|
54
|
+
canPromptNow() {
|
|
55
|
+
if (!isSupported())
|
|
56
|
+
return false;
|
|
57
|
+
if (Notification.permission !== "default")
|
|
58
|
+
return false;
|
|
59
|
+
if (WebPushHelper.isOptedOut())
|
|
60
|
+
return false;
|
|
61
|
+
try {
|
|
62
|
+
const last = Number(localStorage.getItem(LAST_PROMPT_KEY) || 0);
|
|
63
|
+
if (last && Date.now() - last < PROMPT_COOLDOWN_MS)
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
catch { /* ignore */ }
|
|
67
|
+
return true;
|
|
68
|
+
},
|
|
69
|
+
markPrompted() {
|
|
70
|
+
try {
|
|
71
|
+
localStorage.setItem(LAST_PROMPT_KEY, String(Date.now()));
|
|
72
|
+
}
|
|
73
|
+
catch { /* ignore */ }
|
|
74
|
+
},
|
|
75
|
+
isStandalone() {
|
|
76
|
+
if (typeof window === "undefined")
|
|
77
|
+
return false;
|
|
78
|
+
const mq = window.matchMedia?.("(display-mode: standalone)").matches;
|
|
79
|
+
const iosStandalone = window.navigator.standalone === true;
|
|
80
|
+
return !!(mq || iosStandalone);
|
|
81
|
+
},
|
|
82
|
+
async getRegistration() {
|
|
83
|
+
if (!isSupported())
|
|
84
|
+
return null;
|
|
85
|
+
try {
|
|
86
|
+
return (await navigator.serviceWorker.getRegistration(scope)) || null;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
async getExistingSubscription() {
|
|
93
|
+
const reg = await WebPushHelper.getRegistration();
|
|
94
|
+
if (!reg)
|
|
95
|
+
return null;
|
|
96
|
+
try {
|
|
97
|
+
return await reg.pushManager.getSubscription();
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
/**
|
|
104
|
+
* Subscribe (or re-enroll) the active user. Safe to call multiple times — the server
|
|
105
|
+
* upserts based on (churchId, fcmToken). Call after login and after any userChurch change.
|
|
106
|
+
*/
|
|
107
|
+
async subscribe() {
|
|
108
|
+
if (!isSupported() || !UserHelper.user?.id)
|
|
109
|
+
return null;
|
|
110
|
+
const reg = await WebPushHelper.getRegistration();
|
|
111
|
+
if (!reg)
|
|
112
|
+
return null;
|
|
113
|
+
const permission = await Notification.requestPermission();
|
|
114
|
+
WebPushHelper.markPrompted();
|
|
115
|
+
if (permission !== "granted")
|
|
116
|
+
return null;
|
|
117
|
+
const config = await ApiHelper.get("/webpush/publicKey", "MessagingApi");
|
|
118
|
+
const publicKey = config?.publicKey;
|
|
119
|
+
if (!publicKey || !config?.enabled)
|
|
120
|
+
return null;
|
|
121
|
+
const existing = await reg.pushManager.getSubscription();
|
|
122
|
+
if (existing) {
|
|
123
|
+
await WebPushHelper.postSubscription(existing);
|
|
124
|
+
WebPushHelper.setOptedOut(false);
|
|
125
|
+
return existing;
|
|
126
|
+
}
|
|
127
|
+
const subscription = await reg.pushManager.subscribe({
|
|
128
|
+
userVisibleOnly: true,
|
|
129
|
+
applicationServerKey: urlBase64ToUint8Array(publicKey)
|
|
130
|
+
});
|
|
131
|
+
await WebPushHelper.postSubscription(subscription);
|
|
132
|
+
WebPushHelper.setOptedOut(false);
|
|
133
|
+
return subscription;
|
|
134
|
+
},
|
|
135
|
+
/**
|
|
136
|
+
* Re-enroll the existing subscription (no permission prompt). Use this on userChurch
|
|
137
|
+
* change so the device record updates to the new church without re-prompting the user.
|
|
138
|
+
*/
|
|
139
|
+
async refreshEnrollment() {
|
|
140
|
+
if (!isSupported() || !UserHelper.user?.id)
|
|
141
|
+
return;
|
|
142
|
+
const sub = await WebPushHelper.getExistingSubscription();
|
|
143
|
+
if (!sub)
|
|
144
|
+
return;
|
|
145
|
+
await WebPushHelper.postSubscription(sub);
|
|
146
|
+
},
|
|
147
|
+
async unsubscribe() {
|
|
148
|
+
WebPushHelper.setOptedOut(true);
|
|
149
|
+
const sub = await WebPushHelper.getExistingSubscription();
|
|
150
|
+
if (!sub)
|
|
151
|
+
return;
|
|
152
|
+
const endpoint = sub.endpoint;
|
|
153
|
+
try {
|
|
154
|
+
await sub.unsubscribe();
|
|
155
|
+
}
|
|
156
|
+
catch { /* ignore */ }
|
|
157
|
+
try {
|
|
158
|
+
await ApiHelper.post("/webpush/unsubscribe", { endpoint }, "MessagingApi");
|
|
159
|
+
}
|
|
160
|
+
catch { /* ignore */ }
|
|
161
|
+
},
|
|
162
|
+
async postSubscription(sub) {
|
|
163
|
+
const json = sub.toJSON();
|
|
164
|
+
if (!json.endpoint || !json.keys?.p256dh || !json.keys?.auth)
|
|
165
|
+
return;
|
|
166
|
+
const body = {
|
|
167
|
+
subscription: {
|
|
168
|
+
endpoint: json.endpoint,
|
|
169
|
+
keys: { p256dh: json.keys.p256dh, auth: json.keys.auth }
|
|
170
|
+
},
|
|
171
|
+
appName,
|
|
172
|
+
deviceInfo: typeof navigator !== "undefined" ? navigator.userAgent : undefined
|
|
173
|
+
};
|
|
174
|
+
try {
|
|
175
|
+
await ApiHelper.post("/webpush/subscribe", body, "MessagingApi");
|
|
176
|
+
}
|
|
177
|
+
catch { /* ignore */ }
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=WebPushHelper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebPushHelper.js","sourceRoot":"","sources":["../../src/helpers/WebPushHelper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vitest-environment jsdom
|
|
3
|
+
*
|
|
4
|
+
* Unit test for the consolidated apphelper WebPushHelper.subscribe() flow.
|
|
5
|
+
* Stubs the browser push APIs + the underlying ApiHelper, then runs subscribe()
|
|
6
|
+
* end-to-end and asserts:
|
|
7
|
+
* - the right VAPID public key is fetched from the server
|
|
8
|
+
* - pushManager.subscribe is called with userVisibleOnly + the decoded VAPID key
|
|
9
|
+
* - POST /webpush/subscribe is called with the right body shape (the same shape
|
|
10
|
+
* the server's `webpush:` token decoder expects)
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=WebPushHelper.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebPushHelper.test.d.ts","sourceRoot":"","sources":["../../../src/helpers/__tests__/WebPushHelper.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vitest-environment jsdom
|
|
3
|
+
*
|
|
4
|
+
* Unit test for the consolidated apphelper WebPushHelper.subscribe() flow.
|
|
5
|
+
* Stubs the browser push APIs + the underlying ApiHelper, then runs subscribe()
|
|
6
|
+
* end-to-end and asserts:
|
|
7
|
+
* - the right VAPID public key is fetched from the server
|
|
8
|
+
* - pushManager.subscribe is called with userVisibleOnly + the decoded VAPID key
|
|
9
|
+
* - POST /webpush/subscribe is called with the right body shape (the same shape
|
|
10
|
+
* the server's `webpush:` token decoder expects)
|
|
11
|
+
*/
|
|
12
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
13
|
+
// Mock @churchapps/helpers — WebPushHelper imports ApiHelper + UserHelper from there.
|
|
14
|
+
const apiPostMock = vi.fn().mockResolvedValue(undefined);
|
|
15
|
+
const apiGetMock = vi.fn().mockResolvedValue({ publicKey: "BNcRdreALRFXTkOOUHK1EtK2wtaz5Ry4YfYCA_0QTpQtUbVlUls0VJXg7A8u-Ts1XbjhazAkj7I99e8QcYP7DkM", enabled: true });
|
|
16
|
+
vi.mock("@churchapps/helpers", () => ({
|
|
17
|
+
ApiHelper: { get: apiGetMock, post: apiPostMock },
|
|
18
|
+
UserHelper: { user: { id: "USR00000001" } },
|
|
19
|
+
}));
|
|
20
|
+
const { WebPushHelper } = await import("../WebPushHelper");
|
|
21
|
+
describe("WebPushHelper.subscribe", () => {
|
|
22
|
+
let fakeSubscription;
|
|
23
|
+
let pushManagerSubscribeMock;
|
|
24
|
+
let pushManagerGetSubscriptionMock;
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
apiPostMock.mockClear();
|
|
27
|
+
apiGetMock.mockClear();
|
|
28
|
+
fakeSubscription = {
|
|
29
|
+
endpoint: `https://example-push.test/endpoint/${Date.now()}`,
|
|
30
|
+
toJSON() {
|
|
31
|
+
return {
|
|
32
|
+
endpoint: this.endpoint,
|
|
33
|
+
keys: { p256dh: "p256dh-fake", auth: "auth-fake" },
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
pushManagerSubscribeMock = vi.fn().mockResolvedValue(fakeSubscription);
|
|
38
|
+
pushManagerGetSubscriptionMock = vi.fn().mockResolvedValue(null);
|
|
39
|
+
const fakeRegistration = {
|
|
40
|
+
scope: "/mobile",
|
|
41
|
+
pushManager: {
|
|
42
|
+
subscribe: pushManagerSubscribeMock,
|
|
43
|
+
getSubscription: pushManagerGetSubscriptionMock,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
Object.defineProperty(navigator, "serviceWorker", {
|
|
47
|
+
configurable: true,
|
|
48
|
+
value: {
|
|
49
|
+
getRegistration: vi.fn().mockResolvedValue(fakeRegistration),
|
|
50
|
+
register: vi.fn().mockResolvedValue(fakeRegistration),
|
|
51
|
+
ready: Promise.resolve(fakeRegistration),
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
// PushManager presence is what isSupported() checks for
|
|
55
|
+
window.PushManager = function () { };
|
|
56
|
+
// Notification API
|
|
57
|
+
window.Notification = function () { };
|
|
58
|
+
window.Notification.permission = "default";
|
|
59
|
+
window.Notification.requestPermission = vi.fn().mockResolvedValue("granted");
|
|
60
|
+
// Clear any prior opt-out / cooldown state in the jsdom localStorage
|
|
61
|
+
window.localStorage.clear();
|
|
62
|
+
});
|
|
63
|
+
it("posts a webpush subscription to the server when the user grants permission", async () => {
|
|
64
|
+
WebPushHelper.configure({ scope: "/mobile", appName: "B1AppPwa" });
|
|
65
|
+
const sub = await WebPushHelper.subscribe();
|
|
66
|
+
expect(sub).toBeTruthy();
|
|
67
|
+
expect(sub?.endpoint).toBe(fakeSubscription.endpoint);
|
|
68
|
+
// VAPID public key request to the server
|
|
69
|
+
expect(apiGetMock).toHaveBeenCalledWith("/webpush/publicKey", "MessagingApi");
|
|
70
|
+
// pushManager.subscribe was called with userVisibleOnly + the decoded key bytes
|
|
71
|
+
expect(pushManagerSubscribeMock).toHaveBeenCalledTimes(1);
|
|
72
|
+
const args = pushManagerSubscribeMock.mock.calls[0][0];
|
|
73
|
+
expect(args.userVisibleOnly).toBe(true);
|
|
74
|
+
expect(args.applicationServerKey).toBeInstanceOf(Uint8Array);
|
|
75
|
+
// The subscription POST carries the right body shape
|
|
76
|
+
expect(apiPostMock).toHaveBeenCalledWith("/webpush/subscribe", expect.objectContaining({
|
|
77
|
+
appName: "B1AppPwa",
|
|
78
|
+
subscription: expect.objectContaining({
|
|
79
|
+
endpoint: fakeSubscription.endpoint,
|
|
80
|
+
keys: expect.objectContaining({ p256dh: "p256dh-fake", auth: "auth-fake" }),
|
|
81
|
+
}),
|
|
82
|
+
}), "MessagingApi");
|
|
83
|
+
});
|
|
84
|
+
it("returns null and does not POST if permission is denied", async () => {
|
|
85
|
+
window.Notification.requestPermission = vi.fn().mockResolvedValue("denied");
|
|
86
|
+
const sub = await WebPushHelper.subscribe();
|
|
87
|
+
expect(sub).toBeNull();
|
|
88
|
+
expect(apiPostMock).not.toHaveBeenCalled();
|
|
89
|
+
expect(pushManagerSubscribeMock).not.toHaveBeenCalled();
|
|
90
|
+
});
|
|
91
|
+
it("re-posts an existing subscription instead of subscribing again", async () => {
|
|
92
|
+
pushManagerGetSubscriptionMock.mockResolvedValue(fakeSubscription);
|
|
93
|
+
const sub = await WebPushHelper.subscribe();
|
|
94
|
+
expect(sub).toBeTruthy();
|
|
95
|
+
expect(pushManagerSubscribeMock).not.toHaveBeenCalled();
|
|
96
|
+
expect(apiPostMock).toHaveBeenCalledTimes(1);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
//# sourceMappingURL=WebPushHelper.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebPushHelper.test.js","sourceRoot":"","sources":["../../../src/helpers/__tests__/WebPushHelper.test.ts"],"names":[],"mappings":"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"}
|
package/dist/helpers/index.d.ts
CHANGED
|
@@ -7,6 +7,11 @@ export { createEmotionCache } from "./createEmotionCache";
|
|
|
7
7
|
export { Locale } from "./Locale";
|
|
8
8
|
export { SlugHelper } from "./SlugHelper";
|
|
9
9
|
export { SocketHelper } from "./SocketHelper";
|
|
10
|
+
export { SubscriptionManager } from "./SubscriptionManager";
|
|
11
|
+
export { ConversationStore } from "./ConversationStore";
|
|
12
|
+
export { PresenceStore } from "./PresenceStore";
|
|
13
|
+
export type { PresenceSnapshot, PresenceViewer } from "./PresenceStore";
|
|
10
14
|
export { NotificationService } from "./NotificationService";
|
|
11
15
|
export type { NotificationCounts } from "./NotificationService";
|
|
16
|
+
export { WebPushHelper } from "./WebPushHelper";
|
|
12
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EACT,gBAAgB,IAAI,oBAAoB,EACxC,WAAW,EACX,uBAAuB,EACvB,cAAc,EACd,UAAU,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,YAAY,EACZ,UAAU,EACV,cAAc,EACd,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,aAAa,EACb,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,6BAA6B,EAC7B,8BAA8B,EAC9B,mBAAmB,EACnB,4BAA4B,EAC5B,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,EACd,qBAAqB,EACtB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EACT,gBAAgB,IAAI,oBAAoB,EACxC,WAAW,EACX,uBAAuB,EACvB,cAAc,EACd,UAAU,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,YAAY,EACZ,UAAU,EACV,cAAc,EACd,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,aAAa,EACb,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,6BAA6B,EAC7B,8BAA8B,EAC9B,mBAAmB,EACnB,4BAA4B,EAC5B,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,EACd,qBAAqB,EACtB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/helpers/index.js
CHANGED
|
@@ -7,5 +7,9 @@ export { createEmotionCache } from "./createEmotionCache";
|
|
|
7
7
|
export { Locale } from "./Locale";
|
|
8
8
|
export { SlugHelper } from "./SlugHelper";
|
|
9
9
|
export { SocketHelper } from "./SocketHelper";
|
|
10
|
+
export { SubscriptionManager } from "./SubscriptionManager";
|
|
11
|
+
export { ConversationStore } from "./ConversationStore";
|
|
12
|
+
export { PresenceStore } from "./PresenceStore";
|
|
10
13
|
export { NotificationService } from "./NotificationService";
|
|
14
|
+
export { WebPushHelper } from "./WebPushHelper";
|
|
11
15
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,OAAO,EACL,SAAS,EACT,gBAAgB,IAAI,oBAAoB,EACxC,WAAW,EACX,uBAAuB,EACvB,cAAc,EACd,UAAU,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,YAAY,EACZ,UAAU,EACV,cAAc,EACd,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAiC7B,uBAAuB;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,OAAO,EACL,SAAS,EACT,gBAAgB,IAAI,oBAAoB,EACxC,WAAW,EACX,uBAAuB,EACvB,cAAc,EACd,UAAU,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,YAAY,EACZ,UAAU,EACV,cAAc,EACd,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAiC7B,uBAAuB;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { useMountedState } from "./useMountedState";
|
|
2
2
|
export { useNotifications } from "./useNotifications";
|
|
3
3
|
export type { UseNotificationsResult } from "./useNotifications";
|
|
4
|
+
export { useConversation } from "./useConversation";
|
|
5
|
+
export type { UseConversationOptions, UseConversationResult } from "./useConversation";
|
|
4
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/hooks/index.js
CHANGED
package/dist/hooks/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ConversationInterface, MessageInterface, UserContextInterface } from "@churchapps/helpers";
|
|
2
|
+
export interface UseConversationOptions {
|
|
3
|
+
/** content-keyed lookup (e.g. group, person, sermon, contentBlock). If contentId is empty, the hook is idle. */
|
|
4
|
+
contentType?: string;
|
|
5
|
+
contentId?: string;
|
|
6
|
+
/** direct conversation id lookup (used by private messages where the conversation already exists). */
|
|
7
|
+
conversationId?: string;
|
|
8
|
+
/** required for join/leave room calls. */
|
|
9
|
+
context?: UserContextInterface;
|
|
10
|
+
/** if no conversation exists for this content yet, create one with this groupId/visibility on first post. */
|
|
11
|
+
groupId?: string;
|
|
12
|
+
visibility?: string;
|
|
13
|
+
/** if true, the hook does not auto-join the realtime room. Used for transient previews. */
|
|
14
|
+
skipSubscribe?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface UseConversationResult {
|
|
17
|
+
conversation: ConversationInterface | null;
|
|
18
|
+
messages: MessageInterface[];
|
|
19
|
+
isLoading: boolean;
|
|
20
|
+
error: string | null;
|
|
21
|
+
refresh: () => Promise<void>;
|
|
22
|
+
post: (content: string, messageType?: string) => Promise<MessageInterface | null>;
|
|
23
|
+
edit: (messageId: string, content: string) => Promise<void>;
|
|
24
|
+
remove: (messageId: string) => Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Subscribe to a conversation, get a live message list, and post/edit/delete.
|
|
28
|
+
*
|
|
29
|
+
* - On mount: hydrates via REST (by contentType/contentId or by conversationId) and joins the
|
|
30
|
+
* server room via SubscriptionManager so socket events update the store automatically.
|
|
31
|
+
* - On unmount: leaves the room (ref-counted, so multiple consumers of the same conversation share one join).
|
|
32
|
+
* - Mutations write to /messages and rely on the server's broadcast to fan out — including
|
|
33
|
+
* to this same tab, so we do not optimistically apply.
|
|
34
|
+
*/
|
|
35
|
+
export declare function useConversation(opts: UseConversationOptions): UseConversationResult;
|
|
36
|
+
//# sourceMappingURL=useConversation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useConversation.d.ts","sourceRoot":"","sources":["../../src/hooks/useConversation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,qBAAqB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAI/G,MAAM,WAAW,sBAAsB;IACrC,gHAAgH;IAChH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sGAAsG;IACtG,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,6GAA6G;IAC7G,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2FAA2F;IAC3F,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC3C,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAClF,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,qBAAqB,CAqInF"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { ApiHelper } from "@churchapps/helpers";
|
|
4
|
+
import { ConversationStore } from "../helpers/ConversationStore";
|
|
5
|
+
import { SubscriptionManager } from "../helpers/SubscriptionManager";
|
|
6
|
+
/**
|
|
7
|
+
* Subscribe to a conversation, get a live message list, and post/edit/delete.
|
|
8
|
+
*
|
|
9
|
+
* - On mount: hydrates via REST (by contentType/contentId or by conversationId) and joins the
|
|
10
|
+
* server room via SubscriptionManager so socket events update the store automatically.
|
|
11
|
+
* - On unmount: leaves the room (ref-counted, so multiple consumers of the same conversation share one join).
|
|
12
|
+
* - Mutations write to /messages and rely on the server's broadcast to fan out — including
|
|
13
|
+
* to this same tab, so we do not optimistically apply.
|
|
14
|
+
*/
|
|
15
|
+
export function useConversation(opts) {
|
|
16
|
+
const [conversation, setConversation] = useState(null);
|
|
17
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
18
|
+
const [error, setError] = useState(null);
|
|
19
|
+
const churchId = opts.context?.userChurch?.church?.id;
|
|
20
|
+
const personId = opts.context?.person?.id;
|
|
21
|
+
const displayName = opts.context?.person ? `${opts.context.person.name?.first ?? ""} ${opts.context.person.name?.last ?? ""}`.trim() : "";
|
|
22
|
+
const hydrate = useCallback(async () => {
|
|
23
|
+
setError(null);
|
|
24
|
+
try {
|
|
25
|
+
if (opts.conversationId) {
|
|
26
|
+
return await ConversationStore.loadByConversationId(opts.conversationId);
|
|
27
|
+
}
|
|
28
|
+
if (opts.contentType && opts.contentId) {
|
|
29
|
+
return await ConversationStore.loadByContent(opts.contentType, opts.contentId);
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
setError(err?.message || "Failed to load conversation");
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}, [opts.contentType, opts.contentId, opts.conversationId]);
|
|
38
|
+
// Initial hydration + subscribe
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
let cancelled = false;
|
|
41
|
+
let unsubscribe = null;
|
|
42
|
+
let joinedConversationId = null;
|
|
43
|
+
(async () => {
|
|
44
|
+
setIsLoading(true);
|
|
45
|
+
const conv = await hydrate();
|
|
46
|
+
if (cancelled)
|
|
47
|
+
return;
|
|
48
|
+
if (conv?.id) {
|
|
49
|
+
unsubscribe = ConversationStore.subscribe(conv.id, (updated) => {
|
|
50
|
+
if (!cancelled)
|
|
51
|
+
setConversation(updated);
|
|
52
|
+
});
|
|
53
|
+
if (!opts.skipSubscribe && churchId) {
|
|
54
|
+
joinedConversationId = conv.id;
|
|
55
|
+
await SubscriptionManager.joinRoom(conv.id, churchId, personId, displayName);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// also subscribe by direct conversationId even if REST returned nothing yet
|
|
59
|
+
else if (opts.conversationId) {
|
|
60
|
+
unsubscribe = ConversationStore.subscribe(opts.conversationId, (updated) => {
|
|
61
|
+
if (!cancelled)
|
|
62
|
+
setConversation(updated);
|
|
63
|
+
});
|
|
64
|
+
if (!opts.skipSubscribe && churchId) {
|
|
65
|
+
joinedConversationId = opts.conversationId;
|
|
66
|
+
await SubscriptionManager.joinRoom(opts.conversationId, churchId, personId, displayName);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!cancelled)
|
|
70
|
+
setIsLoading(false);
|
|
71
|
+
})();
|
|
72
|
+
return () => {
|
|
73
|
+
cancelled = true;
|
|
74
|
+
if (unsubscribe)
|
|
75
|
+
unsubscribe();
|
|
76
|
+
if (joinedConversationId && churchId) {
|
|
77
|
+
SubscriptionManager.leaveRoom(joinedConversationId, churchId).catch(() => { });
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}, [hydrate, churchId, personId, displayName, opts.skipSubscribe, opts.conversationId]);
|
|
81
|
+
const refresh = useCallback(async () => {
|
|
82
|
+
setIsLoading(true);
|
|
83
|
+
await hydrate();
|
|
84
|
+
setIsLoading(false);
|
|
85
|
+
}, [hydrate]);
|
|
86
|
+
const ensureConversationId = useCallback(async () => {
|
|
87
|
+
if (conversation?.id)
|
|
88
|
+
return conversation.id;
|
|
89
|
+
if (opts.conversationId)
|
|
90
|
+
return opts.conversationId;
|
|
91
|
+
if (!opts.contentType || !opts.contentId)
|
|
92
|
+
return null;
|
|
93
|
+
const newConv = {
|
|
94
|
+
contentType: opts.contentType,
|
|
95
|
+
contentId: opts.contentId,
|
|
96
|
+
groupId: opts.groupId,
|
|
97
|
+
visibility: opts.visibility ?? "public",
|
|
98
|
+
title: `${opts.contentType}-${opts.contentId} Conversation`,
|
|
99
|
+
allowAnonymousPosts: false
|
|
100
|
+
};
|
|
101
|
+
const result = await ApiHelper.post("/conversations", [newConv], "MessagingApi");
|
|
102
|
+
const created = Array.isArray(result) ? result[0] : result;
|
|
103
|
+
if (!created?.id)
|
|
104
|
+
return null;
|
|
105
|
+
ConversationStore.setConversation({ ...created, messages: [] });
|
|
106
|
+
if (churchId)
|
|
107
|
+
await SubscriptionManager.joinRoom(created.id, churchId, personId, displayName);
|
|
108
|
+
return created.id;
|
|
109
|
+
}, [conversation?.id, opts.conversationId, opts.contentType, opts.contentId, opts.groupId, opts.visibility, churchId, personId, displayName]);
|
|
110
|
+
const post = useCallback(async (content, messageType = "comment") => {
|
|
111
|
+
const trimmed = content?.trim();
|
|
112
|
+
if (!trimmed)
|
|
113
|
+
return null;
|
|
114
|
+
const targetConversationId = await ensureConversationId();
|
|
115
|
+
if (!targetConversationId) {
|
|
116
|
+
setError("Cannot post: missing conversation context");
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
const message = {
|
|
120
|
+
conversationId: targetConversationId,
|
|
121
|
+
messageType,
|
|
122
|
+
content: trimmed,
|
|
123
|
+
personId
|
|
124
|
+
};
|
|
125
|
+
const result = await ApiHelper.post("/messages", [message], "MessagingApi");
|
|
126
|
+
return Array.isArray(result) ? result[0] : result;
|
|
127
|
+
}, [ensureConversationId, personId]);
|
|
128
|
+
const edit = useCallback(async (messageId, content) => {
|
|
129
|
+
const trimmed = content?.trim();
|
|
130
|
+
if (!trimmed)
|
|
131
|
+
return;
|
|
132
|
+
const targetConversationId = conversation?.id || opts.conversationId;
|
|
133
|
+
if (!targetConversationId)
|
|
134
|
+
return;
|
|
135
|
+
const message = { id: messageId, conversationId: targetConversationId, content: trimmed };
|
|
136
|
+
await ApiHelper.post("/messages", [message], "MessagingApi");
|
|
137
|
+
}, [conversation?.id, opts.conversationId]);
|
|
138
|
+
const remove = useCallback(async (messageId) => {
|
|
139
|
+
await ApiHelper.delete(`/messages/${messageId}`, "MessagingApi");
|
|
140
|
+
}, []);
|
|
141
|
+
return {
|
|
142
|
+
conversation,
|
|
143
|
+
messages: conversation?.messages ?? [],
|
|
144
|
+
isLoading,
|
|
145
|
+
error,
|
|
146
|
+
refresh,
|
|
147
|
+
post,
|
|
148
|
+
edit,
|
|
149
|
+
remove
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=useConversation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useConversation.js","sourceRoot":"","sources":["../../src/hooks/useConversation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DroppableArea.d.ts","sourceRoot":"","sources":["../../../../src/website/components/admin/DroppableArea.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAGlE,KAAK,KAAK,GAAG;IACX,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,MAAM,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAA;IAChD,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B,CAAC;
|
|
1
|
+
{"version":3,"file":"DroppableArea.d.ts","sourceRoot":"","sources":["../../../../src/website/components/admin/DroppableArea.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAGlE,KAAK,KAAK,GAAG;IACX,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,MAAM,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAA;IAChD,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B,CAAC;AA+FF,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,2CAmEzC"}
|