@realtimexsco/live-chat 1.4.9 → 1.4.11
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/firebase-messaging-sw.js +312 -71
- package/dist/index.cjs +1029 -641
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +128 -37
- package/dist/index.d.ts +128 -37
- package/dist/index.mjs +1019 -637
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +11 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4,16 +4,16 @@ import { create } from 'zustand';
|
|
|
4
4
|
import { persist } from 'zustand/middleware';
|
|
5
5
|
import * as React2 from 'react';
|
|
6
6
|
import React2__default, { createContext, useMemo, useContext, useState, useCallback, useRef, useEffect, useLayoutEffect, useSyncExternalStore } from 'react';
|
|
7
|
-
import { Tooltip as Tooltip$1, Slot,
|
|
7
|
+
import { Tooltip as Tooltip$1, Slot, Switch as Switch$1, Dialog as Dialog$1, Avatar as Avatar$1, ScrollArea as ScrollArea$1, Popover as Popover$1, DropdownMenu as DropdownMenu$1, AlertDialog as AlertDialog$1 } from 'radix-ui';
|
|
8
8
|
import { clsx } from 'clsx';
|
|
9
9
|
import { twMerge } from 'tailwind-merge';
|
|
10
10
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
11
11
|
import { flushSync } from 'react-dom';
|
|
12
|
-
import { Sun, Moon, Search, X,
|
|
12
|
+
import { Sun, Moon, Loader2, Settings, Search, X, UserPlus, ChevronDown, ArrowLeft, Users, WifiOff, Wifi, Sparkles, MessageSquareText, ChevronRight, Pin, Star, MoreVertical, Info, UserKey, ShieldUser, Paperclip, Clock, MessageSquareX, Trash2, LogOut, Ban, CheckCheck, Check, Camera, Save, Pencil, Mail, CornerUpLeft, CheckSquare, Smile, ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon, MessageCircleMore, History, Shield, Send, AlertCircle, ShieldCheck, UserMinus, MessageCircle, Phone, Video, ExternalLink, Download, ChevronLeft, ZoomOut, ZoomIn, RotateCcw, Music, XIcon, ArrowRight, MoreHorizontal, PinOff, StarOff, ImageIcon, Film, Play, Pause, FileText, FileSpreadsheet, FileIcon, MessageSquare, Eye, Captions } from 'lucide-react';
|
|
13
13
|
import { cva } from 'class-variance-authority';
|
|
14
14
|
import EmojiPicker, { Theme } from 'emoji-picker-react';
|
|
15
15
|
import { getDefaultClassNames, DayPicker } from 'react-day-picker';
|
|
16
|
-
import
|
|
16
|
+
import toast$1, { Toaster, toast } from 'react-hot-toast';
|
|
17
17
|
|
|
18
18
|
var __defProp = Object.defineProperty;
|
|
19
19
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -1223,6 +1223,64 @@ var init_query_params = __esm({
|
|
|
1223
1223
|
];
|
|
1224
1224
|
}
|
|
1225
1225
|
});
|
|
1226
|
+
|
|
1227
|
+
// src/services/api/api-version.ts
|
|
1228
|
+
var DEFAULT_VERSIONS, apiVersions, normalizeApiVersion, resolveApiRoot, buildVersionedApiUrl, setChatApiVersions, getChatApiVersions, setChatPushApiVersion, syncDefaultApiVersionFromBaseUrl;
|
|
1229
|
+
var init_api_version = __esm({
|
|
1230
|
+
"src/services/api/api-version.ts"() {
|
|
1231
|
+
init_client();
|
|
1232
|
+
DEFAULT_VERSIONS = {
|
|
1233
|
+
default: "v1",
|
|
1234
|
+
push: "v2"
|
|
1235
|
+
};
|
|
1236
|
+
apiVersions = { ...DEFAULT_VERSIONS };
|
|
1237
|
+
normalizeApiVersion = (version) => {
|
|
1238
|
+
const raw = String(version || "v1").trim().replace(/^\/+|\/+$/g, "");
|
|
1239
|
+
if (!raw) return "v1";
|
|
1240
|
+
return /^v\d+$/i.test(raw) ? raw.toLowerCase() : `v${raw}`;
|
|
1241
|
+
};
|
|
1242
|
+
resolveApiRoot = (baseUrl) => {
|
|
1243
|
+
const raw = String(
|
|
1244
|
+
baseUrl || getChatBaseUrl() || apiClient.defaults.baseURL || ""
|
|
1245
|
+
).trim().replace(/\/$/, "");
|
|
1246
|
+
if (!raw) return "";
|
|
1247
|
+
const withoutVersion = raw.replace(/\/v\d+$/i, "");
|
|
1248
|
+
return withoutVersion || raw;
|
|
1249
|
+
};
|
|
1250
|
+
buildVersionedApiUrl = (path, options) => {
|
|
1251
|
+
const root = resolveApiRoot(options?.baseUrl);
|
|
1252
|
+
const version = normalizeApiVersion(
|
|
1253
|
+
options?.version ?? (options?.service ? apiVersions[options.service] : apiVersions.default)
|
|
1254
|
+
);
|
|
1255
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
1256
|
+
if (!root) {
|
|
1257
|
+
return `/${version}${normalizedPath}`;
|
|
1258
|
+
}
|
|
1259
|
+
return `${root}/${version}${normalizedPath}`;
|
|
1260
|
+
};
|
|
1261
|
+
setChatApiVersions = (config) => {
|
|
1262
|
+
if (!config) return;
|
|
1263
|
+
if (config.default) {
|
|
1264
|
+
apiVersions.default = normalizeApiVersion(config.default);
|
|
1265
|
+
}
|
|
1266
|
+
if (config.push) {
|
|
1267
|
+
apiVersions.push = normalizeApiVersion(config.push);
|
|
1268
|
+
}
|
|
1269
|
+
};
|
|
1270
|
+
getChatApiVersions = () => ({
|
|
1271
|
+
...apiVersions
|
|
1272
|
+
});
|
|
1273
|
+
setChatPushApiVersion = (version) => {
|
|
1274
|
+
apiVersions.push = normalizeApiVersion(version);
|
|
1275
|
+
};
|
|
1276
|
+
syncDefaultApiVersionFromBaseUrl = (baseUrl) => {
|
|
1277
|
+
const match = String(baseUrl || "").trim().match(/\/(v\d+)\/?$/i);
|
|
1278
|
+
if (match?.[1]) {
|
|
1279
|
+
apiVersions.default = normalizeApiVersion(match[1]);
|
|
1280
|
+
}
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
});
|
|
1226
1284
|
function resolveParamsForRequest(url, method) {
|
|
1227
1285
|
const apiKey = resolveChatApiKey(url);
|
|
1228
1286
|
const httpMethod = (method || "get").toLowerCase();
|
|
@@ -1239,7 +1297,9 @@ var chatClientId, chatAccessToken, chatBaseUrl, chatSocketUrl, chatQueryParams,
|
|
|
1239
1297
|
var init_client = __esm({
|
|
1240
1298
|
"src/services/api/client.ts"() {
|
|
1241
1299
|
init_query_params();
|
|
1300
|
+
init_api_version();
|
|
1242
1301
|
init_query_params();
|
|
1302
|
+
init_api_version();
|
|
1243
1303
|
chatClientId = "";
|
|
1244
1304
|
chatAccessToken = "";
|
|
1245
1305
|
chatBaseUrl = "";
|
|
@@ -1257,6 +1317,7 @@ var init_client = __esm({
|
|
|
1257
1317
|
setChatBaseURL = (url) => {
|
|
1258
1318
|
chatBaseUrl = url.trim();
|
|
1259
1319
|
apiClient.defaults.baseURL = chatBaseUrl;
|
|
1320
|
+
syncDefaultApiVersionFromBaseUrl(chatBaseUrl);
|
|
1260
1321
|
};
|
|
1261
1322
|
getChatBaseUrl = () => chatBaseUrl;
|
|
1262
1323
|
setChatSocketUrl = (url) => {
|
|
@@ -3722,7 +3783,7 @@ function resolveApiUrl(apiUrl) {
|
|
|
3722
3783
|
function resolveSocketUrl(socketUrl, apiUrl) {
|
|
3723
3784
|
const explicit = (socketUrl ?? "").trim();
|
|
3724
3785
|
if (explicit) return explicit;
|
|
3725
|
-
return resolveApiUrl(apiUrl).replace(/\/api\/
|
|
3786
|
+
return resolveApiUrl(apiUrl).replace(/\/api\/v\d+\/?$/i, "");
|
|
3726
3787
|
}
|
|
3727
3788
|
|
|
3728
3789
|
// src/hooks/chat-sync/useChatSync.ts
|
|
@@ -4469,6 +4530,7 @@ var Chat = ({
|
|
|
4469
4530
|
queryParams,
|
|
4470
4531
|
queryParamApis,
|
|
4471
4532
|
queryParamsByApi,
|
|
4533
|
+
apiVersions: apiVersions2,
|
|
4472
4534
|
channelsData,
|
|
4473
4535
|
messagesData,
|
|
4474
4536
|
onMessageReceived,
|
|
@@ -4494,6 +4556,7 @@ var Chat = ({
|
|
|
4494
4556
|
const resolvedApiUrl = resolveApiUrl(apiUrl);
|
|
4495
4557
|
const resolvedSocketUrl = resolveSocketUrl(socketUrl, resolvedApiUrl);
|
|
4496
4558
|
if (resolvedApiUrl) setChatBaseURL(resolvedApiUrl);
|
|
4559
|
+
setChatApiVersions(apiVersions2);
|
|
4497
4560
|
if (resolvedSocketUrl) setChatSocketUrl(resolvedSocketUrl);
|
|
4498
4561
|
let currentToken = accessToken || "";
|
|
4499
4562
|
let sessionUser = resolveUserFromAccessToken(currentToken, loggedUserDetails);
|
|
@@ -4632,7 +4695,9 @@ init_store_helpers();
|
|
|
4632
4695
|
var OPEN_CONVERSATION_EVENT = "realtimex:open-conversation";
|
|
4633
4696
|
var NOTIFICATION_CLICK_SW_TYPE = "realtimex:notification-click";
|
|
4634
4697
|
var PUSH_BROADCAST_CHANNEL = "realtimex-push";
|
|
4698
|
+
var PUSH_DATA_CACHE_NAME = "realtimex-push-data-v1";
|
|
4635
4699
|
var PENDING_STORAGE_KEY = "realtimex:pending-open-conversation";
|
|
4700
|
+
var PENDING_OPEN_CACHE_PATH = "pending-open";
|
|
4636
4701
|
var resolveConversationIdFromPushData = (data) => {
|
|
4637
4702
|
if (!data || typeof data !== "object") return "";
|
|
4638
4703
|
let fcmMsg = data.FCM_MSG;
|
|
@@ -4773,6 +4838,37 @@ var mapConversationToChannel = (conversation, loggedUserId, allUsers) => {
|
|
|
4773
4838
|
starredCount: conversation.starredCount
|
|
4774
4839
|
};
|
|
4775
4840
|
};
|
|
4841
|
+
var stripConversationIdFromUrl = () => {
|
|
4842
|
+
if (typeof window === "undefined") return;
|
|
4843
|
+
try {
|
|
4844
|
+
const url = new URL(window.location.href);
|
|
4845
|
+
if (!url.searchParams.has("conversationId")) return;
|
|
4846
|
+
url.searchParams.delete("conversationId");
|
|
4847
|
+
const next = `${url.pathname}${url.search}${url.hash}`;
|
|
4848
|
+
window.history.replaceState(window.history.state, "", next);
|
|
4849
|
+
} catch {
|
|
4850
|
+
}
|
|
4851
|
+
};
|
|
4852
|
+
var cacheRequestForPath = (path) => new Request(new URL(path, window.location.origin).toString());
|
|
4853
|
+
var consumePendingOpenFromPushCache = async () => {
|
|
4854
|
+
if (typeof caches === "undefined") return null;
|
|
4855
|
+
try {
|
|
4856
|
+
const cache = await caches.open(PUSH_DATA_CACHE_NAME);
|
|
4857
|
+
const req = cacheRequestForPath(PENDING_OPEN_CACHE_PATH);
|
|
4858
|
+
const res = await cache.match(req);
|
|
4859
|
+
if (!res) return null;
|
|
4860
|
+
await cache.delete(req);
|
|
4861
|
+
const data = await res.json();
|
|
4862
|
+
const conversationId = resolveConversationIdFromPushData(data);
|
|
4863
|
+
if (!conversationId) return null;
|
|
4864
|
+
return {
|
|
4865
|
+
conversationId,
|
|
4866
|
+
...normalizePushMeta(data)
|
|
4867
|
+
};
|
|
4868
|
+
} catch {
|
|
4869
|
+
return null;
|
|
4870
|
+
}
|
|
4871
|
+
};
|
|
4776
4872
|
var readConversationIdFromLocation = () => {
|
|
4777
4873
|
try {
|
|
4778
4874
|
return new URLSearchParams(window.location.search).get("conversationId") || "";
|
|
@@ -4781,16 +4877,33 @@ var readConversationIdFromLocation = () => {
|
|
|
4781
4877
|
}
|
|
4782
4878
|
};
|
|
4783
4879
|
var consumedUrlConversationIds = /* @__PURE__ */ new Set();
|
|
4880
|
+
var lastHandledOpenId = "";
|
|
4881
|
+
var lastHandledOpenAt = 0;
|
|
4882
|
+
var shouldHandleOpen = (conversationId) => {
|
|
4883
|
+
const id = String(conversationId || "").trim();
|
|
4884
|
+
if (!id) return false;
|
|
4885
|
+
const now = Date.now();
|
|
4886
|
+
if (lastHandledOpenId === id && now - lastHandledOpenAt < 2500) {
|
|
4887
|
+
return false;
|
|
4888
|
+
}
|
|
4889
|
+
lastHandledOpenId = id;
|
|
4890
|
+
lastHandledOpenAt = now;
|
|
4891
|
+
return true;
|
|
4892
|
+
};
|
|
4784
4893
|
var handleNotificationOpen = (conversationId, pushData, options) => {
|
|
4785
4894
|
const id = String(conversationId || "").trim();
|
|
4786
4895
|
if (!id) {
|
|
4787
4896
|
console.warn("[realtimex-push] notification open ignored \u2014 no conversationId", pushData);
|
|
4788
4897
|
return;
|
|
4789
4898
|
}
|
|
4899
|
+
if (!shouldHandleOpen(id)) {
|
|
4900
|
+
stripConversationIdFromUrl();
|
|
4901
|
+
return;
|
|
4902
|
+
}
|
|
4790
4903
|
requestOpenConversation(id, pushData);
|
|
4791
4904
|
const chatPath = options.chatPath || "/chat";
|
|
4792
|
-
|
|
4793
|
-
options.onNavigate?.(id,
|
|
4905
|
+
stripConversationIdFromUrl();
|
|
4906
|
+
options.onNavigate?.(id, chatPath);
|
|
4794
4907
|
};
|
|
4795
4908
|
var installNotificationClickBridge = (options = {}) => {
|
|
4796
4909
|
if (typeof window === "undefined") return () => void 0;
|
|
@@ -4817,7 +4930,17 @@ var installNotificationClickBridge = (options = {}) => {
|
|
|
4817
4930
|
if (fromUrl && !consumedUrlConversationIds.has(fromUrl)) {
|
|
4818
4931
|
consumedUrlConversationIds.add(fromUrl);
|
|
4819
4932
|
handleNotificationOpen(fromUrl, void 0, options);
|
|
4933
|
+
} else {
|
|
4934
|
+
stripConversationIdFromUrl();
|
|
4820
4935
|
}
|
|
4936
|
+
void consumePendingOpenFromPushCache().then((request) => {
|
|
4937
|
+
if (!request?.conversationId) return;
|
|
4938
|
+
handleNotificationOpen(
|
|
4939
|
+
request.conversationId,
|
|
4940
|
+
request,
|
|
4941
|
+
options
|
|
4942
|
+
);
|
|
4943
|
+
});
|
|
4821
4944
|
return () => {
|
|
4822
4945
|
navigator.serviceWorker?.removeEventListener("message", onSwMessage);
|
|
4823
4946
|
broadcast?.close();
|
|
@@ -5551,6 +5674,18 @@ function formatMemberName(name) {
|
|
|
5551
5674
|
function formatLoggedUserName(name) {
|
|
5552
5675
|
return name ? name.charAt(0).toUpperCase() + name.slice(1) : "User";
|
|
5553
5676
|
}
|
|
5677
|
+
|
|
5678
|
+
// src/chat/sidebar/build-logged-user-profile.ts
|
|
5679
|
+
var buildLoggedUserProfile = (loggedUserDetails) => ({
|
|
5680
|
+
_id: loggedUserDetails?._id || "1",
|
|
5681
|
+
name: formatLoggedUserName(loggedUserDetails?.name),
|
|
5682
|
+
email: loggedUserDetails?.email || "user@example.com",
|
|
5683
|
+
role: loggedUserDetails?.role || "user",
|
|
5684
|
+
isActive: loggedUserDetails?.isActive ?? true,
|
|
5685
|
+
createdAt: loggedUserDetails?.createdAt ? new Date(loggedUserDetails.createdAt) : /* @__PURE__ */ new Date(),
|
|
5686
|
+
updatedAt: loggedUserDetails?.updatedAt ? new Date(loggedUserDetails.updatedAt) : /* @__PURE__ */ new Date(),
|
|
5687
|
+
image: loggedUserDetails?.image || void 0
|
|
5688
|
+
});
|
|
5554
5689
|
function Dialog({
|
|
5555
5690
|
...props
|
|
5556
5691
|
}) {
|
|
@@ -6455,194 +6590,688 @@ var CreateChatDialog = (props) => {
|
|
|
6455
6590
|
);
|
|
6456
6591
|
};
|
|
6457
6592
|
var CreateChatDialog_default = CreateChatDialog;
|
|
6458
|
-
|
|
6459
|
-
loggedUserDetails,
|
|
6460
|
-
onUserSelect,
|
|
6461
|
-
isCreateModalOpen = false,
|
|
6462
|
-
setIsCreateModalOpen,
|
|
6463
|
-
searchQuery = "",
|
|
6464
|
-
setSearchQuery
|
|
6465
|
-
}) => {
|
|
6466
|
-
const { showColorModeToggle } = useChatTheme();
|
|
6467
|
-
const user = {
|
|
6468
|
-
_id: loggedUserDetails?._id || "1",
|
|
6469
|
-
name: formatLoggedUserName(loggedUserDetails?.name),
|
|
6470
|
-
email: loggedUserDetails?.email || "user@example.com",
|
|
6471
|
-
role: loggedUserDetails?.role || "user",
|
|
6472
|
-
isActive: loggedUserDetails?.isActive ?? true,
|
|
6473
|
-
createdAt: loggedUserDetails?.createdAt ? new Date(loggedUserDetails.createdAt) : /* @__PURE__ */ new Date(),
|
|
6474
|
-
updatedAt: loggedUserDetails?.updatedAt ? new Date(loggedUserDetails.updatedAt) : /* @__PURE__ */ new Date(),
|
|
6475
|
-
image: loggedUserDetails?.image || void 0
|
|
6476
|
-
};
|
|
6477
|
-
return /* @__PURE__ */ jsxs("div", { className: "shrink-0 border-b border-(--chat-border) bg-(--chat-surface) px-3 pb-3 pt-3", children: [
|
|
6478
|
-
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [
|
|
6479
|
-
/* @__PURE__ */ jsxs("div", { className: "relative shrink-0", children: [
|
|
6480
|
-
/* @__PURE__ */ jsxs(Avatar, { className: "size-8 ring-1 ring-(--chat-surface)", children: [
|
|
6481
|
-
user.image ? /* @__PURE__ */ jsx(AvatarImage, { src: user.image, alt: user.name }) : null,
|
|
6482
|
-
/* @__PURE__ */ jsx(AvatarFallback, { className: "bg-(--chat-theme-10) text-[10px] font-medium text-(--chat-theme)", children: (user.name || "?").charAt(0).toUpperCase() })
|
|
6483
|
-
] }),
|
|
6484
|
-
/* @__PURE__ */ jsx("span", { className: "absolute -bottom-0.5 -right-0.5 size-2 rounded-full border-2 border-(--chat-surface) bg-(--chat-online)" })
|
|
6485
|
-
] }),
|
|
6486
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
6487
|
-
/* @__PURE__ */ jsx("h2", { className: "truncate text-xs font-medium leading-tight text-(--chat-text)", children: user.name }),
|
|
6488
|
-
/* @__PURE__ */ jsx("p", { className: "truncate text-[10px] text-(--chat-muted)", children: user.email })
|
|
6489
|
-
] }),
|
|
6490
|
-
showColorModeToggle ? /* @__PURE__ */ jsx(ChatThemeToggle_default, {}) : null
|
|
6491
|
-
] }),
|
|
6492
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center gap-1.5", children: [
|
|
6493
|
-
/* @__PURE__ */ jsxs("div", { className: chatSidebarSearchShellClass, children: [
|
|
6494
|
-
/* @__PURE__ */ jsx(Search, { className: "pointer-events-none size-3.5 shrink-0 text-(--chat-muted)" }),
|
|
6495
|
-
/* @__PURE__ */ jsx(
|
|
6496
|
-
"input",
|
|
6497
|
-
{
|
|
6498
|
-
type: "text",
|
|
6499
|
-
inputMode: "search",
|
|
6500
|
-
enterKeyHint: "search",
|
|
6501
|
-
placeholder: "Search conversations...",
|
|
6502
|
-
value: searchQuery,
|
|
6503
|
-
onChange: (e) => setSearchQuery?.(e.target.value),
|
|
6504
|
-
className: chatSidebarSearchInputClass
|
|
6505
|
-
}
|
|
6506
|
-
),
|
|
6507
|
-
searchQuery ? /* @__PURE__ */ jsx(
|
|
6508
|
-
"button",
|
|
6509
|
-
{
|
|
6510
|
-
type: "button",
|
|
6511
|
-
onClick: () => setSearchQuery?.(""),
|
|
6512
|
-
className: "flex size-6 shrink-0 items-center justify-center rounded-md text-(--chat-muted) transition-colors hover:bg-(--chat-hover) hover:text-(--chat-text)",
|
|
6513
|
-
"aria-label": "Clear search",
|
|
6514
|
-
children: /* @__PURE__ */ jsx(X, { size: 12 })
|
|
6515
|
-
}
|
|
6516
|
-
) : null
|
|
6517
|
-
] }),
|
|
6518
|
-
/* @__PURE__ */ jsx(
|
|
6519
|
-
CreateChatDialog_default,
|
|
6520
|
-
{
|
|
6521
|
-
loggedUserDetails,
|
|
6522
|
-
onUserSelect,
|
|
6523
|
-
isCreateModalOpen,
|
|
6524
|
-
setIsCreateModalOpen
|
|
6525
|
-
}
|
|
6526
|
-
)
|
|
6527
|
-
] })
|
|
6528
|
-
] });
|
|
6529
|
-
};
|
|
6530
|
-
var LoggedUserDetails_default = LoggedUserDetails;
|
|
6531
|
-
function ScrollArea({
|
|
6532
|
-
className,
|
|
6533
|
-
children,
|
|
6534
|
-
...props
|
|
6535
|
-
}) {
|
|
6536
|
-
return /* @__PURE__ */ jsxs(
|
|
6537
|
-
ScrollArea$1.Root,
|
|
6538
|
-
{
|
|
6539
|
-
"data-slot": "scroll-area",
|
|
6540
|
-
className: cn("relative", className),
|
|
6541
|
-
...props,
|
|
6542
|
-
children: [
|
|
6543
|
-
/* @__PURE__ */ jsx(
|
|
6544
|
-
ScrollArea$1.Viewport,
|
|
6545
|
-
{
|
|
6546
|
-
"data-slot": "scroll-area-viewport",
|
|
6547
|
-
className: "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1",
|
|
6548
|
-
children
|
|
6549
|
-
}
|
|
6550
|
-
),
|
|
6551
|
-
/* @__PURE__ */ jsx(ScrollBar, {}),
|
|
6552
|
-
/* @__PURE__ */ jsx(ScrollArea$1.Corner, {})
|
|
6553
|
-
]
|
|
6554
|
-
}
|
|
6555
|
-
);
|
|
6556
|
-
}
|
|
6557
|
-
function ScrollBar({
|
|
6593
|
+
function Switch({
|
|
6558
6594
|
className,
|
|
6559
|
-
|
|
6595
|
+
size = "default",
|
|
6560
6596
|
...props
|
|
6561
6597
|
}) {
|
|
6562
6598
|
return /* @__PURE__ */ jsx(
|
|
6563
|
-
|
|
6599
|
+
Switch$1.Root,
|
|
6564
6600
|
{
|
|
6565
|
-
"data-slot": "
|
|
6566
|
-
|
|
6601
|
+
"data-slot": "switch",
|
|
6602
|
+
"data-size": size,
|
|
6567
6603
|
className: cn(
|
|
6568
|
-
"flex
|
|
6569
|
-
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent",
|
|
6570
|
-
orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent",
|
|
6604
|
+
"peer group/switch inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-[1.15rem] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-input/80",
|
|
6571
6605
|
className
|
|
6572
6606
|
),
|
|
6573
6607
|
...props,
|
|
6574
6608
|
children: /* @__PURE__ */ jsx(
|
|
6575
|
-
|
|
6609
|
+
Switch$1.Thumb,
|
|
6576
6610
|
{
|
|
6577
|
-
"data-slot": "
|
|
6578
|
-
className:
|
|
6611
|
+
"data-slot": "switch-thumb",
|
|
6612
|
+
className: cn(
|
|
6613
|
+
"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0 dark:data-[state=checked]:bg-primary-foreground dark:data-[state=unchecked]:bg-foreground"
|
|
6614
|
+
)
|
|
6579
6615
|
}
|
|
6580
6616
|
)
|
|
6581
6617
|
}
|
|
6582
6618
|
);
|
|
6583
6619
|
}
|
|
6584
6620
|
|
|
6585
|
-
// src/
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
var
|
|
6589
|
-
var
|
|
6590
|
-
var
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
draftRevision += 1;
|
|
6598
|
-
draftListeners.forEach((listener) => listener());
|
|
6599
|
-
}
|
|
6600
|
-
function subscribeToDrafts(listener) {
|
|
6601
|
-
draftListeners.add(listener);
|
|
6602
|
-
return () => {
|
|
6603
|
-
draftListeners.delete(listener);
|
|
6604
|
-
};
|
|
6605
|
-
}
|
|
6606
|
-
function getDraftRevision() {
|
|
6607
|
-
return draftRevision;
|
|
6608
|
-
}
|
|
6609
|
-
function useDraftRevision() {
|
|
6610
|
-
return useSyncExternalStore(subscribeToDrafts, getDraftRevision, getDraftRevision);
|
|
6611
|
-
}
|
|
6612
|
-
function getConversationDraft(conversationId) {
|
|
6613
|
-
if (!conversationId) return emptyDraft();
|
|
6614
|
-
return conversationDrafts.get(conversationId) ?? emptyDraft();
|
|
6615
|
-
}
|
|
6616
|
-
function updateConversationDraft(conversationId, draft) {
|
|
6617
|
-
if (!conversationId) return;
|
|
6618
|
-
if (draft.messageInput.trim() || draft.attachments.length > 0) {
|
|
6619
|
-
conversationDrafts.set(conversationId, {
|
|
6620
|
-
messageInput: draft.messageInput,
|
|
6621
|
-
attachments: draft.attachments
|
|
6622
|
-
});
|
|
6623
|
-
} else {
|
|
6624
|
-
conversationDrafts.delete(conversationId);
|
|
6625
|
-
}
|
|
6626
|
-
notifyDraftChange();
|
|
6627
|
-
}
|
|
6628
|
-
function clearConversationDraft(conversationId) {
|
|
6629
|
-
if (!conversationId) return;
|
|
6630
|
-
if (!conversationDrafts.has(conversationId)) return;
|
|
6631
|
-
conversationDrafts.delete(conversationId);
|
|
6632
|
-
notifyDraftChange();
|
|
6633
|
-
}
|
|
6634
|
-
function getConversationDraftPreview(conversationId) {
|
|
6635
|
-
if (!conversationId) return null;
|
|
6636
|
-
const draft = conversationDrafts.get(conversationId);
|
|
6637
|
-
if (!draft) return null;
|
|
6638
|
-
const text = draft.messageInput.trim();
|
|
6639
|
-
if (text) {
|
|
6640
|
-
return text.length > DRAFT_PREVIEW_MAX_LENGTH ? `${text.slice(0, DRAFT_PREVIEW_MAX_LENGTH)}\u2026` : text;
|
|
6621
|
+
// src/notifications/push.service.ts
|
|
6622
|
+
init_client();
|
|
6623
|
+
init_api_version();
|
|
6624
|
+
var PUSH_TOKEN_STORAGE_KEY = "realtimex-push-token";
|
|
6625
|
+
var SERVICE_WORKER_PATH = "/firebase-messaging-sw.js";
|
|
6626
|
+
var PUSH_CHANGED_EVENT = "realtimex:push-changed";
|
|
6627
|
+
var emitPushChanged = (enabled) => {
|
|
6628
|
+
try {
|
|
6629
|
+
window.dispatchEvent(
|
|
6630
|
+
new CustomEvent(PUSH_CHANGED_EVENT, { detail: { enabled } })
|
|
6631
|
+
);
|
|
6632
|
+
} catch {
|
|
6641
6633
|
}
|
|
6642
|
-
|
|
6643
|
-
|
|
6634
|
+
};
|
|
6635
|
+
var pushApiUrl = (path) => buildVersionedApiUrl(path, { service: "push" });
|
|
6636
|
+
var apiGetPushConfig = async () => {
|
|
6637
|
+
const { data } = await apiClient.get(pushApiUrl("/notifications/push/config"));
|
|
6638
|
+
return data?.data;
|
|
6639
|
+
};
|
|
6640
|
+
var apiRegisterPushToken = async (token, deviceLabel) => {
|
|
6641
|
+
const { data } = await apiClient.post(pushApiUrl("/notifications/push/token"), {
|
|
6642
|
+
token,
|
|
6643
|
+
deviceLabel
|
|
6644
|
+
});
|
|
6645
|
+
return data?.data;
|
|
6646
|
+
};
|
|
6647
|
+
var apiRemovePushToken = async (token) => {
|
|
6648
|
+
const { data } = await apiClient.delete(pushApiUrl("/notifications/push/token"), {
|
|
6649
|
+
data: { token }
|
|
6650
|
+
});
|
|
6651
|
+
return data;
|
|
6652
|
+
};
|
|
6653
|
+
var apiGetPushPreference = async () => {
|
|
6654
|
+
const { data } = await apiClient.get(
|
|
6655
|
+
pushApiUrl("/notifications/push/preference")
|
|
6656
|
+
);
|
|
6657
|
+
return data?.data;
|
|
6658
|
+
};
|
|
6659
|
+
var apiUpdatePushPreference = async (enabled) => {
|
|
6660
|
+
const { data } = await apiClient.patch(
|
|
6661
|
+
pushApiUrl("/notifications/push/preference"),
|
|
6662
|
+
{ enabled }
|
|
6663
|
+
);
|
|
6664
|
+
return data?.data;
|
|
6665
|
+
};
|
|
6666
|
+
var isPushSupported = () => typeof window !== "undefined" && "Notification" in window && "serviceWorker" in navigator && "PushManager" in window;
|
|
6667
|
+
var getStoredPushToken = () => {
|
|
6668
|
+
try {
|
|
6669
|
+
return localStorage.getItem(PUSH_TOKEN_STORAGE_KEY);
|
|
6670
|
+
} catch {
|
|
6671
|
+
return null;
|
|
6644
6672
|
}
|
|
6645
|
-
|
|
6673
|
+
};
|
|
6674
|
+
var storePushToken = (token) => {
|
|
6675
|
+
try {
|
|
6676
|
+
if (token) localStorage.setItem(PUSH_TOKEN_STORAGE_KEY, token);
|
|
6677
|
+
else localStorage.removeItem(PUSH_TOKEN_STORAGE_KEY);
|
|
6678
|
+
} catch {
|
|
6679
|
+
}
|
|
6680
|
+
};
|
|
6681
|
+
var defaultDeviceLabel = () => {
|
|
6682
|
+
const ua = navigator.userAgent;
|
|
6683
|
+
const browser = /edg\//i.test(ua) ? "Edge" : /chrome/i.test(ua) ? "Chrome" : /safari/i.test(ua) ? "Safari" : /firefox/i.test(ua) ? "Firefox" : "Browser";
|
|
6684
|
+
const os = /mac/i.test(ua) ? "macOS" : /windows/i.test(ua) ? "Windows" : /android/i.test(ua) ? "Android" : /iphone|ipad/i.test(ua) ? "iOS" : /linux/i.test(ua) ? "Linux" : "Unknown OS";
|
|
6685
|
+
return `${browser} on ${os}`;
|
|
6686
|
+
};
|
|
6687
|
+
var loadFirebaseMessaging = async () => {
|
|
6688
|
+
try {
|
|
6689
|
+
const [{ initializeApp, getApps }, messagingModule] = await Promise.all([
|
|
6690
|
+
import('firebase/app'),
|
|
6691
|
+
import('firebase/messaging')
|
|
6692
|
+
]);
|
|
6693
|
+
return { initializeApp, getApps, ...messagingModule };
|
|
6694
|
+
} catch {
|
|
6695
|
+
throw new Error(
|
|
6696
|
+
'Push notifications need the "firebase" package \u2014 run: npm install firebase'
|
|
6697
|
+
);
|
|
6698
|
+
}
|
|
6699
|
+
};
|
|
6700
|
+
var getFirebaseMessaging = async (firebaseConfig) => {
|
|
6701
|
+
const fb = await loadFirebaseMessaging();
|
|
6702
|
+
const app = fb.getApps().length ? fb.getApps()[0] : fb.initializeApp(firebaseConfig);
|
|
6703
|
+
return { fb, messaging: fb.getMessaging(app) };
|
|
6704
|
+
};
|
|
6705
|
+
var enablePushOnThisDevice = async () => {
|
|
6706
|
+
if (!isPushSupported()) {
|
|
6707
|
+
throw new Error("Push notifications are not supported in this browser");
|
|
6708
|
+
}
|
|
6709
|
+
const config = await apiGetPushConfig();
|
|
6710
|
+
if (!config?.enabled) {
|
|
6711
|
+
throw new Error("Push notifications are disabled for this workspace");
|
|
6712
|
+
}
|
|
6713
|
+
if (!config.configured || !config.firebaseConfig || !config.vapidKey) {
|
|
6714
|
+
throw new Error(
|
|
6715
|
+
"Push notifications are not configured on the server yet"
|
|
6716
|
+
);
|
|
6717
|
+
}
|
|
6718
|
+
const permission = await Notification.requestPermission();
|
|
6719
|
+
if (permission !== "granted") {
|
|
6720
|
+
throw new Error("Notification permission was not granted");
|
|
6721
|
+
}
|
|
6722
|
+
let registration;
|
|
6723
|
+
try {
|
|
6724
|
+
registration = await navigator.serviceWorker.register(
|
|
6725
|
+
`${SERVICE_WORKER_PATH}?config=${encodeURIComponent(
|
|
6726
|
+
JSON.stringify(config.firebaseConfig)
|
|
6727
|
+
)}`
|
|
6728
|
+
);
|
|
6729
|
+
} catch {
|
|
6730
|
+
throw new Error(
|
|
6731
|
+
`Could not register ${SERVICE_WORKER_PATH} \u2014 copy it from node_modules/@realtimexsco/live-chat/dist/firebase-messaging-sw.js into your app's public folder`
|
|
6732
|
+
);
|
|
6733
|
+
}
|
|
6734
|
+
const { fb, messaging } = await getFirebaseMessaging(config.firebaseConfig);
|
|
6735
|
+
const token = await fb.getToken(messaging, {
|
|
6736
|
+
vapidKey: config.vapidKey,
|
|
6737
|
+
serviceWorkerRegistration: registration
|
|
6738
|
+
});
|
|
6739
|
+
if (!token) {
|
|
6740
|
+
throw new Error("Could not obtain a push token from Firebase");
|
|
6741
|
+
}
|
|
6742
|
+
await apiRegisterPushToken(token, defaultDeviceLabel());
|
|
6743
|
+
storePushToken(token);
|
|
6744
|
+
emitPushChanged(true);
|
|
6745
|
+
return token;
|
|
6746
|
+
};
|
|
6747
|
+
var disablePushOnThisDevice = async () => {
|
|
6748
|
+
const token = getStoredPushToken();
|
|
6749
|
+
if (!token) return;
|
|
6750
|
+
try {
|
|
6751
|
+
const config = await apiGetPushConfig();
|
|
6752
|
+
if (config?.firebaseConfig) {
|
|
6753
|
+
const { fb, messaging } = await getFirebaseMessaging(
|
|
6754
|
+
config.firebaseConfig
|
|
6755
|
+
);
|
|
6756
|
+
await fb.deleteToken(messaging).catch(() => void 0);
|
|
6757
|
+
}
|
|
6758
|
+
} catch {
|
|
6759
|
+
}
|
|
6760
|
+
await apiRemovePushToken(token).catch(() => void 0);
|
|
6761
|
+
storePushToken(null);
|
|
6762
|
+
emitPushChanged(false);
|
|
6763
|
+
};
|
|
6764
|
+
var onForegroundPush = async (callback) => {
|
|
6765
|
+
const config = await apiGetPushConfig();
|
|
6766
|
+
if (!config?.configured || !config.firebaseConfig) {
|
|
6767
|
+
throw new Error("Push config unavailable (not configured or API not ready)");
|
|
6768
|
+
}
|
|
6769
|
+
const { fb, messaging } = await getFirebaseMessaging(config.firebaseConfig);
|
|
6770
|
+
return fb.onMessage(messaging, (payload) => {
|
|
6771
|
+
console.log("[realtimex-push] FCM foreground payload (raw):", payload);
|
|
6772
|
+
console.log("[realtimex-push] FCM foreground data:", payload?.data);
|
|
6773
|
+
console.log("[realtimex-push] FCM foreground notification:", payload?.notification);
|
|
6774
|
+
callback({
|
|
6775
|
+
title: payload?.notification?.title,
|
|
6776
|
+
body: payload?.notification?.body,
|
|
6777
|
+
data: payload?.data
|
|
6778
|
+
});
|
|
6779
|
+
});
|
|
6780
|
+
};
|
|
6781
|
+
|
|
6782
|
+
// src/notifications/usePushNotifications.ts
|
|
6783
|
+
var usePushNotifications = () => {
|
|
6784
|
+
const [state, setState] = useState({
|
|
6785
|
+
supported: false,
|
|
6786
|
+
allowedByWorkspace: false,
|
|
6787
|
+
configured: false,
|
|
6788
|
+
permission: "unsupported",
|
|
6789
|
+
userEnabled: true,
|
|
6790
|
+
deviceEnabled: false,
|
|
6791
|
+
loading: true,
|
|
6792
|
+
error: null
|
|
6793
|
+
});
|
|
6794
|
+
const refresh = useCallback(async () => {
|
|
6795
|
+
if (!isPushSupported()) {
|
|
6796
|
+
setState((prev) => ({
|
|
6797
|
+
...prev,
|
|
6798
|
+
supported: false,
|
|
6799
|
+
loading: false
|
|
6800
|
+
}));
|
|
6801
|
+
return;
|
|
6802
|
+
}
|
|
6803
|
+
try {
|
|
6804
|
+
const [config, preference] = await Promise.all([
|
|
6805
|
+
apiGetPushConfig(),
|
|
6806
|
+
apiGetPushPreference().catch(() => null)
|
|
6807
|
+
]);
|
|
6808
|
+
setState({
|
|
6809
|
+
supported: true,
|
|
6810
|
+
allowedByWorkspace: Boolean(config?.enabled),
|
|
6811
|
+
configured: Boolean(config?.configured),
|
|
6812
|
+
permission: Notification.permission,
|
|
6813
|
+
userEnabled: preference?.enabled ?? true,
|
|
6814
|
+
deviceEnabled: Notification.permission === "granted" && Boolean(getStoredPushToken()),
|
|
6815
|
+
loading: false,
|
|
6816
|
+
error: null
|
|
6817
|
+
});
|
|
6818
|
+
} catch (error) {
|
|
6819
|
+
setState((prev) => ({
|
|
6820
|
+
...prev,
|
|
6821
|
+
supported: true,
|
|
6822
|
+
loading: false,
|
|
6823
|
+
error: error instanceof Error ? error.message : "Could not load push settings"
|
|
6824
|
+
}));
|
|
6825
|
+
}
|
|
6826
|
+
}, []);
|
|
6827
|
+
useEffect(() => {
|
|
6828
|
+
void refresh();
|
|
6829
|
+
}, [refresh]);
|
|
6830
|
+
const enable = useCallback(async () => {
|
|
6831
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
6832
|
+
try {
|
|
6833
|
+
await enablePushOnThisDevice();
|
|
6834
|
+
await refresh();
|
|
6835
|
+
return true;
|
|
6836
|
+
} catch (error) {
|
|
6837
|
+
setState((prev) => ({
|
|
6838
|
+
...prev,
|
|
6839
|
+
loading: false,
|
|
6840
|
+
permission: isPushSupported() ? Notification.permission : "unsupported",
|
|
6841
|
+
error: error instanceof Error ? error.message : "Could not enable push notifications"
|
|
6842
|
+
}));
|
|
6843
|
+
return false;
|
|
6844
|
+
}
|
|
6845
|
+
}, [refresh]);
|
|
6846
|
+
const disable = useCallback(async () => {
|
|
6847
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
6848
|
+
try {
|
|
6849
|
+
await disablePushOnThisDevice();
|
|
6850
|
+
} finally {
|
|
6851
|
+
await refresh();
|
|
6852
|
+
}
|
|
6853
|
+
}, [refresh]);
|
|
6854
|
+
const setUserEnabled = useCallback(
|
|
6855
|
+
async (enabled) => {
|
|
6856
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
6857
|
+
try {
|
|
6858
|
+
await apiUpdatePushPreference(enabled);
|
|
6859
|
+
setState((prev) => ({ ...prev, userEnabled: enabled, loading: false }));
|
|
6860
|
+
} catch (error) {
|
|
6861
|
+
setState((prev) => ({
|
|
6862
|
+
...prev,
|
|
6863
|
+
userEnabled: !enabled,
|
|
6864
|
+
loading: false,
|
|
6865
|
+
error: error instanceof Error ? error.message : "Could not update push preference"
|
|
6866
|
+
}));
|
|
6867
|
+
}
|
|
6868
|
+
},
|
|
6869
|
+
[]
|
|
6870
|
+
);
|
|
6871
|
+
return { ...state, enable, disable, setUserEnabled, refresh };
|
|
6872
|
+
};
|
|
6873
|
+
var PushNotificationToggle = ({
|
|
6874
|
+
className,
|
|
6875
|
+
label = "Push notifications",
|
|
6876
|
+
description = "Get notified about new messages on this device",
|
|
6877
|
+
children
|
|
6878
|
+
}) => {
|
|
6879
|
+
const push = usePushNotifications();
|
|
6880
|
+
const [isToggling, setIsToggling] = useState(false);
|
|
6881
|
+
if (!push.supported || !push.allowedByWorkspace || !push.configured) {
|
|
6882
|
+
return null;
|
|
6883
|
+
}
|
|
6884
|
+
const isOn = push.deviceEnabled && push.userEnabled;
|
|
6885
|
+
const permissionBlocked = push.permission === "denied";
|
|
6886
|
+
const showLoader = isToggling;
|
|
6887
|
+
const handleChange = async (checked) => {
|
|
6888
|
+
setIsToggling(true);
|
|
6889
|
+
try {
|
|
6890
|
+
if (checked) {
|
|
6891
|
+
if (!push.userEnabled) await push.setUserEnabled(true);
|
|
6892
|
+
if (!push.deviceEnabled) await push.enable();
|
|
6893
|
+
} else {
|
|
6894
|
+
await push.disable();
|
|
6895
|
+
}
|
|
6896
|
+
} finally {
|
|
6897
|
+
setIsToggling(false);
|
|
6898
|
+
}
|
|
6899
|
+
};
|
|
6900
|
+
const renderProps = {
|
|
6901
|
+
label,
|
|
6902
|
+
description: permissionBlocked ? "Notifications are blocked in your browser settings" : push.error ?? description,
|
|
6903
|
+
checked: isOn,
|
|
6904
|
+
disabled: showLoader || permissionBlocked || push.loading,
|
|
6905
|
+
loading: showLoader || push.loading,
|
|
6906
|
+
permissionBlocked,
|
|
6907
|
+
error: push.error,
|
|
6908
|
+
onCheckedChange: (checked) => void handleChange(checked)
|
|
6909
|
+
};
|
|
6910
|
+
if (children) {
|
|
6911
|
+
return /* @__PURE__ */ jsx(Fragment, { children: children(renderProps) });
|
|
6912
|
+
}
|
|
6913
|
+
return /* @__PURE__ */ jsxs(
|
|
6914
|
+
"div",
|
|
6915
|
+
{
|
|
6916
|
+
className: cn(
|
|
6917
|
+
"flex items-center justify-between gap-4 rounded-xl border border-(--chat-border) bg-(--chat-surface) px-4 py-3",
|
|
6918
|
+
className
|
|
6919
|
+
),
|
|
6920
|
+
children: [
|
|
6921
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
6922
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-(--chat-text)", children: label }),
|
|
6923
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-(--chat-muted)", children: renderProps.description })
|
|
6924
|
+
] }),
|
|
6925
|
+
showLoader ? /* @__PURE__ */ jsx(
|
|
6926
|
+
Loader2,
|
|
6927
|
+
{
|
|
6928
|
+
className: "size-5 shrink-0 animate-spin text-(--chat-theme)",
|
|
6929
|
+
"aria-label": "Updating push notifications"
|
|
6930
|
+
}
|
|
6931
|
+
) : /* @__PURE__ */ jsx(
|
|
6932
|
+
Switch,
|
|
6933
|
+
{
|
|
6934
|
+
checked: isOn,
|
|
6935
|
+
disabled: permissionBlocked || push.loading,
|
|
6936
|
+
onCheckedChange: (checked) => void handleChange(checked),
|
|
6937
|
+
"aria-label": `Toggle ${label}`
|
|
6938
|
+
}
|
|
6939
|
+
)
|
|
6940
|
+
]
|
|
6941
|
+
}
|
|
6942
|
+
);
|
|
6943
|
+
};
|
|
6944
|
+
var LoggedUserSettingsContent = ({
|
|
6945
|
+
user,
|
|
6946
|
+
title = "Account settings",
|
|
6947
|
+
showProfile = true,
|
|
6948
|
+
showPushToggle = true,
|
|
6949
|
+
className
|
|
6950
|
+
}) => {
|
|
6951
|
+
const { resolveComponent, slotClassName } = useChatCustomization();
|
|
6952
|
+
const PushToggleSlot = resolveComponent(
|
|
6953
|
+
"PushNotificationToggle",
|
|
6954
|
+
PushNotificationToggle
|
|
6955
|
+
);
|
|
6956
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6957
|
+
/* @__PURE__ */ jsx(
|
|
6958
|
+
"div",
|
|
6959
|
+
{
|
|
6960
|
+
className: cn(
|
|
6961
|
+
"border-b border-(--chat-border) px-5 py-4",
|
|
6962
|
+
slotClassName("loggedUserSettingsHeader")
|
|
6963
|
+
),
|
|
6964
|
+
children: /* @__PURE__ */ jsx(DialogTitle, { className: "text-left text-base font-semibold text-(--chat-text)", children: title })
|
|
6965
|
+
}
|
|
6966
|
+
),
|
|
6967
|
+
/* @__PURE__ */ jsxs(
|
|
6968
|
+
"div",
|
|
6969
|
+
{
|
|
6970
|
+
className: cn(
|
|
6971
|
+
"space-y-5 px-5 py-5",
|
|
6972
|
+
slotClassName("loggedUserSettingsContent", className)
|
|
6973
|
+
),
|
|
6974
|
+
children: [
|
|
6975
|
+
showProfile ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center text-center", children: [
|
|
6976
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
6977
|
+
/* @__PURE__ */ jsxs(
|
|
6978
|
+
Avatar,
|
|
6979
|
+
{
|
|
6980
|
+
className: cn(
|
|
6981
|
+
"size-16 ring-2 ring-(--chat-theme-20)",
|
|
6982
|
+
slotClassName("loggedUserSettingsAvatar")
|
|
6983
|
+
),
|
|
6984
|
+
children: [
|
|
6985
|
+
user.image ? /* @__PURE__ */ jsx(AvatarImage, { src: user.image, alt: user.name }) : null,
|
|
6986
|
+
/* @__PURE__ */ jsx(AvatarFallback, { className: "bg-(--chat-theme-10) text-lg font-medium text-(--chat-theme)", children: (user.name || "?").charAt(0).toUpperCase() })
|
|
6987
|
+
]
|
|
6988
|
+
}
|
|
6989
|
+
),
|
|
6990
|
+
/* @__PURE__ */ jsx("span", { className: "absolute bottom-0.5 right-0.5 size-3 rounded-full border-2 border-(--chat-surface) bg-(--chat-online)" })
|
|
6991
|
+
] }),
|
|
6992
|
+
/* @__PURE__ */ jsx("h3", { className: "mt-3 text-base font-semibold text-(--chat-text)", children: user.name }),
|
|
6993
|
+
/* @__PURE__ */ jsx("p", { className: "mt-0.5 text-sm text-(--chat-muted)", children: user.email }),
|
|
6994
|
+
/* @__PURE__ */ jsxs("p", { className: "mt-2 inline-flex items-center gap-1.5 rounded-full bg-(--chat-theme-10) px-2.5 py-0.5 text-xs font-medium text-(--chat-theme)", children: [
|
|
6995
|
+
/* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-(--chat-online)" }),
|
|
6996
|
+
"Online"
|
|
6997
|
+
] })
|
|
6998
|
+
] }) : null,
|
|
6999
|
+
showPushToggle ? /* @__PURE__ */ jsx("div", { className: "border-t border-(--chat-border) pt-4", children: /* @__PURE__ */ jsx(
|
|
7000
|
+
PushToggleSlot,
|
|
7001
|
+
{
|
|
7002
|
+
className: cn(
|
|
7003
|
+
"flex items-center justify-between gap-4 rounded-xl border border-(--chat-border) bg-(--chat-theme-10) px-4 py-3",
|
|
7004
|
+
slotClassName("pushNotificationToggle")
|
|
7005
|
+
)
|
|
7006
|
+
}
|
|
7007
|
+
) }) : null
|
|
7008
|
+
]
|
|
7009
|
+
}
|
|
7010
|
+
)
|
|
7011
|
+
] });
|
|
7012
|
+
};
|
|
7013
|
+
var LoggedUserSettingsContent_default = LoggedUserSettingsContent;
|
|
7014
|
+
var LoggedUserSettingsTrigger = ({
|
|
7015
|
+
onClick,
|
|
7016
|
+
className,
|
|
7017
|
+
tooltip = "Settings",
|
|
7018
|
+
ariaLabel = "Account settings"
|
|
7019
|
+
}) => {
|
|
7020
|
+
const { slotClassName } = useChatCustomization();
|
|
7021
|
+
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
7022
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
7023
|
+
Button,
|
|
7024
|
+
{
|
|
7025
|
+
type: "button",
|
|
7026
|
+
variant: "ghost",
|
|
7027
|
+
size: "icon",
|
|
7028
|
+
className: cn(
|
|
7029
|
+
sidebarActionBtnClass,
|
|
7030
|
+
slotClassName("loggedUserSettingsTrigger", className)
|
|
7031
|
+
),
|
|
7032
|
+
"aria-label": ariaLabel,
|
|
7033
|
+
onClick,
|
|
7034
|
+
children: /* @__PURE__ */ jsx(Settings, { className: "size-3.5", strokeWidth: 2 })
|
|
7035
|
+
}
|
|
7036
|
+
) }),
|
|
7037
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "bottom", children: tooltip })
|
|
7038
|
+
] });
|
|
7039
|
+
};
|
|
7040
|
+
var LoggedUserSettingsTrigger_default = LoggedUserSettingsTrigger;
|
|
7041
|
+
var LoggedUserSettingsDialog = ({
|
|
7042
|
+
loggedUserDetails,
|
|
7043
|
+
open: controlledOpen,
|
|
7044
|
+
onOpenChange: controlledOnOpenChange,
|
|
7045
|
+
title,
|
|
7046
|
+
showProfile = true,
|
|
7047
|
+
showPushToggle = true,
|
|
7048
|
+
className
|
|
7049
|
+
}) => {
|
|
7050
|
+
const { resolveComponent, slotClassName } = useChatCustomization();
|
|
7051
|
+
const [internalOpen, setInternalOpen] = useState(false);
|
|
7052
|
+
const open = controlledOpen ?? internalOpen;
|
|
7053
|
+
const onOpenChange = controlledOnOpenChange ?? setInternalOpen;
|
|
7054
|
+
const TriggerSlot = resolveComponent(
|
|
7055
|
+
"LoggedUserSettingsTrigger",
|
|
7056
|
+
LoggedUserSettingsTrigger_default
|
|
7057
|
+
);
|
|
7058
|
+
const ContentSlot = resolveComponent(
|
|
7059
|
+
"LoggedUserSettingsContent",
|
|
7060
|
+
LoggedUserSettingsContent_default
|
|
7061
|
+
);
|
|
7062
|
+
const user = buildLoggedUserProfile(loggedUserDetails);
|
|
7063
|
+
return /* @__PURE__ */ jsxs(Dialog, { open, onOpenChange, children: [
|
|
7064
|
+
/* @__PURE__ */ jsx(TriggerSlot, { onClick: () => onOpenChange(true) }),
|
|
7065
|
+
/* @__PURE__ */ jsx(
|
|
7066
|
+
ChatDialogContent,
|
|
7067
|
+
{
|
|
7068
|
+
className: cn(
|
|
7069
|
+
"gap-0 overflow-hidden p-0 sm:max-w-[380px]",
|
|
7070
|
+
slotClassName("loggedUserSettingsDialog", className)
|
|
7071
|
+
),
|
|
7072
|
+
children: /* @__PURE__ */ jsx(
|
|
7073
|
+
ContentSlot,
|
|
7074
|
+
{
|
|
7075
|
+
loggedUserDetails,
|
|
7076
|
+
user,
|
|
7077
|
+
onClose: () => onOpenChange(false),
|
|
7078
|
+
title,
|
|
7079
|
+
showProfile,
|
|
7080
|
+
showPushToggle
|
|
7081
|
+
}
|
|
7082
|
+
)
|
|
7083
|
+
}
|
|
7084
|
+
)
|
|
7085
|
+
] });
|
|
7086
|
+
};
|
|
7087
|
+
var LoggedUserSettingsDialog_default = LoggedUserSettingsDialog;
|
|
7088
|
+
var LoggedUserDetails = ({
|
|
7089
|
+
loggedUserDetails,
|
|
7090
|
+
onUserSelect,
|
|
7091
|
+
isCreateModalOpen = false,
|
|
7092
|
+
setIsCreateModalOpen,
|
|
7093
|
+
searchQuery = "",
|
|
7094
|
+
setSearchQuery
|
|
7095
|
+
}) => {
|
|
7096
|
+
const { showColorModeToggle } = useChatTheme();
|
|
7097
|
+
const { resolveComponent } = useChatCustomization();
|
|
7098
|
+
const SettingsDialogSlot = resolveComponent(
|
|
7099
|
+
"LoggedUserSettingsDialog",
|
|
7100
|
+
LoggedUserSettingsDialog_default
|
|
7101
|
+
);
|
|
7102
|
+
const user = buildLoggedUserProfile(loggedUserDetails);
|
|
7103
|
+
return /* @__PURE__ */ jsxs("div", { className: "shrink-0 border-b border-(--chat-border) bg-(--chat-surface) px-3 pb-3 pt-3", children: [
|
|
7104
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [
|
|
7105
|
+
/* @__PURE__ */ jsxs("div", { className: "relative shrink-0", children: [
|
|
7106
|
+
/* @__PURE__ */ jsxs(Avatar, { className: "size-8 ring-1 ring-(--chat-surface)", children: [
|
|
7107
|
+
user.image ? /* @__PURE__ */ jsx(AvatarImage, { src: user.image, alt: user.name }) : null,
|
|
7108
|
+
/* @__PURE__ */ jsx(AvatarFallback, { className: "bg-(--chat-theme-10) text-[10px] font-medium text-(--chat-theme)", children: (user.name || "?").charAt(0).toUpperCase() })
|
|
7109
|
+
] }),
|
|
7110
|
+
/* @__PURE__ */ jsx("span", { className: "absolute -bottom-0.5 -right-0.5 size-2 rounded-full border-2 border-(--chat-surface) bg-(--chat-online)" })
|
|
7111
|
+
] }),
|
|
7112
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
7113
|
+
/* @__PURE__ */ jsx("h2", { className: "truncate text-xs font-medium leading-tight text-(--chat-text)", children: user.name }),
|
|
7114
|
+
/* @__PURE__ */ jsx("p", { className: "truncate text-[10px] text-(--chat-muted)", children: user.email })
|
|
7115
|
+
] }),
|
|
7116
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-0.5", children: [
|
|
7117
|
+
/* @__PURE__ */ jsx(SettingsDialogSlot, { loggedUserDetails }),
|
|
7118
|
+
showColorModeToggle ? /* @__PURE__ */ jsx(ChatThemeToggle_default, {}) : null
|
|
7119
|
+
] })
|
|
7120
|
+
] }),
|
|
7121
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center gap-1.5", children: [
|
|
7122
|
+
/* @__PURE__ */ jsxs("div", { className: chatSidebarSearchShellClass, children: [
|
|
7123
|
+
/* @__PURE__ */ jsx(Search, { className: "pointer-events-none size-3.5 shrink-0 text-(--chat-muted)" }),
|
|
7124
|
+
/* @__PURE__ */ jsx(
|
|
7125
|
+
"input",
|
|
7126
|
+
{
|
|
7127
|
+
type: "text",
|
|
7128
|
+
inputMode: "search",
|
|
7129
|
+
enterKeyHint: "search",
|
|
7130
|
+
placeholder: "Search conversations...",
|
|
7131
|
+
value: searchQuery,
|
|
7132
|
+
onChange: (e) => setSearchQuery?.(e.target.value),
|
|
7133
|
+
className: chatSidebarSearchInputClass
|
|
7134
|
+
}
|
|
7135
|
+
),
|
|
7136
|
+
searchQuery ? /* @__PURE__ */ jsx(
|
|
7137
|
+
"button",
|
|
7138
|
+
{
|
|
7139
|
+
type: "button",
|
|
7140
|
+
onClick: () => setSearchQuery?.(""),
|
|
7141
|
+
className: "flex size-6 shrink-0 items-center justify-center rounded-md text-(--chat-muted) transition-colors hover:bg-(--chat-hover) hover:text-(--chat-text)",
|
|
7142
|
+
"aria-label": "Clear search",
|
|
7143
|
+
children: /* @__PURE__ */ jsx(X, { size: 12 })
|
|
7144
|
+
}
|
|
7145
|
+
) : null
|
|
7146
|
+
] }),
|
|
7147
|
+
/* @__PURE__ */ jsx(
|
|
7148
|
+
CreateChatDialog_default,
|
|
7149
|
+
{
|
|
7150
|
+
loggedUserDetails,
|
|
7151
|
+
onUserSelect,
|
|
7152
|
+
isCreateModalOpen,
|
|
7153
|
+
setIsCreateModalOpen
|
|
7154
|
+
}
|
|
7155
|
+
)
|
|
7156
|
+
] })
|
|
7157
|
+
] });
|
|
7158
|
+
};
|
|
7159
|
+
var LoggedUserDetails_default = LoggedUserDetails;
|
|
7160
|
+
function ScrollArea({
|
|
7161
|
+
className,
|
|
7162
|
+
children,
|
|
7163
|
+
...props
|
|
7164
|
+
}) {
|
|
7165
|
+
return /* @__PURE__ */ jsxs(
|
|
7166
|
+
ScrollArea$1.Root,
|
|
7167
|
+
{
|
|
7168
|
+
"data-slot": "scroll-area",
|
|
7169
|
+
className: cn("relative", className),
|
|
7170
|
+
...props,
|
|
7171
|
+
children: [
|
|
7172
|
+
/* @__PURE__ */ jsx(
|
|
7173
|
+
ScrollArea$1.Viewport,
|
|
7174
|
+
{
|
|
7175
|
+
"data-slot": "scroll-area-viewport",
|
|
7176
|
+
className: "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1",
|
|
7177
|
+
children
|
|
7178
|
+
}
|
|
7179
|
+
),
|
|
7180
|
+
/* @__PURE__ */ jsx(ScrollBar, {}),
|
|
7181
|
+
/* @__PURE__ */ jsx(ScrollArea$1.Corner, {})
|
|
7182
|
+
]
|
|
7183
|
+
}
|
|
7184
|
+
);
|
|
7185
|
+
}
|
|
7186
|
+
function ScrollBar({
|
|
7187
|
+
className,
|
|
7188
|
+
orientation = "vertical",
|
|
7189
|
+
...props
|
|
7190
|
+
}) {
|
|
7191
|
+
return /* @__PURE__ */ jsx(
|
|
7192
|
+
ScrollArea$1.ScrollAreaScrollbar,
|
|
7193
|
+
{
|
|
7194
|
+
"data-slot": "scroll-area-scrollbar",
|
|
7195
|
+
orientation,
|
|
7196
|
+
className: cn(
|
|
7197
|
+
"flex touch-none p-px transition-colors select-none",
|
|
7198
|
+
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent",
|
|
7199
|
+
orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent",
|
|
7200
|
+
className
|
|
7201
|
+
),
|
|
7202
|
+
...props,
|
|
7203
|
+
children: /* @__PURE__ */ jsx(
|
|
7204
|
+
ScrollArea$1.ScrollAreaThumb,
|
|
7205
|
+
{
|
|
7206
|
+
"data-slot": "scroll-area-thumb",
|
|
7207
|
+
className: "bg-border relative flex-1 rounded-full"
|
|
7208
|
+
}
|
|
7209
|
+
)
|
|
7210
|
+
}
|
|
7211
|
+
);
|
|
7212
|
+
}
|
|
7213
|
+
|
|
7214
|
+
// src/chat/channel-list/useChannelList.ts
|
|
7215
|
+
init_useStore();
|
|
7216
|
+
init_store_helpers();
|
|
7217
|
+
var conversationDrafts = /* @__PURE__ */ new Map();
|
|
7218
|
+
var DRAFT_PREVIEW_MAX_LENGTH = 50;
|
|
7219
|
+
var emptyDraft = () => ({
|
|
7220
|
+
messageInput: "",
|
|
7221
|
+
attachments: []
|
|
7222
|
+
});
|
|
7223
|
+
var draftRevision = 0;
|
|
7224
|
+
var draftListeners = /* @__PURE__ */ new Set();
|
|
7225
|
+
function notifyDraftChange() {
|
|
7226
|
+
draftRevision += 1;
|
|
7227
|
+
draftListeners.forEach((listener) => listener());
|
|
7228
|
+
}
|
|
7229
|
+
function subscribeToDrafts(listener) {
|
|
7230
|
+
draftListeners.add(listener);
|
|
7231
|
+
return () => {
|
|
7232
|
+
draftListeners.delete(listener);
|
|
7233
|
+
};
|
|
7234
|
+
}
|
|
7235
|
+
function getDraftRevision() {
|
|
7236
|
+
return draftRevision;
|
|
7237
|
+
}
|
|
7238
|
+
function useDraftRevision() {
|
|
7239
|
+
return useSyncExternalStore(subscribeToDrafts, getDraftRevision, getDraftRevision);
|
|
7240
|
+
}
|
|
7241
|
+
function getConversationDraft(conversationId) {
|
|
7242
|
+
if (!conversationId) return emptyDraft();
|
|
7243
|
+
return conversationDrafts.get(conversationId) ?? emptyDraft();
|
|
7244
|
+
}
|
|
7245
|
+
function updateConversationDraft(conversationId, draft) {
|
|
7246
|
+
if (!conversationId) return;
|
|
7247
|
+
if (draft.messageInput.trim() || draft.attachments.length > 0) {
|
|
7248
|
+
conversationDrafts.set(conversationId, {
|
|
7249
|
+
messageInput: draft.messageInput,
|
|
7250
|
+
attachments: draft.attachments
|
|
7251
|
+
});
|
|
7252
|
+
} else {
|
|
7253
|
+
conversationDrafts.delete(conversationId);
|
|
7254
|
+
}
|
|
7255
|
+
notifyDraftChange();
|
|
7256
|
+
}
|
|
7257
|
+
function clearConversationDraft(conversationId) {
|
|
7258
|
+
if (!conversationId) return;
|
|
7259
|
+
if (!conversationDrafts.has(conversationId)) return;
|
|
7260
|
+
conversationDrafts.delete(conversationId);
|
|
7261
|
+
notifyDraftChange();
|
|
7262
|
+
}
|
|
7263
|
+
function getConversationDraftPreview(conversationId) {
|
|
7264
|
+
if (!conversationId) return null;
|
|
7265
|
+
const draft = conversationDrafts.get(conversationId);
|
|
7266
|
+
if (!draft) return null;
|
|
7267
|
+
const text = draft.messageInput.trim();
|
|
7268
|
+
if (text) {
|
|
7269
|
+
return text.length > DRAFT_PREVIEW_MAX_LENGTH ? `${text.slice(0, DRAFT_PREVIEW_MAX_LENGTH)}\u2026` : text;
|
|
7270
|
+
}
|
|
7271
|
+
if (draft.attachments.length > 0) {
|
|
7272
|
+
return draft.attachments.length === 1 ? "Attachment" : `${draft.attachments.length} attachments`;
|
|
7273
|
+
}
|
|
7274
|
+
return null;
|
|
6646
7275
|
}
|
|
6647
7276
|
function useConversationDraft(conversationId) {
|
|
6648
7277
|
const composerRef = useRef(emptyDraft());
|
|
@@ -12198,51 +12827,22 @@ var ChannelDetailsDrawer = (props) => {
|
|
|
12198
12827
|
const pId = typeof p === "string" ? p : p._id;
|
|
12199
12828
|
const pName = typeof p === "string" ? "Unknown" : p.name;
|
|
12200
12829
|
if (!pId) return null;
|
|
12201
|
-
return /* @__PURE__ */ jsx(
|
|
12202
|
-
"span",
|
|
12203
|
-
{
|
|
12204
|
-
className: "rounded-md border border-(--chat-border) bg-(--chat-input-bg)/50 px-2 py-0.5 text-[10px] font-medium text-(--chat-text-secondary)",
|
|
12205
|
-
children: pName
|
|
12206
|
-
},
|
|
12207
|
-
`${pId}-${index}`
|
|
12208
|
-
);
|
|
12209
|
-
}) })
|
|
12210
|
-
] })
|
|
12211
|
-
] })
|
|
12212
|
-
] })
|
|
12213
|
-
] })
|
|
12214
|
-
] }) });
|
|
12215
|
-
};
|
|
12216
|
-
var ChannelDetailsDrawer_default = ChannelDetailsDrawer;
|
|
12217
|
-
function Switch({
|
|
12218
|
-
className,
|
|
12219
|
-
size = "default",
|
|
12220
|
-
...props
|
|
12221
|
-
}) {
|
|
12222
|
-
return /* @__PURE__ */ jsx(
|
|
12223
|
-
Switch$1.Root,
|
|
12224
|
-
{
|
|
12225
|
-
"data-slot": "switch",
|
|
12226
|
-
"data-size": size,
|
|
12227
|
-
className: cn(
|
|
12228
|
-
"peer group/switch inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-[1.15rem] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-input/80",
|
|
12229
|
-
className
|
|
12230
|
-
),
|
|
12231
|
-
...props,
|
|
12232
|
-
children: /* @__PURE__ */ jsx(
|
|
12233
|
-
Switch$1.Thumb,
|
|
12234
|
-
{
|
|
12235
|
-
"data-slot": "switch-thumb",
|
|
12236
|
-
className: cn(
|
|
12237
|
-
"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0 dark:data-[state=checked]:bg-primary-foreground dark:data-[state=unchecked]:bg-foreground"
|
|
12238
|
-
)
|
|
12239
|
-
}
|
|
12240
|
-
)
|
|
12241
|
-
}
|
|
12242
|
-
);
|
|
12243
|
-
}
|
|
12244
|
-
|
|
12245
|
-
// src/chat/header/PermissionDrawer.tsx
|
|
12830
|
+
return /* @__PURE__ */ jsx(
|
|
12831
|
+
"span",
|
|
12832
|
+
{
|
|
12833
|
+
className: "rounded-md border border-(--chat-border) bg-(--chat-input-bg)/50 px-2 py-0.5 text-[10px] font-medium text-(--chat-text-secondary)",
|
|
12834
|
+
children: pName
|
|
12835
|
+
},
|
|
12836
|
+
`${pId}-${index}`
|
|
12837
|
+
);
|
|
12838
|
+
}) })
|
|
12839
|
+
] })
|
|
12840
|
+
] })
|
|
12841
|
+
] })
|
|
12842
|
+
] })
|
|
12843
|
+
] }) });
|
|
12844
|
+
};
|
|
12845
|
+
var ChannelDetailsDrawer_default = ChannelDetailsDrawer;
|
|
12246
12846
|
init_useStore();
|
|
12247
12847
|
var PermissionDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo }) => {
|
|
12248
12848
|
const updateGroupPermissions = useStore((s) => s.updateGroupPermissions);
|
|
@@ -17632,253 +18232,17 @@ function ChatViewport({
|
|
|
17632
18232
|
{
|
|
17633
18233
|
className: cn(
|
|
17634
18234
|
"chat-package-viewport flex min-h-0 w-full flex-col overflow-hidden",
|
|
17635
|
-
resolved.className,
|
|
17636
|
-
className
|
|
17637
|
-
),
|
|
17638
|
-
style: { ...resolved.style, ...style },
|
|
17639
|
-
children
|
|
17640
|
-
}
|
|
17641
|
-
);
|
|
17642
|
-
}
|
|
17643
|
-
var ChatViewport_default = ChatViewport;
|
|
17644
|
-
|
|
17645
|
-
|
|
17646
|
-
icon,
|
|
17647
|
-
duration
|
|
17648
|
-
};
|
|
17649
|
-
switch (type) {
|
|
17650
|
-
case "success":
|
|
17651
|
-
toast.success(message, options);
|
|
17652
|
-
break;
|
|
17653
|
-
case "error":
|
|
17654
|
-
toast.error(message, options);
|
|
17655
|
-
break;
|
|
17656
|
-
case "info":
|
|
17657
|
-
toast(message, options);
|
|
17658
|
-
break;
|
|
17659
|
-
case "warning":
|
|
17660
|
-
toast(message, { ...options, icon: "\u26A0\uFE0F" });
|
|
17661
|
-
break;
|
|
17662
|
-
default:
|
|
17663
|
-
toast(message, options);
|
|
17664
|
-
}
|
|
17665
|
-
};
|
|
17666
|
-
var downloadFile = async (src, name) => {
|
|
17667
|
-
try {
|
|
17668
|
-
const link = document.createElement("a");
|
|
17669
|
-
link.href = src;
|
|
17670
|
-
link.setAttribute("download", name);
|
|
17671
|
-
link.setAttribute("rel", "noopener noreferrer");
|
|
17672
|
-
link.click();
|
|
17673
|
-
showNotification("File Downloaded Successfully", "success");
|
|
17674
|
-
} catch (err) {
|
|
17675
|
-
console.error("File download failed:", err);
|
|
17676
|
-
showNotification("Failed to download file", "error");
|
|
17677
|
-
}
|
|
17678
|
-
};
|
|
17679
|
-
var getResponsiveWidth = (width) => {
|
|
17680
|
-
const screenWidth = window.innerWidth;
|
|
17681
|
-
if (width) {
|
|
17682
|
-
return width;
|
|
17683
|
-
} else if (screenWidth < 640) {
|
|
17684
|
-
return 350;
|
|
17685
|
-
} else if (screenWidth >= 640 && screenWidth < 1024) {
|
|
17686
|
-
return 600;
|
|
17687
|
-
} else if (screenWidth >= 1024 && screenWidth < 1280) {
|
|
17688
|
-
return 800;
|
|
17689
|
-
} else {
|
|
17690
|
-
return 1e3;
|
|
17691
|
-
}
|
|
17692
|
-
};
|
|
17693
|
-
var isEmpty = (value) => {
|
|
17694
|
-
if (value === null || value === void 0) return true;
|
|
17695
|
-
if (typeof value === "string") return value.trim().length === 0;
|
|
17696
|
-
if (Array.isArray(value)) {
|
|
17697
|
-
return value.length === 0 || value.every((item) => isEmpty(item));
|
|
17698
|
-
}
|
|
17699
|
-
if (typeof value === "object") {
|
|
17700
|
-
return Object.keys(value).length === 0;
|
|
17701
|
-
}
|
|
17702
|
-
return false;
|
|
17703
|
-
};
|
|
17704
|
-
function uniqueList(list, key) {
|
|
17705
|
-
const seen = /* @__PURE__ */ new Set();
|
|
17706
|
-
return list.filter((item) => {
|
|
17707
|
-
const value = item[key];
|
|
17708
|
-
if (seen.has(value)) return false;
|
|
17709
|
-
seen.add(value);
|
|
17710
|
-
return true;
|
|
17711
|
-
});
|
|
17712
|
-
}
|
|
17713
|
-
var capitalizeFirst = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
17714
|
-
var getFirstAndLastNameOneCharacter = (name) => {
|
|
17715
|
-
const names = name.split(" ");
|
|
17716
|
-
return names.map((name2) => name2.charAt(0).toUpperCase()).join("");
|
|
17717
|
-
};
|
|
17718
|
-
|
|
17719
|
-
// src/notifications/ForegroundPushBridge.tsx
|
|
17720
|
-
init_normalize_helpers();
|
|
17721
|
-
init_useStore();
|
|
17722
|
-
|
|
17723
|
-
// src/notifications/push.service.ts
|
|
17724
|
-
init_client();
|
|
17725
|
-
var PUSH_TOKEN_STORAGE_KEY = "realtimex-push-token";
|
|
17726
|
-
var SERVICE_WORKER_PATH = "/firebase-messaging-sw.js";
|
|
17727
|
-
var PUSH_CHANGED_EVENT = "realtimex:push-changed";
|
|
17728
|
-
var emitPushChanged = (enabled) => {
|
|
17729
|
-
try {
|
|
17730
|
-
window.dispatchEvent(
|
|
17731
|
-
new CustomEvent(PUSH_CHANGED_EVENT, { detail: { enabled } })
|
|
17732
|
-
);
|
|
17733
|
-
} catch {
|
|
17734
|
-
}
|
|
17735
|
-
};
|
|
17736
|
-
var v2Url = "https://realtimex.softwareco.com/api/v2";
|
|
17737
|
-
var apiGetPushConfig = async () => {
|
|
17738
|
-
const { data } = await apiClient.get(`${v2Url}/notifications/push/config`);
|
|
17739
|
-
return data?.data;
|
|
17740
|
-
};
|
|
17741
|
-
var apiRegisterPushToken = async (token, deviceLabel) => {
|
|
17742
|
-
const { data } = await apiClient.post(`${v2Url}/notifications/push/token`, {
|
|
17743
|
-
token,
|
|
17744
|
-
deviceLabel
|
|
17745
|
-
});
|
|
17746
|
-
return data?.data;
|
|
17747
|
-
};
|
|
17748
|
-
var apiRemovePushToken = async (token) => {
|
|
17749
|
-
const { data } = await apiClient.delete(`${v2Url}/notifications/push/token`, {
|
|
17750
|
-
data: { token }
|
|
17751
|
-
});
|
|
17752
|
-
return data;
|
|
17753
|
-
};
|
|
17754
|
-
var apiGetPushPreference = async () => {
|
|
17755
|
-
const { data } = await apiClient.get(
|
|
17756
|
-
`${v2Url}/notifications/push/preference`
|
|
17757
|
-
);
|
|
17758
|
-
return data?.data;
|
|
17759
|
-
};
|
|
17760
|
-
var apiUpdatePushPreference = async (enabled) => {
|
|
17761
|
-
const { data } = await apiClient.patch(
|
|
17762
|
-
`${v2Url}/notifications/push/preference`,
|
|
17763
|
-
{ enabled }
|
|
17764
|
-
);
|
|
17765
|
-
return data?.data;
|
|
17766
|
-
};
|
|
17767
|
-
var isPushSupported = () => typeof window !== "undefined" && "Notification" in window && "serviceWorker" in navigator && "PushManager" in window;
|
|
17768
|
-
var getStoredPushToken = () => {
|
|
17769
|
-
try {
|
|
17770
|
-
return localStorage.getItem(PUSH_TOKEN_STORAGE_KEY);
|
|
17771
|
-
} catch {
|
|
17772
|
-
return null;
|
|
17773
|
-
}
|
|
17774
|
-
};
|
|
17775
|
-
var storePushToken = (token) => {
|
|
17776
|
-
try {
|
|
17777
|
-
if (token) localStorage.setItem(PUSH_TOKEN_STORAGE_KEY, token);
|
|
17778
|
-
else localStorage.removeItem(PUSH_TOKEN_STORAGE_KEY);
|
|
17779
|
-
} catch {
|
|
17780
|
-
}
|
|
17781
|
-
};
|
|
17782
|
-
var defaultDeviceLabel = () => {
|
|
17783
|
-
const ua = navigator.userAgent;
|
|
17784
|
-
const browser = /edg\//i.test(ua) ? "Edge" : /chrome/i.test(ua) ? "Chrome" : /safari/i.test(ua) ? "Safari" : /firefox/i.test(ua) ? "Firefox" : "Browser";
|
|
17785
|
-
const os = /mac/i.test(ua) ? "macOS" : /windows/i.test(ua) ? "Windows" : /android/i.test(ua) ? "Android" : /iphone|ipad/i.test(ua) ? "iOS" : /linux/i.test(ua) ? "Linux" : "Unknown OS";
|
|
17786
|
-
return `${browser} on ${os}`;
|
|
17787
|
-
};
|
|
17788
|
-
var loadFirebaseMessaging = async () => {
|
|
17789
|
-
try {
|
|
17790
|
-
const [{ initializeApp, getApps }, messagingModule] = await Promise.all([
|
|
17791
|
-
import('firebase/app'),
|
|
17792
|
-
import('firebase/messaging')
|
|
17793
|
-
]);
|
|
17794
|
-
return { initializeApp, getApps, ...messagingModule };
|
|
17795
|
-
} catch {
|
|
17796
|
-
throw new Error(
|
|
17797
|
-
'Push notifications need the "firebase" package \u2014 run: npm install firebase'
|
|
17798
|
-
);
|
|
17799
|
-
}
|
|
17800
|
-
};
|
|
17801
|
-
var getFirebaseMessaging = async (firebaseConfig) => {
|
|
17802
|
-
const fb = await loadFirebaseMessaging();
|
|
17803
|
-
const app = fb.getApps().length ? fb.getApps()[0] : fb.initializeApp(firebaseConfig);
|
|
17804
|
-
return { fb, messaging: fb.getMessaging(app) };
|
|
17805
|
-
};
|
|
17806
|
-
var enablePushOnThisDevice = async () => {
|
|
17807
|
-
if (!isPushSupported()) {
|
|
17808
|
-
throw new Error("Push notifications are not supported in this browser");
|
|
17809
|
-
}
|
|
17810
|
-
const config = await apiGetPushConfig();
|
|
17811
|
-
if (!config?.enabled) {
|
|
17812
|
-
throw new Error("Push notifications are disabled for this workspace");
|
|
17813
|
-
}
|
|
17814
|
-
if (!config.configured || !config.firebaseConfig || !config.vapidKey) {
|
|
17815
|
-
throw new Error(
|
|
17816
|
-
"Push notifications are not configured on the server yet"
|
|
17817
|
-
);
|
|
17818
|
-
}
|
|
17819
|
-
const permission = await Notification.requestPermission();
|
|
17820
|
-
if (permission !== "granted") {
|
|
17821
|
-
throw new Error("Notification permission was not granted");
|
|
17822
|
-
}
|
|
17823
|
-
let registration;
|
|
17824
|
-
try {
|
|
17825
|
-
registration = await navigator.serviceWorker.register(
|
|
17826
|
-
`${SERVICE_WORKER_PATH}?config=${encodeURIComponent(
|
|
17827
|
-
JSON.stringify(config.firebaseConfig)
|
|
17828
|
-
)}`
|
|
17829
|
-
);
|
|
17830
|
-
} catch {
|
|
17831
|
-
throw new Error(
|
|
17832
|
-
`Could not register ${SERVICE_WORKER_PATH} \u2014 copy it from node_modules/@realtimexsco/live-chat/dist/firebase-messaging-sw.js into your app's public folder`
|
|
17833
|
-
);
|
|
17834
|
-
}
|
|
17835
|
-
const { fb, messaging } = await getFirebaseMessaging(config.firebaseConfig);
|
|
17836
|
-
const token = await fb.getToken(messaging, {
|
|
17837
|
-
vapidKey: config.vapidKey,
|
|
17838
|
-
serviceWorkerRegistration: registration
|
|
17839
|
-
});
|
|
17840
|
-
if (!token) {
|
|
17841
|
-
throw new Error("Could not obtain a push token from Firebase");
|
|
17842
|
-
}
|
|
17843
|
-
await apiRegisterPushToken(token, defaultDeviceLabel());
|
|
17844
|
-
storePushToken(token);
|
|
17845
|
-
emitPushChanged(true);
|
|
17846
|
-
return token;
|
|
17847
|
-
};
|
|
17848
|
-
var disablePushOnThisDevice = async () => {
|
|
17849
|
-
const token = getStoredPushToken();
|
|
17850
|
-
if (!token) return;
|
|
17851
|
-
try {
|
|
17852
|
-
const config = await apiGetPushConfig();
|
|
17853
|
-
if (config?.firebaseConfig) {
|
|
17854
|
-
const { fb, messaging } = await getFirebaseMessaging(
|
|
17855
|
-
config.firebaseConfig
|
|
17856
|
-
);
|
|
17857
|
-
await fb.deleteToken(messaging).catch(() => void 0);
|
|
17858
|
-
}
|
|
17859
|
-
} catch {
|
|
17860
|
-
}
|
|
17861
|
-
await apiRemovePushToken(token).catch(() => void 0);
|
|
17862
|
-
storePushToken(null);
|
|
17863
|
-
emitPushChanged(false);
|
|
17864
|
-
};
|
|
17865
|
-
var onForegroundPush = async (callback) => {
|
|
17866
|
-
const config = await apiGetPushConfig();
|
|
17867
|
-
if (!config?.configured || !config.firebaseConfig) {
|
|
17868
|
-
throw new Error("Push config unavailable (not configured or API not ready)");
|
|
17869
|
-
}
|
|
17870
|
-
const { fb, messaging } = await getFirebaseMessaging(config.firebaseConfig);
|
|
17871
|
-
return fb.onMessage(messaging, (payload) => {
|
|
17872
|
-
console.log("[realtimex-push] FCM foreground payload (raw):", payload);
|
|
17873
|
-
console.log("[realtimex-push] FCM foreground data:", payload?.data);
|
|
17874
|
-
console.log("[realtimex-push] FCM foreground notification:", payload?.notification);
|
|
17875
|
-
callback({
|
|
17876
|
-
title: payload?.notification?.title,
|
|
17877
|
-
body: payload?.notification?.body,
|
|
17878
|
-
data: payload?.data
|
|
17879
|
-
});
|
|
17880
|
-
});
|
|
17881
|
-
};
|
|
18235
|
+
resolved.className,
|
|
18236
|
+
className
|
|
18237
|
+
),
|
|
18238
|
+
style: { ...resolved.style, ...style },
|
|
18239
|
+
children
|
|
18240
|
+
}
|
|
18241
|
+
);
|
|
18242
|
+
}
|
|
18243
|
+
var ChatViewport_default = ChatViewport;
|
|
18244
|
+
init_normalize_helpers();
|
|
18245
|
+
init_useStore();
|
|
17882
18246
|
var RETRY_DELAYS_MS = [1e3, 3e3, 8e3, 2e4];
|
|
17883
18247
|
var recentToastIds = /* @__PURE__ */ new Set();
|
|
17884
18248
|
var rememberToastId = (id) => {
|
|
@@ -17892,48 +18256,95 @@ var rememberToastId = (id) => {
|
|
|
17892
18256
|
}
|
|
17893
18257
|
return true;
|
|
17894
18258
|
};
|
|
17895
|
-
var
|
|
17896
|
-
|
|
17897
|
-
|
|
18259
|
+
var truncate = (value, max) => value.length > max ? `${value.slice(0, max - 1)}\u2026` : value;
|
|
18260
|
+
var PushMessageToast = ({
|
|
18261
|
+
t,
|
|
18262
|
+
title,
|
|
18263
|
+
body,
|
|
18264
|
+
onOpen
|
|
18265
|
+
}) => {
|
|
18266
|
+
const dismiss = () => toast$1.dismiss(t.id);
|
|
18267
|
+
const handleDismiss = (event) => {
|
|
18268
|
+
event.stopPropagation();
|
|
18269
|
+
dismiss();
|
|
18270
|
+
};
|
|
18271
|
+
const handleOpen = () => {
|
|
18272
|
+
dismiss();
|
|
18273
|
+
onOpen?.();
|
|
18274
|
+
};
|
|
18275
|
+
return /* @__PURE__ */ jsxs(
|
|
18276
|
+
"div",
|
|
18277
|
+
{
|
|
18278
|
+
role: "alert",
|
|
18279
|
+
"aria-live": "polite",
|
|
18280
|
+
onClick: onOpen ? handleOpen : void 0,
|
|
18281
|
+
onKeyDown: onOpen ? (event) => {
|
|
18282
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
18283
|
+
event.preventDefault();
|
|
18284
|
+
handleOpen();
|
|
18285
|
+
}
|
|
18286
|
+
} : void 0,
|
|
18287
|
+
tabIndex: onOpen ? 0 : void 0,
|
|
18288
|
+
className: cn(
|
|
18289
|
+
"pointer-events-auto flex w-[min(320px,calc(100vw-24px))] items-start gap-3 rounded-xl border border-(--chat-border) bg-(--chat-surface) p-3 shadow-[0_8px_24px_rgba(15,23,42,0.12)] transition-[opacity,transform] duration-200 ease-out",
|
|
18290
|
+
onOpen && "cursor-pointer hover:border-(--chat-theme-20) hover:shadow-[0_10px_28px_rgba(15,23,42,0.16)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-(--chat-theme-30)",
|
|
18291
|
+
t.visible ? "translate-y-0 opacity-100" : "-translate-y-1 opacity-0"
|
|
18292
|
+
),
|
|
18293
|
+
children: [
|
|
18294
|
+
/* @__PURE__ */ jsx(
|
|
18295
|
+
"div",
|
|
18296
|
+
{
|
|
18297
|
+
"aria-hidden": true,
|
|
18298
|
+
className: "flex size-9 shrink-0 items-center justify-center rounded-lg bg-(--chat-theme-10) text-(--chat-theme)",
|
|
18299
|
+
children: /* @__PURE__ */ jsx(MessageSquare, { className: "size-4", strokeWidth: 2.25 })
|
|
18300
|
+
}
|
|
18301
|
+
),
|
|
18302
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 pt-0.5", children: [
|
|
18303
|
+
/* @__PURE__ */ jsx("p", { className: "text-[11px] font-semibold uppercase tracking-wide text-(--chat-muted)", children: "New message" }),
|
|
18304
|
+
/* @__PURE__ */ jsx("p", { className: "mt-0.5 truncate text-sm font-semibold leading-snug text-(--chat-text)", children: truncate(title, 40) }),
|
|
18305
|
+
body ? /* @__PURE__ */ jsx("p", { className: "mt-0.5 line-clamp-2 text-xs leading-relaxed text-(--chat-muted)", children: truncate(body, 72) }) : null
|
|
18306
|
+
] }),
|
|
18307
|
+
/* @__PURE__ */ jsx(
|
|
18308
|
+
"button",
|
|
18309
|
+
{
|
|
18310
|
+
type: "button",
|
|
18311
|
+
"aria-label": "Dismiss notification",
|
|
18312
|
+
onClick: handleDismiss,
|
|
18313
|
+
className: "shrink-0 rounded-md p-1 text-(--chat-muted) transition-colors hover:bg-(--chat-hover) hover:text-(--chat-text) focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-(--chat-theme-30)",
|
|
18314
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4", strokeWidth: 2 })
|
|
18315
|
+
}
|
|
18316
|
+
)
|
|
18317
|
+
]
|
|
18318
|
+
}
|
|
18319
|
+
);
|
|
17898
18320
|
};
|
|
17899
18321
|
var emitToast = (payload, onPush) => {
|
|
17900
18322
|
if (onPush && onPush(payload) !== false) return;
|
|
17901
|
-
const title = payload.title || payload.data?.title;
|
|
17902
|
-
const body = payload.body || payload.data?.body || payload.data?.message;
|
|
17903
|
-
const text = resolveToastText(title, body);
|
|
18323
|
+
const title = payload.title || payload.data?.title || "New message";
|
|
18324
|
+
const body = payload.body || payload.data?.body || payload.data?.message || "";
|
|
17904
18325
|
const conversationId = resolveConversationIdFromPushData(payload.data);
|
|
17905
|
-
|
|
17906
|
-
|
|
17907
|
-
|
|
17908
|
-
|
|
17909
|
-
|
|
17910
|
-
|
|
17911
|
-
|
|
17912
|
-
|
|
17913
|
-
|
|
17914
|
-
|
|
17915
|
-
|
|
17916
|
-
|
|
17917
|
-
|
|
17918
|
-
|
|
17919
|
-
|
|
17920
|
-
|
|
17921
|
-
|
|
17922
|
-
|
|
17923
|
-
|
|
17924
|
-
|
|
17925
|
-
|
|
17926
|
-
|
|
17927
|
-
font: "inherit"
|
|
17928
|
-
},
|
|
17929
|
-
children: text
|
|
17930
|
-
}
|
|
17931
|
-
),
|
|
17932
|
-
{ duration: 5e3 }
|
|
17933
|
-
);
|
|
17934
|
-
return;
|
|
17935
|
-
}
|
|
17936
|
-
showNotification(text, "info");
|
|
18326
|
+
const messageId2 = String(
|
|
18327
|
+
payload.data?.messageId || payload.data?.message_id || payload.data?.messageID || ""
|
|
18328
|
+
);
|
|
18329
|
+
if (!title && !body) return;
|
|
18330
|
+
toast$1.custom(
|
|
18331
|
+
(t) => /* @__PURE__ */ jsx(
|
|
18332
|
+
PushMessageToast,
|
|
18333
|
+
{
|
|
18334
|
+
t,
|
|
18335
|
+
title,
|
|
18336
|
+
body: body || void 0,
|
|
18337
|
+
onOpen: conversationId ? () => requestOpenConversation(
|
|
18338
|
+
conversationId,
|
|
18339
|
+
payload.data
|
|
18340
|
+
) : void 0
|
|
18341
|
+
}
|
|
18342
|
+
),
|
|
18343
|
+
{
|
|
18344
|
+
duration: 5e3,
|
|
18345
|
+
id: messageId2 || void 0
|
|
18346
|
+
}
|
|
18347
|
+
);
|
|
17937
18348
|
};
|
|
17938
18349
|
var ForegroundPushBridge = ({ onPush }) => {
|
|
17939
18350
|
const lastDM = useStore((s) => s.lastDM);
|
|
@@ -18071,8 +18482,28 @@ var ForegroundPushBridge = ({ onPush }) => {
|
|
|
18071
18482
|
Toaster,
|
|
18072
18483
|
{
|
|
18073
18484
|
position: "top-right",
|
|
18074
|
-
|
|
18075
|
-
|
|
18485
|
+
gutter: 12,
|
|
18486
|
+
containerClassName: "realtimex-push-toaster",
|
|
18487
|
+
containerStyle: {
|
|
18488
|
+
zIndex: 99999,
|
|
18489
|
+
top: 16,
|
|
18490
|
+
right: 16,
|
|
18491
|
+
width: "auto",
|
|
18492
|
+
maxWidth: "none"
|
|
18493
|
+
},
|
|
18494
|
+
toastOptions: {
|
|
18495
|
+
duration: 5e3,
|
|
18496
|
+
className: "!w-auto !max-w-none",
|
|
18497
|
+
style: {
|
|
18498
|
+
padding: 0,
|
|
18499
|
+
margin: 0,
|
|
18500
|
+
background: "transparent",
|
|
18501
|
+
boxShadow: "none",
|
|
18502
|
+
border: "none",
|
|
18503
|
+
width: "auto",
|
|
18504
|
+
maxWidth: "none"
|
|
18505
|
+
}
|
|
18506
|
+
}
|
|
18076
18507
|
}
|
|
18077
18508
|
);
|
|
18078
18509
|
};
|
|
@@ -18085,6 +18516,7 @@ var ChatMain = ({
|
|
|
18085
18516
|
queryParams,
|
|
18086
18517
|
queryParamApis,
|
|
18087
18518
|
queryParamsByApi,
|
|
18519
|
+
apiVersions: apiVersions2,
|
|
18088
18520
|
themeColor = "#7494ec",
|
|
18089
18521
|
theme,
|
|
18090
18522
|
uiConfig,
|
|
@@ -18154,6 +18586,7 @@ var ChatMain = ({
|
|
|
18154
18586
|
queryParams,
|
|
18155
18587
|
queryParamApis,
|
|
18156
18588
|
queryParamsByApi,
|
|
18589
|
+
apiVersions: apiVersions2,
|
|
18157
18590
|
children: [
|
|
18158
18591
|
/* @__PURE__ */ jsx(ForegroundPushBridge, {}),
|
|
18159
18592
|
/* @__PURE__ */ jsx(
|
|
@@ -18229,6 +18662,80 @@ var getSocketConfig = (accessToken, tenantId, options) => {
|
|
|
18229
18662
|
}
|
|
18230
18663
|
};
|
|
18231
18664
|
};
|
|
18665
|
+
var showNotification = (message, type = "info", icon, duration) => {
|
|
18666
|
+
const options = {
|
|
18667
|
+
icon,
|
|
18668
|
+
duration
|
|
18669
|
+
};
|
|
18670
|
+
switch (type) {
|
|
18671
|
+
case "success":
|
|
18672
|
+
toast.success(message, options);
|
|
18673
|
+
break;
|
|
18674
|
+
case "error":
|
|
18675
|
+
toast.error(message, options);
|
|
18676
|
+
break;
|
|
18677
|
+
case "info":
|
|
18678
|
+
toast(message, options);
|
|
18679
|
+
break;
|
|
18680
|
+
case "warning":
|
|
18681
|
+
toast(message, { ...options, icon: "\u26A0\uFE0F" });
|
|
18682
|
+
break;
|
|
18683
|
+
default:
|
|
18684
|
+
toast(message, options);
|
|
18685
|
+
}
|
|
18686
|
+
};
|
|
18687
|
+
var downloadFile = async (src, name) => {
|
|
18688
|
+
try {
|
|
18689
|
+
const link = document.createElement("a");
|
|
18690
|
+
link.href = src;
|
|
18691
|
+
link.setAttribute("download", name);
|
|
18692
|
+
link.setAttribute("rel", "noopener noreferrer");
|
|
18693
|
+
link.click();
|
|
18694
|
+
showNotification("File Downloaded Successfully", "success");
|
|
18695
|
+
} catch (err) {
|
|
18696
|
+
console.error("File download failed:", err);
|
|
18697
|
+
showNotification("Failed to download file", "error");
|
|
18698
|
+
}
|
|
18699
|
+
};
|
|
18700
|
+
var getResponsiveWidth = (width) => {
|
|
18701
|
+
const screenWidth = window.innerWidth;
|
|
18702
|
+
if (width) {
|
|
18703
|
+
return width;
|
|
18704
|
+
} else if (screenWidth < 640) {
|
|
18705
|
+
return 350;
|
|
18706
|
+
} else if (screenWidth >= 640 && screenWidth < 1024) {
|
|
18707
|
+
return 600;
|
|
18708
|
+
} else if (screenWidth >= 1024 && screenWidth < 1280) {
|
|
18709
|
+
return 800;
|
|
18710
|
+
} else {
|
|
18711
|
+
return 1e3;
|
|
18712
|
+
}
|
|
18713
|
+
};
|
|
18714
|
+
var isEmpty = (value) => {
|
|
18715
|
+
if (value === null || value === void 0) return true;
|
|
18716
|
+
if (typeof value === "string") return value.trim().length === 0;
|
|
18717
|
+
if (Array.isArray(value)) {
|
|
18718
|
+
return value.length === 0 || value.every((item) => isEmpty(item));
|
|
18719
|
+
}
|
|
18720
|
+
if (typeof value === "object") {
|
|
18721
|
+
return Object.keys(value).length === 0;
|
|
18722
|
+
}
|
|
18723
|
+
return false;
|
|
18724
|
+
};
|
|
18725
|
+
function uniqueList(list, key) {
|
|
18726
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18727
|
+
return list.filter((item) => {
|
|
18728
|
+
const value = item[key];
|
|
18729
|
+
if (seen.has(value)) return false;
|
|
18730
|
+
seen.add(value);
|
|
18731
|
+
return true;
|
|
18732
|
+
});
|
|
18733
|
+
}
|
|
18734
|
+
var capitalizeFirst = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
18735
|
+
var getFirstAndLastNameOneCharacter = (name) => {
|
|
18736
|
+
const names = name.split(" ");
|
|
18737
|
+
return names.map((name2) => name2.charAt(0).toUpperCase()).join("");
|
|
18738
|
+
};
|
|
18232
18739
|
var SIZE_MAP = {
|
|
18233
18740
|
xs: "size-6",
|
|
18234
18741
|
sm: "size-8",
|
|
@@ -18372,6 +18879,10 @@ var ChannelListItem_default = ChannelListItem2;
|
|
|
18372
18879
|
var packageDefaultComponents = {
|
|
18373
18880
|
ChatLayout: DefaultChatLayout_default,
|
|
18374
18881
|
LoggedUserDetails: LoggedUserDetails_default,
|
|
18882
|
+
LoggedUserSettingsDialog: LoggedUserSettingsDialog_default,
|
|
18883
|
+
LoggedUserSettingsTrigger: LoggedUserSettingsTrigger_default,
|
|
18884
|
+
LoggedUserSettingsContent: LoggedUserSettingsContent_default,
|
|
18885
|
+
PushNotificationToggle,
|
|
18375
18886
|
ChannelList: ChannelListView_default,
|
|
18376
18887
|
ChannelListItem: DefaultChannelListItem,
|
|
18377
18888
|
ChannelHeader: ChannelHeaderView_default,
|
|
@@ -18402,139 +18913,10 @@ var packageDefaultComponents = {
|
|
|
18402
18913
|
ChatDateTimeSettings: ChatDateTimeSettings_default,
|
|
18403
18914
|
ChatSocketStatus: ChatSocketStatus_default
|
|
18404
18915
|
};
|
|
18405
|
-
var usePushNotifications = () => {
|
|
18406
|
-
const [state, setState] = useState({
|
|
18407
|
-
supported: false,
|
|
18408
|
-
allowedByWorkspace: false,
|
|
18409
|
-
configured: false,
|
|
18410
|
-
permission: "unsupported",
|
|
18411
|
-
userEnabled: true,
|
|
18412
|
-
deviceEnabled: false,
|
|
18413
|
-
loading: true,
|
|
18414
|
-
error: null
|
|
18415
|
-
});
|
|
18416
|
-
const refresh = useCallback(async () => {
|
|
18417
|
-
if (!isPushSupported()) {
|
|
18418
|
-
setState((prev) => ({
|
|
18419
|
-
...prev,
|
|
18420
|
-
supported: false,
|
|
18421
|
-
loading: false
|
|
18422
|
-
}));
|
|
18423
|
-
return;
|
|
18424
|
-
}
|
|
18425
|
-
try {
|
|
18426
|
-
const [config, preference] = await Promise.all([
|
|
18427
|
-
apiGetPushConfig(),
|
|
18428
|
-
apiGetPushPreference().catch(() => null)
|
|
18429
|
-
]);
|
|
18430
|
-
setState({
|
|
18431
|
-
supported: true,
|
|
18432
|
-
allowedByWorkspace: Boolean(config?.enabled),
|
|
18433
|
-
configured: Boolean(config?.configured),
|
|
18434
|
-
permission: Notification.permission,
|
|
18435
|
-
userEnabled: preference?.enabled ?? true,
|
|
18436
|
-
deviceEnabled: Notification.permission === "granted" && Boolean(getStoredPushToken()),
|
|
18437
|
-
loading: false,
|
|
18438
|
-
error: null
|
|
18439
|
-
});
|
|
18440
|
-
} catch (error) {
|
|
18441
|
-
setState((prev) => ({
|
|
18442
|
-
...prev,
|
|
18443
|
-
supported: true,
|
|
18444
|
-
loading: false,
|
|
18445
|
-
error: error instanceof Error ? error.message : "Could not load push settings"
|
|
18446
|
-
}));
|
|
18447
|
-
}
|
|
18448
|
-
}, []);
|
|
18449
|
-
useEffect(() => {
|
|
18450
|
-
void refresh();
|
|
18451
|
-
}, [refresh]);
|
|
18452
|
-
const enable = useCallback(async () => {
|
|
18453
|
-
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
18454
|
-
try {
|
|
18455
|
-
await enablePushOnThisDevice();
|
|
18456
|
-
await refresh();
|
|
18457
|
-
return true;
|
|
18458
|
-
} catch (error) {
|
|
18459
|
-
setState((prev) => ({
|
|
18460
|
-
...prev,
|
|
18461
|
-
loading: false,
|
|
18462
|
-
permission: isPushSupported() ? Notification.permission : "unsupported",
|
|
18463
|
-
error: error instanceof Error ? error.message : "Could not enable push notifications"
|
|
18464
|
-
}));
|
|
18465
|
-
return false;
|
|
18466
|
-
}
|
|
18467
|
-
}, [refresh]);
|
|
18468
|
-
const disable = useCallback(async () => {
|
|
18469
|
-
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
18470
|
-
try {
|
|
18471
|
-
await disablePushOnThisDevice();
|
|
18472
|
-
} finally {
|
|
18473
|
-
await refresh();
|
|
18474
|
-
}
|
|
18475
|
-
}, [refresh]);
|
|
18476
|
-
const setUserEnabled = useCallback(
|
|
18477
|
-
async (enabled) => {
|
|
18478
|
-
setState((prev) => ({ ...prev, userEnabled: enabled }));
|
|
18479
|
-
try {
|
|
18480
|
-
await apiUpdatePushPreference(enabled);
|
|
18481
|
-
} catch (error) {
|
|
18482
|
-
setState((prev) => ({
|
|
18483
|
-
...prev,
|
|
18484
|
-
userEnabled: !enabled,
|
|
18485
|
-
error: error instanceof Error ? error.message : "Could not update push preference"
|
|
18486
|
-
}));
|
|
18487
|
-
}
|
|
18488
|
-
},
|
|
18489
|
-
[]
|
|
18490
|
-
);
|
|
18491
|
-
return { ...state, enable, disable, setUserEnabled, refresh };
|
|
18492
|
-
};
|
|
18493
|
-
var PushNotificationToggle = ({
|
|
18494
|
-
className,
|
|
18495
|
-
label = "Push notifications",
|
|
18496
|
-
description = "Get notified about new messages on this device"
|
|
18497
|
-
}) => {
|
|
18498
|
-
const push = usePushNotifications();
|
|
18499
|
-
if (!push.supported || !push.allowedByWorkspace || !push.configured) {
|
|
18500
|
-
return null;
|
|
18501
|
-
}
|
|
18502
|
-
const isOn = push.deviceEnabled && push.userEnabled;
|
|
18503
|
-
const permissionBlocked = push.permission === "denied";
|
|
18504
|
-
const handleChange = async (checked) => {
|
|
18505
|
-
if (checked) {
|
|
18506
|
-
if (!push.userEnabled) await push.setUserEnabled(true);
|
|
18507
|
-
if (!push.deviceEnabled) await push.enable();
|
|
18508
|
-
} else {
|
|
18509
|
-
await push.disable();
|
|
18510
|
-
}
|
|
18511
|
-
};
|
|
18512
|
-
return /* @__PURE__ */ jsxs(
|
|
18513
|
-
"div",
|
|
18514
|
-
{
|
|
18515
|
-
className: className ?? "flex items-center justify-between gap-4 rounded-xl border border-border bg-background px-4 py-3",
|
|
18516
|
-
children: [
|
|
18517
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
18518
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: label }),
|
|
18519
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: permissionBlocked ? "Notifications are blocked in your browser settings" : push.error ?? description })
|
|
18520
|
-
] }),
|
|
18521
|
-
/* @__PURE__ */ jsx(
|
|
18522
|
-
Switch,
|
|
18523
|
-
{
|
|
18524
|
-
checked: isOn,
|
|
18525
|
-
disabled: push.loading || permissionBlocked,
|
|
18526
|
-
onCheckedChange: (checked) => void handleChange(checked),
|
|
18527
|
-
"aria-label": `Toggle ${label}`
|
|
18528
|
-
}
|
|
18529
|
-
)
|
|
18530
|
-
]
|
|
18531
|
-
}
|
|
18532
|
-
);
|
|
18533
|
-
};
|
|
18534
18916
|
|
|
18535
18917
|
// src/index.ts
|
|
18536
18918
|
var index_default = ChatMain_default;
|
|
18537
18919
|
|
|
18538
|
-
export { CHAT_API_KEYS, CHAT_GET_API_KEYS, Calendar, CalendarDayButton, Channel, ChannelHeaderView_default as ChannelHeader, ChannelListView_default as ChannelList, ChannelListItem_default as ChannelListItem, Chat, ChatAlertsProvider, ChatAvatar_default as ChatAvatar, ChatCustomizationProvider, ChatDateJumpMenu, ChatLayout_default as ChatLayout, ChatLocaleProvider, ChatMain_default as ChatMain, ChatThemeProvider, ChatViewport, DefaultChannelListItem, DefaultChatAvatar, DefaultChatLayout_default as DefaultChatLayout, ForegroundPushBridge, ForwardModalView as ForwardModal, HeaderCallActions_default as HeaderCallActions, LoggedUserDetails_default as LoggedUserDetails, ChannelMessageBoxView_default as MessageInput, MessageItemView as MessageItem, ActiveChannelMessagesView_default as MessageList, NOTIFICATION_CLICK_SW_TYPE, OPEN_CONVERSATION_EVENT, PUSH_BROADCAST_CHANNEL, PUSH_CHANGED_EVENT, PushNotificationToggle, apiGetPushConfig, apiGetPushPreference, apiRegisterPushToken, apiRemovePushToken, apiUpdatePushPreference, buildChannelFromPushRequest, capitalizeFirst, clampJumpDate, consumePendingOpenConversation, consumePendingOpenRequest, index_default as default, defaultChatClassNames, defaultChatComponents, defaultChatFeatures, defaultChatLayoutConfig, disablePushOnThisDevice, downloadFile, enablePushOnThisDevice, getChatBaseUrl, getChatQueryParamApis, getChatQueryParams, getChatQueryParamsByApi, getChatSocketUrl, getFirstAndLastNameOneCharacter, getResponsiveWidth, getSocketConfig, getStoredPushToken, installNotificationClickBridge, isEmpty, isPushSupported, mergeChatCustomization, mergeChatLayoutConfig, onForegroundPush, packageDefaultComponents, peekPendingOpenConversation, peekPendingOpenRequest, requestOpenConversation, resolveApiUrl, resolveChatApiKey, resolveConversationIdFromPushData, resolveJumpDateBounds, resolveJumpPreset, resolveJumpStep, resolveSocketUrl, setChatAccessToken, setChatBaseURL, setChatClientId, setChatQueryParamApis, setChatQueryParams, setChatQueryParamsByApi, setChatSocketUrl, showNotification, smoothScrollToMessage, socket_service_default as socketService, startOfLocalDay, toDateInputValue, uniqueList, useChatAlerts, useChatContext, useChatController, useChatCustomization, useChatCustomizationOptional, useChatFeatures, useChatFeaturesOptional, useChatLocale, useStore as useChatStore, useChatTheme, usePushNotifications };
|
|
18920
|
+
export { CHAT_API_KEYS, CHAT_GET_API_KEYS, Calendar, CalendarDayButton, Channel, ChannelHeaderView_default as ChannelHeader, ChannelListView_default as ChannelList, ChannelListItem_default as ChannelListItem, Chat, ChatAlertsProvider, ChatAvatar_default as ChatAvatar, ChatCustomizationProvider, ChatDateJumpMenu, ChatLayout_default as ChatLayout, ChatLocaleProvider, ChatMain_default as ChatMain, ChatThemeProvider, ChatViewport, DefaultChannelListItem, DefaultChatAvatar, DefaultChatLayout_default as DefaultChatLayout, ForegroundPushBridge, ForwardModalView as ForwardModal, HeaderCallActions_default as HeaderCallActions, LoggedUserDetails_default as LoggedUserDetails, LoggedUserSettingsContent_default as LoggedUserSettingsContent, LoggedUserSettingsDialog_default as LoggedUserSettingsDialog, LoggedUserSettingsTrigger_default as LoggedUserSettingsTrigger, ChannelMessageBoxView_default as MessageInput, MessageItemView as MessageItem, ActiveChannelMessagesView_default as MessageList, NOTIFICATION_CLICK_SW_TYPE, OPEN_CONVERSATION_EVENT, PUSH_BROADCAST_CHANNEL, PUSH_CHANGED_EVENT, PUSH_DATA_CACHE_NAME, PushNotificationToggle, apiGetPushConfig, apiGetPushPreference, apiRegisterPushToken, apiRemovePushToken, apiUpdatePushPreference, buildChannelFromPushRequest, buildLoggedUserProfile, buildVersionedApiUrl, capitalizeFirst, clampJumpDate, consumePendingOpenConversation, consumePendingOpenFromPushCache, consumePendingOpenRequest, index_default as default, defaultChatClassNames, defaultChatComponents, defaultChatFeatures, defaultChatLayoutConfig, disablePushOnThisDevice, downloadFile, enablePushOnThisDevice, getChatApiVersions, getChatBaseUrl, getChatQueryParamApis, getChatQueryParams, getChatQueryParamsByApi, getChatSocketUrl, getFirstAndLastNameOneCharacter, getResponsiveWidth, getSocketConfig, getStoredPushToken, installNotificationClickBridge, isEmpty, isPushSupported, mergeChatCustomization, mergeChatLayoutConfig, onForegroundPush, packageDefaultComponents, peekPendingOpenConversation, peekPendingOpenRequest, requestOpenConversation, resolveApiRoot, resolveApiUrl, resolveChatApiKey, resolveConversationIdFromPushData, resolveJumpDateBounds, resolveJumpPreset, resolveJumpStep, resolveSocketUrl, setChatAccessToken, setChatApiVersions, setChatBaseURL, setChatClientId, setChatPushApiVersion, setChatQueryParamApis, setChatQueryParams, setChatQueryParamsByApi, setChatSocketUrl, showNotification, smoothScrollToMessage, socket_service_default as socketService, startOfLocalDay, toDateInputValue, uniqueList, useChatAlerts, useChatContext, useChatController, useChatCustomization, useChatCustomizationOptional, useChatFeatures, useChatFeaturesOptional, useChatLocale, useStore as useChatStore, useChatTheme, usePushNotifications };
|
|
18539
18921
|
//# sourceMappingURL=index.mjs.map
|
|
18540
18922
|
//# sourceMappingURL=index.mjs.map
|