@realtimexsco/live-chat 1.4.10 → 1.4.12
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/LICENSE +2 -2
- package/README.md +6 -6
- package/dist/index.cjs +1374 -504
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +206 -47
- package/dist/index.d.ts +206 -47
- package/dist/index.mjs +1105 -242
- package/dist/index.mjs.map +1 -1
- package/package.json +19 -4
package/dist/index.mjs
CHANGED
|
@@ -2,14 +2,14 @@ import { io } from 'socket.io-client';
|
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { create } from 'zustand';
|
|
4
4
|
import { persist } from 'zustand/middleware';
|
|
5
|
-
import * as
|
|
6
|
-
import
|
|
7
|
-
import { Tooltip as Tooltip$1, Slot, Switch as Switch$1, Avatar as Avatar$1, ScrollArea as ScrollArea$1, Popover as Popover$1, DropdownMenu as DropdownMenu$1,
|
|
5
|
+
import * as React3 from 'react';
|
|
6
|
+
import React3__default, { createContext, useMemo, useContext, useState, useCallback, useEffect, useRef, useLayoutEffect, Fragment as Fragment$1, useSyncExternalStore } from 'react';
|
|
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';
|
|
@@ -1162,6 +1162,7 @@ function resolveChatApiKey(url) {
|
|
|
1162
1162
|
}
|
|
1163
1163
|
if (path.includes("/message/search-messages")) return "searchMessages";
|
|
1164
1164
|
if (path.includes("/message/searched-message/context")) return "searchMessagesContext";
|
|
1165
|
+
if (path.includes("/settings/effective")) return "effectiveSettings";
|
|
1165
1166
|
if (path.includes("/conversation/group/create")) return "createGroup";
|
|
1166
1167
|
if (path.includes("/conversation/group/permission/update")) return "updateGroupPermissions";
|
|
1167
1168
|
if (path.includes("/conversation/group/information/update")) return "updateGroupInfo";
|
|
@@ -1205,7 +1206,8 @@ var init_query_params = __esm({
|
|
|
1205
1206
|
"pinnedMessages",
|
|
1206
1207
|
"starredMessages",
|
|
1207
1208
|
"searchMessages",
|
|
1208
|
-
"searchMessagesContext"
|
|
1209
|
+
"searchMessagesContext",
|
|
1210
|
+
"effectiveSettings"
|
|
1209
1211
|
];
|
|
1210
1212
|
CHAT_API_KEYS = [
|
|
1211
1213
|
"all",
|
|
@@ -1223,6 +1225,64 @@ var init_query_params = __esm({
|
|
|
1223
1225
|
];
|
|
1224
1226
|
}
|
|
1225
1227
|
});
|
|
1228
|
+
|
|
1229
|
+
// src/services/api/api-version.ts
|
|
1230
|
+
var DEFAULT_VERSIONS, apiVersions, normalizeApiVersion, resolveApiRoot, buildVersionedApiUrl, setChatApiVersions, getChatApiVersions, setChatPushApiVersion, syncDefaultApiVersionFromBaseUrl;
|
|
1231
|
+
var init_api_version = __esm({
|
|
1232
|
+
"src/services/api/api-version.ts"() {
|
|
1233
|
+
init_client();
|
|
1234
|
+
DEFAULT_VERSIONS = {
|
|
1235
|
+
v1: "v1",
|
|
1236
|
+
v2: "v2"
|
|
1237
|
+
};
|
|
1238
|
+
apiVersions = { ...DEFAULT_VERSIONS };
|
|
1239
|
+
normalizeApiVersion = (version) => {
|
|
1240
|
+
const raw = String(version || "v1").trim().replace(/^\/+|\/+$/g, "");
|
|
1241
|
+
if (!raw) return "v1";
|
|
1242
|
+
return /^v\d+$/i.test(raw) ? raw.toLowerCase() : `v${raw}`;
|
|
1243
|
+
};
|
|
1244
|
+
resolveApiRoot = (baseUrl) => {
|
|
1245
|
+
const raw = String(
|
|
1246
|
+
baseUrl || getChatBaseUrl() || apiClient.defaults.baseURL || ""
|
|
1247
|
+
).trim().replace(/\/$/, "");
|
|
1248
|
+
if (!raw) return "";
|
|
1249
|
+
const withoutVersion = raw.replace(/\/v\d+$/i, "");
|
|
1250
|
+
return withoutVersion || raw;
|
|
1251
|
+
};
|
|
1252
|
+
buildVersionedApiUrl = (path, options) => {
|
|
1253
|
+
const root = resolveApiRoot(options?.baseUrl);
|
|
1254
|
+
const version = normalizeApiVersion(
|
|
1255
|
+
options?.version ?? (options?.service ? apiVersions[options.service] : apiVersions.v1)
|
|
1256
|
+
);
|
|
1257
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
1258
|
+
if (!root) {
|
|
1259
|
+
return `/${version}${normalizedPath}`;
|
|
1260
|
+
}
|
|
1261
|
+
return `${root}/${version}${normalizedPath}`;
|
|
1262
|
+
};
|
|
1263
|
+
setChatApiVersions = (config) => {
|
|
1264
|
+
if (!config) return;
|
|
1265
|
+
if (config.v1) {
|
|
1266
|
+
apiVersions.v1 = normalizeApiVersion(config.v1);
|
|
1267
|
+
}
|
|
1268
|
+
if (config.v2) {
|
|
1269
|
+
apiVersions.v2 = normalizeApiVersion(config.v2);
|
|
1270
|
+
}
|
|
1271
|
+
};
|
|
1272
|
+
getChatApiVersions = () => ({
|
|
1273
|
+
...apiVersions
|
|
1274
|
+
});
|
|
1275
|
+
setChatPushApiVersion = (version) => {
|
|
1276
|
+
apiVersions.v2 = normalizeApiVersion(version);
|
|
1277
|
+
};
|
|
1278
|
+
syncDefaultApiVersionFromBaseUrl = (baseUrl) => {
|
|
1279
|
+
const match = String(baseUrl || "").trim().match(/\/(v\d+)\/?$/i);
|
|
1280
|
+
if (match?.[1]) {
|
|
1281
|
+
apiVersions.v1 = normalizeApiVersion(match[1]);
|
|
1282
|
+
}
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
});
|
|
1226
1286
|
function resolveParamsForRequest(url, method) {
|
|
1227
1287
|
const apiKey = resolveChatApiKey(url);
|
|
1228
1288
|
const httpMethod = (method || "get").toLowerCase();
|
|
@@ -1239,7 +1299,9 @@ var chatClientId, chatAccessToken, chatBaseUrl, chatSocketUrl, chatQueryParams,
|
|
|
1239
1299
|
var init_client = __esm({
|
|
1240
1300
|
"src/services/api/client.ts"() {
|
|
1241
1301
|
init_query_params();
|
|
1302
|
+
init_api_version();
|
|
1242
1303
|
init_query_params();
|
|
1304
|
+
init_api_version();
|
|
1243
1305
|
chatClientId = "";
|
|
1244
1306
|
chatAccessToken = "";
|
|
1245
1307
|
chatBaseUrl = "";
|
|
@@ -1257,6 +1319,7 @@ var init_client = __esm({
|
|
|
1257
1319
|
setChatBaseURL = (url) => {
|
|
1258
1320
|
chatBaseUrl = url.trim();
|
|
1259
1321
|
apiClient.defaults.baseURL = chatBaseUrl;
|
|
1322
|
+
syncDefaultApiVersionFromBaseUrl(chatBaseUrl);
|
|
1260
1323
|
};
|
|
1261
1324
|
getChatBaseUrl = () => chatBaseUrl;
|
|
1262
1325
|
setChatSocketUrl = (url) => {
|
|
@@ -1360,6 +1423,9 @@ var init_api_constants = __esm({
|
|
|
1360
1423
|
SEARCH_MESSAGES: "/message/search-messages",
|
|
1361
1424
|
SEARCH_MESSAGES_CONTEXT: (messageId2) => `/message/searched-message/context?messageId=${messageId2}`,
|
|
1362
1425
|
BLOCK_UNBLOCK_USER: "/user/block-unblock"
|
|
1426
|
+
},
|
|
1427
|
+
SETTINGS: {
|
|
1428
|
+
PERMISSIONS: "/settings/effective"
|
|
1363
1429
|
}
|
|
1364
1430
|
};
|
|
1365
1431
|
}
|
|
@@ -1396,13 +1462,11 @@ var init_auth_api = __esm({
|
|
|
1396
1462
|
});
|
|
1397
1463
|
|
|
1398
1464
|
// src/constants/chat.constants.ts
|
|
1399
|
-
var DEFAULT_MESSAGES_LIMIT, DEFAULT_CONVERSATIONS_LIMIT,
|
|
1465
|
+
var DEFAULT_MESSAGES_LIMIT, DEFAULT_CONVERSATIONS_LIMIT, MAX_ATTACHMENT_CAPTION_LENGTH, ATTACHMENT_FILENAME_TIMESTAMP_LENGTH;
|
|
1400
1466
|
var init_chat_constants = __esm({
|
|
1401
1467
|
"src/constants/chat.constants.ts"() {
|
|
1402
1468
|
DEFAULT_MESSAGES_LIMIT = 20;
|
|
1403
1469
|
DEFAULT_CONVERSATIONS_LIMIT = 20;
|
|
1404
|
-
DM_EDIT_WINDOW_MS = 5 * 60 * 1e3;
|
|
1405
|
-
GROUP_EDIT_WINDOW_MS = 10 * 60 * 1e3;
|
|
1406
1470
|
MAX_ATTACHMENT_CAPTION_LENGTH = 100;
|
|
1407
1471
|
ATTACHMENT_FILENAME_TIMESTAMP_LENGTH = 13;
|
|
1408
1472
|
}
|
|
@@ -1605,6 +1669,206 @@ var init_uploads_api = __esm({
|
|
|
1605
1669
|
}
|
|
1606
1670
|
});
|
|
1607
1671
|
|
|
1672
|
+
// src/types/settings.types.ts
|
|
1673
|
+
var DEFAULT_EFFECTIVE_SETTINGS, ADMIN_PERMISSION_DENIED_MESSAGE, CALLS_NOT_CONFIGURED_MESSAGE;
|
|
1674
|
+
var init_settings_types = __esm({
|
|
1675
|
+
"src/types/settings.types.ts"() {
|
|
1676
|
+
DEFAULT_EFFECTIVE_SETTINGS = {
|
|
1677
|
+
pushNotificationEnabled: true,
|
|
1678
|
+
videoCallEnabled: true,
|
|
1679
|
+
audioCallEnabled: true,
|
|
1680
|
+
blockUsersEnabled: true,
|
|
1681
|
+
calls: {
|
|
1682
|
+
enabled: true,
|
|
1683
|
+
configured: true
|
|
1684
|
+
},
|
|
1685
|
+
groupPolicy: {
|
|
1686
|
+
defaults: {
|
|
1687
|
+
onlyAdminCanSendMessage: false,
|
|
1688
|
+
onlyAdminCanEditInfo: false,
|
|
1689
|
+
senderCanEditMessage: true,
|
|
1690
|
+
allowMemberAdd: true,
|
|
1691
|
+
allowMemberRemove: false,
|
|
1692
|
+
moderationEnabled: false
|
|
1693
|
+
},
|
|
1694
|
+
locked: []
|
|
1695
|
+
},
|
|
1696
|
+
messageTimers: {
|
|
1697
|
+
dmEditMinutes: 5,
|
|
1698
|
+
dmDeleteMinutes: 5,
|
|
1699
|
+
groupEditMinutes: 10,
|
|
1700
|
+
groupDeleteMinutes: 10
|
|
1701
|
+
},
|
|
1702
|
+
attachments: {
|
|
1703
|
+
enabled: true,
|
|
1704
|
+
maxFileSizeMB: 10,
|
|
1705
|
+
allowedMimeTypes: ["image/*", "video/*", "audio/*", "application/pdf"],
|
|
1706
|
+
maxAttachmentsPerMessage: 10
|
|
1707
|
+
},
|
|
1708
|
+
maxAdminsPerGroup: 5,
|
|
1709
|
+
maxParticipantsPerGroup: 100,
|
|
1710
|
+
maxPinnedMessagesPerConversation: 10,
|
|
1711
|
+
groupCreationEnabled: true
|
|
1712
|
+
};
|
|
1713
|
+
ADMIN_PERMISSION_DENIED_MESSAGE = "This feature is disabled by your administrator.";
|
|
1714
|
+
CALLS_NOT_CONFIGURED_MESSAGE = "Calls are not configured. Please contact your administrator.";
|
|
1715
|
+
}
|
|
1716
|
+
});
|
|
1717
|
+
|
|
1718
|
+
// src/services/api/settings.api.ts
|
|
1719
|
+
function asBoolean(value, fallback) {
|
|
1720
|
+
return typeof value === "boolean" ? value : fallback;
|
|
1721
|
+
}
|
|
1722
|
+
function asPositiveNumber(value, fallback) {
|
|
1723
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : fallback;
|
|
1724
|
+
}
|
|
1725
|
+
function asStringArray(value, fallback) {
|
|
1726
|
+
if (!Array.isArray(value)) return fallback;
|
|
1727
|
+
const next = value.filter((item) => typeof item === "string");
|
|
1728
|
+
return next.length > 0 ? next : fallback;
|
|
1729
|
+
}
|
|
1730
|
+
function normalizeGroupPermissions(value, fallback) {
|
|
1731
|
+
if (!value || typeof value !== "object") return { ...fallback };
|
|
1732
|
+
const raw = value;
|
|
1733
|
+
return {
|
|
1734
|
+
onlyAdminCanSendMessage: asBoolean(
|
|
1735
|
+
raw.onlyAdminCanSendMessage,
|
|
1736
|
+
fallback.onlyAdminCanSendMessage
|
|
1737
|
+
),
|
|
1738
|
+
onlyAdminCanEditInfo: asBoolean(
|
|
1739
|
+
raw.onlyAdminCanEditInfo,
|
|
1740
|
+
fallback.onlyAdminCanEditInfo
|
|
1741
|
+
),
|
|
1742
|
+
senderCanEditMessage: asBoolean(
|
|
1743
|
+
raw.senderCanEditMessage,
|
|
1744
|
+
fallback.senderCanEditMessage
|
|
1745
|
+
),
|
|
1746
|
+
allowMemberAdd: asBoolean(raw.allowMemberAdd, fallback.allowMemberAdd),
|
|
1747
|
+
allowMemberRemove: asBoolean(
|
|
1748
|
+
raw.allowMemberRemove,
|
|
1749
|
+
fallback.allowMemberRemove
|
|
1750
|
+
),
|
|
1751
|
+
moderationEnabled: asBoolean(
|
|
1752
|
+
raw.moderationEnabled,
|
|
1753
|
+
fallback.moderationEnabled
|
|
1754
|
+
)
|
|
1755
|
+
};
|
|
1756
|
+
}
|
|
1757
|
+
function normalizeCalls(value, fallback) {
|
|
1758
|
+
if (!value || typeof value !== "object") return { ...fallback };
|
|
1759
|
+
const raw = value;
|
|
1760
|
+
return {
|
|
1761
|
+
enabled: asBoolean(raw.enabled, fallback.enabled),
|
|
1762
|
+
configured: asBoolean(raw.configured, fallback.configured)
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1765
|
+
function normalizeGroupPolicy(value, fallback) {
|
|
1766
|
+
if (!value || typeof value !== "object") {
|
|
1767
|
+
return {
|
|
1768
|
+
defaults: { ...fallback.defaults },
|
|
1769
|
+
locked: [...fallback.locked]
|
|
1770
|
+
};
|
|
1771
|
+
}
|
|
1772
|
+
const raw = value;
|
|
1773
|
+
return {
|
|
1774
|
+
defaults: normalizeGroupPermissions(raw.defaults, fallback.defaults),
|
|
1775
|
+
locked: asStringArray(raw.locked, fallback.locked)
|
|
1776
|
+
};
|
|
1777
|
+
}
|
|
1778
|
+
function normalizeMessageTimers(value, fallback) {
|
|
1779
|
+
if (!value || typeof value !== "object") return { ...fallback };
|
|
1780
|
+
const raw = value;
|
|
1781
|
+
return {
|
|
1782
|
+
dmEditMinutes: asPositiveNumber(raw.dmEditMinutes, fallback.dmEditMinutes),
|
|
1783
|
+
dmDeleteMinutes: asPositiveNumber(
|
|
1784
|
+
raw.dmDeleteMinutes,
|
|
1785
|
+
fallback.dmDeleteMinutes
|
|
1786
|
+
),
|
|
1787
|
+
groupEditMinutes: asPositiveNumber(
|
|
1788
|
+
raw.groupEditMinutes,
|
|
1789
|
+
fallback.groupEditMinutes
|
|
1790
|
+
),
|
|
1791
|
+
groupDeleteMinutes: asPositiveNumber(
|
|
1792
|
+
raw.groupDeleteMinutes,
|
|
1793
|
+
fallback.groupDeleteMinutes
|
|
1794
|
+
)
|
|
1795
|
+
};
|
|
1796
|
+
}
|
|
1797
|
+
function normalizeAttachments(value, fallback) {
|
|
1798
|
+
if (!value || typeof value !== "object") return { ...fallback };
|
|
1799
|
+
const raw = value;
|
|
1800
|
+
return {
|
|
1801
|
+
enabled: asBoolean(raw.enabled, fallback.enabled),
|
|
1802
|
+
maxFileSizeMB: asPositiveNumber(raw.maxFileSizeMB, fallback.maxFileSizeMB),
|
|
1803
|
+
allowedMimeTypes: asStringArray(
|
|
1804
|
+
raw.allowedMimeTypes,
|
|
1805
|
+
fallback.allowedMimeTypes
|
|
1806
|
+
),
|
|
1807
|
+
maxAttachmentsPerMessage: asPositiveNumber(
|
|
1808
|
+
raw.maxAttachmentsPerMessage,
|
|
1809
|
+
fallback.maxAttachmentsPerMessage
|
|
1810
|
+
)
|
|
1811
|
+
};
|
|
1812
|
+
}
|
|
1813
|
+
function normalizeEffectiveSettings(raw) {
|
|
1814
|
+
const payload = raw && typeof raw === "object" ? raw.data ?? raw : null;
|
|
1815
|
+
const source = payload && typeof payload === "object" ? payload : {};
|
|
1816
|
+
const defaults = DEFAULT_EFFECTIVE_SETTINGS;
|
|
1817
|
+
return {
|
|
1818
|
+
pushNotificationEnabled: asBoolean(
|
|
1819
|
+
source.pushNotificationEnabled,
|
|
1820
|
+
defaults.pushNotificationEnabled
|
|
1821
|
+
),
|
|
1822
|
+
videoCallEnabled: asBoolean(
|
|
1823
|
+
source.videoCallEnabled,
|
|
1824
|
+
defaults.videoCallEnabled
|
|
1825
|
+
),
|
|
1826
|
+
audioCallEnabled: asBoolean(
|
|
1827
|
+
source.audioCallEnabled,
|
|
1828
|
+
defaults.audioCallEnabled
|
|
1829
|
+
),
|
|
1830
|
+
blockUsersEnabled: asBoolean(
|
|
1831
|
+
source.blockUsersEnabled,
|
|
1832
|
+
defaults.blockUsersEnabled
|
|
1833
|
+
),
|
|
1834
|
+
calls: normalizeCalls(source.calls, defaults.calls),
|
|
1835
|
+
groupPolicy: normalizeGroupPolicy(source.groupPolicy, defaults.groupPolicy),
|
|
1836
|
+
messageTimers: normalizeMessageTimers(
|
|
1837
|
+
source.messageTimers,
|
|
1838
|
+
defaults.messageTimers
|
|
1839
|
+
),
|
|
1840
|
+
attachments: normalizeAttachments(source.attachments, defaults.attachments),
|
|
1841
|
+
maxAdminsPerGroup: asPositiveNumber(
|
|
1842
|
+
source.maxAdminsPerGroup,
|
|
1843
|
+
defaults.maxAdminsPerGroup
|
|
1844
|
+
),
|
|
1845
|
+
maxParticipantsPerGroup: asPositiveNumber(
|
|
1846
|
+
source.maxParticipantsPerGroup,
|
|
1847
|
+
defaults.maxParticipantsPerGroup
|
|
1848
|
+
),
|
|
1849
|
+
maxPinnedMessagesPerConversation: asPositiveNumber(
|
|
1850
|
+
source.maxPinnedMessagesPerConversation,
|
|
1851
|
+
defaults.maxPinnedMessagesPerConversation
|
|
1852
|
+
),
|
|
1853
|
+
groupCreationEnabled: asBoolean(
|
|
1854
|
+
source.groupCreationEnabled,
|
|
1855
|
+
defaults.groupCreationEnabled
|
|
1856
|
+
)
|
|
1857
|
+
};
|
|
1858
|
+
}
|
|
1859
|
+
var fetchEffectiveSettings;
|
|
1860
|
+
var init_settings_api = __esm({
|
|
1861
|
+
"src/services/api/settings.api.ts"() {
|
|
1862
|
+
init_api_constants();
|
|
1863
|
+
init_client();
|
|
1864
|
+
init_settings_types();
|
|
1865
|
+
fetchEffectiveSettings = async () => {
|
|
1866
|
+
const response = await apiClient.get(API_ENDPOINTS.SETTINGS.PERMISSIONS);
|
|
1867
|
+
return normalizeEffectiveSettings(response.data);
|
|
1868
|
+
};
|
|
1869
|
+
}
|
|
1870
|
+
});
|
|
1871
|
+
|
|
1608
1872
|
// src/services/api/index.ts
|
|
1609
1873
|
var init_api = __esm({
|
|
1610
1874
|
"src/services/api/index.ts"() {
|
|
@@ -1613,6 +1877,7 @@ var init_api = __esm({
|
|
|
1613
1877
|
init_messages_api();
|
|
1614
1878
|
init_groups_api();
|
|
1615
1879
|
init_uploads_api();
|
|
1880
|
+
init_settings_api();
|
|
1616
1881
|
}
|
|
1617
1882
|
});
|
|
1618
1883
|
|
|
@@ -3722,7 +3987,7 @@ function resolveApiUrl(apiUrl) {
|
|
|
3722
3987
|
function resolveSocketUrl(socketUrl, apiUrl) {
|
|
3723
3988
|
const explicit = (socketUrl ?? "").trim();
|
|
3724
3989
|
if (explicit) return explicit;
|
|
3725
|
-
return resolveApiUrl(apiUrl).replace(/\/api\/
|
|
3990
|
+
return resolveApiUrl(apiUrl).replace(/\/api\/v\d+\/?$/i, "");
|
|
3726
3991
|
}
|
|
3727
3992
|
|
|
3728
3993
|
// src/hooks/chat-sync/useChatSync.ts
|
|
@@ -4444,6 +4709,143 @@ var useChatCustomizationOptional = () => {
|
|
|
4444
4709
|
};
|
|
4445
4710
|
var useChatFeatures = () => useChatCustomization().features;
|
|
4446
4711
|
var useChatFeaturesOptional = () => useChatCustomizationOptional().features;
|
|
4712
|
+
|
|
4713
|
+
// src/context/ChatEffectiveSettingsContext.tsx
|
|
4714
|
+
init_settings_api();
|
|
4715
|
+
init_settings_types();
|
|
4716
|
+
var ChatEffectiveSettingsContext = createContext(null);
|
|
4717
|
+
function buildCallGate(settings, featureEnabled) {
|
|
4718
|
+
if (!settings.calls.configured) {
|
|
4719
|
+
return {
|
|
4720
|
+
visible: true,
|
|
4721
|
+
enabled: false,
|
|
4722
|
+
disabledReason: CALLS_NOT_CONFIGURED_MESSAGE
|
|
4723
|
+
};
|
|
4724
|
+
}
|
|
4725
|
+
if (!settings.calls.enabled) {
|
|
4726
|
+
return {
|
|
4727
|
+
visible: true,
|
|
4728
|
+
enabled: false,
|
|
4729
|
+
disabledReason: ADMIN_PERMISSION_DENIED_MESSAGE
|
|
4730
|
+
};
|
|
4731
|
+
}
|
|
4732
|
+
if (!featureEnabled) {
|
|
4733
|
+
return {
|
|
4734
|
+
visible: true,
|
|
4735
|
+
enabled: false,
|
|
4736
|
+
disabledReason: ADMIN_PERMISSION_DENIED_MESSAGE
|
|
4737
|
+
};
|
|
4738
|
+
}
|
|
4739
|
+
return { visible: true, enabled: true, disabledReason: null };
|
|
4740
|
+
}
|
|
4741
|
+
function ChatEffectiveSettingsProvider({
|
|
4742
|
+
children,
|
|
4743
|
+
enabled = true
|
|
4744
|
+
}) {
|
|
4745
|
+
const [settings, setSettings] = useState(
|
|
4746
|
+
DEFAULT_EFFECTIVE_SETTINGS
|
|
4747
|
+
);
|
|
4748
|
+
const [loading, setLoading] = useState(true);
|
|
4749
|
+
const [error, setError] = useState(null);
|
|
4750
|
+
const refresh = useCallback(async () => {
|
|
4751
|
+
if (!enabled) {
|
|
4752
|
+
setLoading(false);
|
|
4753
|
+
return;
|
|
4754
|
+
}
|
|
4755
|
+
setLoading(true);
|
|
4756
|
+
try {
|
|
4757
|
+
const next = await fetchEffectiveSettings();
|
|
4758
|
+
setSettings(next);
|
|
4759
|
+
setError(null);
|
|
4760
|
+
} catch (err) {
|
|
4761
|
+
console.error("Failed to fetch effective settings:", err);
|
|
4762
|
+
setError(
|
|
4763
|
+
err instanceof Error ? err.message : "Could not load chat permissions"
|
|
4764
|
+
);
|
|
4765
|
+
setSettings(DEFAULT_EFFECTIVE_SETTINGS);
|
|
4766
|
+
} finally {
|
|
4767
|
+
setLoading(false);
|
|
4768
|
+
}
|
|
4769
|
+
}, [enabled]);
|
|
4770
|
+
useEffect(() => {
|
|
4771
|
+
void refresh();
|
|
4772
|
+
}, [refresh]);
|
|
4773
|
+
const value = useMemo(() => {
|
|
4774
|
+
const isGroupPermissionLocked = (key) => settings.groupPolicy.locked.includes(key);
|
|
4775
|
+
return {
|
|
4776
|
+
settings,
|
|
4777
|
+
loading,
|
|
4778
|
+
error,
|
|
4779
|
+
refresh,
|
|
4780
|
+
isGroupPermissionLocked,
|
|
4781
|
+
getAudioCallGate: () => buildCallGate(settings, settings.audioCallEnabled),
|
|
4782
|
+
getVideoCallGate: () => buildCallGate(settings, settings.videoCallEnabled),
|
|
4783
|
+
getPushNotificationGate: () => ({
|
|
4784
|
+
visible: true,
|
|
4785
|
+
enabled: settings.pushNotificationEnabled,
|
|
4786
|
+
disabledReason: settings.pushNotificationEnabled ? null : ADMIN_PERMISSION_DENIED_MESSAGE
|
|
4787
|
+
}),
|
|
4788
|
+
getBlockUsersGate: () => ({
|
|
4789
|
+
visible: true,
|
|
4790
|
+
enabled: settings.blockUsersEnabled,
|
|
4791
|
+
disabledReason: settings.blockUsersEnabled ? null : ADMIN_PERMISSION_DENIED_MESSAGE
|
|
4792
|
+
}),
|
|
4793
|
+
getAttachmentsGate: () => ({
|
|
4794
|
+
visible: true,
|
|
4795
|
+
enabled: settings.attachments.enabled,
|
|
4796
|
+
disabledReason: settings.attachments.enabled ? null : ADMIN_PERMISSION_DENIED_MESSAGE
|
|
4797
|
+
}),
|
|
4798
|
+
getGroupCreationGate: () => ({
|
|
4799
|
+
visible: true,
|
|
4800
|
+
enabled: settings.groupCreationEnabled,
|
|
4801
|
+
disabledReason: settings.groupCreationEnabled ? null : ADMIN_PERMISSION_DENIED_MESSAGE
|
|
4802
|
+
})
|
|
4803
|
+
};
|
|
4804
|
+
}, [settings, loading, error, refresh]);
|
|
4805
|
+
return /* @__PURE__ */ jsx(ChatEffectiveSettingsContext.Provider, { value, children });
|
|
4806
|
+
}
|
|
4807
|
+
function useEffectiveSettings() {
|
|
4808
|
+
const ctx = useContext(ChatEffectiveSettingsContext);
|
|
4809
|
+
if (!ctx) {
|
|
4810
|
+
throw new Error(
|
|
4811
|
+
"useEffectiveSettings must be used within ChatEffectiveSettingsProvider"
|
|
4812
|
+
);
|
|
4813
|
+
}
|
|
4814
|
+
return ctx;
|
|
4815
|
+
}
|
|
4816
|
+
function useEffectiveSettingsOptional() {
|
|
4817
|
+
const ctx = useContext(ChatEffectiveSettingsContext);
|
|
4818
|
+
if (ctx) return ctx;
|
|
4819
|
+
return {
|
|
4820
|
+
settings: DEFAULT_EFFECTIVE_SETTINGS,
|
|
4821
|
+
loading: false,
|
|
4822
|
+
error: null,
|
|
4823
|
+
refresh: async () => void 0,
|
|
4824
|
+
isGroupPermissionLocked: () => false,
|
|
4825
|
+
getAudioCallGate: () => buildCallGate(DEFAULT_EFFECTIVE_SETTINGS, true),
|
|
4826
|
+
getVideoCallGate: () => buildCallGate(DEFAULT_EFFECTIVE_SETTINGS, true),
|
|
4827
|
+
getPushNotificationGate: () => ({
|
|
4828
|
+
visible: true,
|
|
4829
|
+
enabled: true,
|
|
4830
|
+
disabledReason: null
|
|
4831
|
+
}),
|
|
4832
|
+
getBlockUsersGate: () => ({
|
|
4833
|
+
visible: true,
|
|
4834
|
+
enabled: true,
|
|
4835
|
+
disabledReason: null
|
|
4836
|
+
}),
|
|
4837
|
+
getAttachmentsGate: () => ({
|
|
4838
|
+
visible: true,
|
|
4839
|
+
enabled: true,
|
|
4840
|
+
disabledReason: null
|
|
4841
|
+
}),
|
|
4842
|
+
getGroupCreationGate: () => ({
|
|
4843
|
+
visible: true,
|
|
4844
|
+
enabled: true,
|
|
4845
|
+
disabledReason: null
|
|
4846
|
+
})
|
|
4847
|
+
};
|
|
4848
|
+
}
|
|
4447
4849
|
var ChatContext = createContext(void 0);
|
|
4448
4850
|
var useChatContext = () => {
|
|
4449
4851
|
const context = useContext(ChatContext);
|
|
@@ -4469,6 +4871,7 @@ var Chat = ({
|
|
|
4469
4871
|
queryParams,
|
|
4470
4872
|
queryParamApis,
|
|
4471
4873
|
queryParamsByApi,
|
|
4874
|
+
apiVersions: apiVersions2,
|
|
4472
4875
|
channelsData,
|
|
4473
4876
|
messagesData,
|
|
4474
4877
|
onMessageReceived,
|
|
@@ -4482,7 +4885,7 @@ var Chat = ({
|
|
|
4482
4885
|
const status = useStore((s) => s.status);
|
|
4483
4886
|
const error = useStore((s) => s.error);
|
|
4484
4887
|
useChatSync();
|
|
4485
|
-
|
|
4888
|
+
React3__default.useEffect(() => {
|
|
4486
4889
|
const clientId = client?.id;
|
|
4487
4890
|
const initializeChat = async () => {
|
|
4488
4891
|
if (!clientId || !loggedUserDetails) return;
|
|
@@ -4494,6 +4897,7 @@ var Chat = ({
|
|
|
4494
4897
|
const resolvedApiUrl = resolveApiUrl(apiUrl);
|
|
4495
4898
|
const resolvedSocketUrl = resolveSocketUrl(socketUrl, resolvedApiUrl);
|
|
4496
4899
|
if (resolvedApiUrl) setChatBaseURL(resolvedApiUrl);
|
|
4900
|
+
setChatApiVersions(apiVersions2);
|
|
4497
4901
|
if (resolvedSocketUrl) setChatSocketUrl(resolvedSocketUrl);
|
|
4498
4902
|
let currentToken = accessToken || "";
|
|
4499
4903
|
let sessionUser = resolveUserFromAccessToken(currentToken, loggedUserDetails);
|
|
@@ -4571,28 +4975,28 @@ var Chat = ({
|
|
|
4571
4975
|
queryParamApis: queryParamApis ?? ["get"],
|
|
4572
4976
|
queryParamsByApi: queryParamsByApi ?? {}
|
|
4573
4977
|
});
|
|
4574
|
-
|
|
4978
|
+
React3__default.useEffect(() => {
|
|
4575
4979
|
setChatQueryParams(queryParams);
|
|
4576
4980
|
setChatQueryParamApis(queryParamApis);
|
|
4577
4981
|
setChatQueryParamsByApi(queryParamsByApi);
|
|
4578
4982
|
}, [queryConfigKey]);
|
|
4579
|
-
|
|
4983
|
+
React3__default.useEffect(() => {
|
|
4580
4984
|
if (lastDM && onMessageReceived) {
|
|
4581
4985
|
onMessageReceived(lastDM);
|
|
4582
4986
|
}
|
|
4583
4987
|
}, [lastDM, onMessageReceived]);
|
|
4584
|
-
|
|
4988
|
+
React3__default.useEffect(() => {
|
|
4585
4989
|
if (status === "connected" && onSocketConnected) {
|
|
4586
4990
|
const socketId = useStore.getState().socketId;
|
|
4587
4991
|
if (socketId) onSocketConnected(socketId);
|
|
4588
4992
|
}
|
|
4589
4993
|
}, [status, onSocketConnected]);
|
|
4590
|
-
|
|
4994
|
+
React3__default.useEffect(() => {
|
|
4591
4995
|
if (status === "error" && error && onSocketError) {
|
|
4592
4996
|
onSocketError(error);
|
|
4593
4997
|
}
|
|
4594
4998
|
}, [status, error, onSocketError]);
|
|
4595
|
-
const contextValue =
|
|
4999
|
+
const contextValue = React3__default.useMemo(
|
|
4596
5000
|
() => ({
|
|
4597
5001
|
onSendMessage,
|
|
4598
5002
|
client,
|
|
@@ -4612,7 +5016,7 @@ var Chat = ({
|
|
|
4612
5016
|
messagesData
|
|
4613
5017
|
]
|
|
4614
5018
|
);
|
|
4615
|
-
const customization =
|
|
5019
|
+
const customization = React3__default.useMemo(
|
|
4616
5020
|
() => ({
|
|
4617
5021
|
components: uiConfig.components,
|
|
4618
5022
|
classNames: uiConfig.classNames,
|
|
@@ -4620,7 +5024,7 @@ var Chat = ({
|
|
|
4620
5024
|
}),
|
|
4621
5025
|
[uiConfig.components, uiConfig.classNames, uiConfig.features]
|
|
4622
5026
|
);
|
|
4623
|
-
return /* @__PURE__ */ jsx(ChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(ChatCustomizationProvider, { customization, children: /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx("div", { className: "chat-container-root flex h-full min-h-0 w-full flex-1 flex-col overflow-hidden", children: isSessionReady ? children : /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center text-gray-400 font-bold", children: "Initializing session..." }) }) }) }) });
|
|
5027
|
+
return /* @__PURE__ */ jsx(ChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(ChatCustomizationProvider, { customization, children: /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx("div", { className: "chat-container-root flex h-full min-h-0 w-full flex-1 flex-col overflow-hidden", children: isSessionReady ? /* @__PURE__ */ jsx(ChatEffectiveSettingsProvider, { enabled: true, children }) : /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center text-gray-400 font-bold", children: "Initializing session..." }) }) }) }) });
|
|
4624
5028
|
};
|
|
4625
5029
|
|
|
4626
5030
|
// src/hooks/useChatController.ts
|
|
@@ -5611,6 +6015,18 @@ function formatMemberName(name) {
|
|
|
5611
6015
|
function formatLoggedUserName(name) {
|
|
5612
6016
|
return name ? name.charAt(0).toUpperCase() + name.slice(1) : "User";
|
|
5613
6017
|
}
|
|
6018
|
+
|
|
6019
|
+
// src/chat/sidebar/build-logged-user-profile.ts
|
|
6020
|
+
var buildLoggedUserProfile = (loggedUserDetails) => ({
|
|
6021
|
+
_id: loggedUserDetails?._id || "1",
|
|
6022
|
+
name: formatLoggedUserName(loggedUserDetails?.name),
|
|
6023
|
+
email: loggedUserDetails?.email || "user@example.com",
|
|
6024
|
+
role: loggedUserDetails?.role || "user",
|
|
6025
|
+
isActive: loggedUserDetails?.isActive ?? true,
|
|
6026
|
+
createdAt: loggedUserDetails?.createdAt ? new Date(loggedUserDetails.createdAt) : /* @__PURE__ */ new Date(),
|
|
6027
|
+
updatedAt: loggedUserDetails?.updatedAt ? new Date(loggedUserDetails.updatedAt) : /* @__PURE__ */ new Date(),
|
|
6028
|
+
image: loggedUserDetails?.image || void 0
|
|
6029
|
+
});
|
|
5614
6030
|
function Dialog({
|
|
5615
6031
|
...props
|
|
5616
6032
|
}) {
|
|
@@ -6011,6 +6427,8 @@ function useCreateChatDialog({
|
|
|
6011
6427
|
const fetchAllUsers = useStore((storeState) => storeState.fetchAllUsers);
|
|
6012
6428
|
const accessToken = useStore((storeState) => storeState.accessToken);
|
|
6013
6429
|
const fetchConversations2 = useStore((storeState) => storeState.fetchConversations);
|
|
6430
|
+
const { settings } = useEffectiveSettingsOptional();
|
|
6431
|
+
const maxParticipants = settings.maxParticipantsPerGroup;
|
|
6014
6432
|
const fileInputRef = useRef(null);
|
|
6015
6433
|
useEffect(() => {
|
|
6016
6434
|
if (accessToken) {
|
|
@@ -6024,9 +6442,18 @@ function useCreateChatDialog({
|
|
|
6024
6442
|
setState((prev) => {
|
|
6025
6443
|
const memberId = String(member._id);
|
|
6026
6444
|
const exists = prev.selectedMembers.some((m) => String(m._id) === memberId);
|
|
6445
|
+
if (exists) {
|
|
6446
|
+
return {
|
|
6447
|
+
...prev,
|
|
6448
|
+
selectedMembers: prev.selectedMembers.filter((m) => String(m._id) !== memberId)
|
|
6449
|
+
};
|
|
6450
|
+
}
|
|
6451
|
+
if (prev.selectedMembers.length + 1 >= maxParticipants) {
|
|
6452
|
+
return prev;
|
|
6453
|
+
}
|
|
6027
6454
|
return {
|
|
6028
6455
|
...prev,
|
|
6029
|
-
selectedMembers:
|
|
6456
|
+
selectedMembers: [...prev.selectedMembers, member]
|
|
6030
6457
|
};
|
|
6031
6458
|
});
|
|
6032
6459
|
};
|
|
@@ -6410,8 +6837,25 @@ function GroupCreateTab({
|
|
|
6410
6837
|
) })
|
|
6411
6838
|
] });
|
|
6412
6839
|
}
|
|
6840
|
+
function AdminPermissionTooltip({
|
|
6841
|
+
disabled,
|
|
6842
|
+
message,
|
|
6843
|
+
side = "top",
|
|
6844
|
+
className,
|
|
6845
|
+
children
|
|
6846
|
+
}) {
|
|
6847
|
+
if (!disabled || !message) {
|
|
6848
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
6849
|
+
}
|
|
6850
|
+
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
6851
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: cn("inline-flex", className), children }) }),
|
|
6852
|
+
/* @__PURE__ */ jsx(TooltipContent, { side, className: "max-w-[240px] text-xs", children: message })
|
|
6853
|
+
] });
|
|
6854
|
+
}
|
|
6413
6855
|
var CreateChatDialog = (props) => {
|
|
6414
6856
|
const { isCreateModalOpen = false, setIsCreateModalOpen } = props;
|
|
6857
|
+
const { getGroupCreationGate } = useEffectiveSettingsOptional();
|
|
6858
|
+
const groupCreationGate = getGroupCreationGate();
|
|
6415
6859
|
const {
|
|
6416
6860
|
state,
|
|
6417
6861
|
updateState,
|
|
@@ -6465,24 +6909,39 @@ var CreateChatDialog = (props) => {
|
|
|
6465
6909
|
) })
|
|
6466
6910
|
] }),
|
|
6467
6911
|
/* @__PURE__ */ jsx("div", { className: "grid shrink-0 grid-cols-2 gap-2 px-5", children: [
|
|
6468
|
-
{ id: "dm", label: "Message", icon: MessageCircle },
|
|
6469
|
-
{ id: "group", label: "New group", icon: Users }
|
|
6470
|
-
].map(({ id, label, icon: Icon }) => /* @__PURE__ */ jsxs(
|
|
6471
|
-
"button",
|
|
6912
|
+
{ id: "dm", label: "Message", icon: MessageCircle, disabled: false, reason: null },
|
|
6472
6913
|
{
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6914
|
+
id: "group",
|
|
6915
|
+
label: "New group",
|
|
6916
|
+
icon: Users,
|
|
6917
|
+
disabled: !groupCreationGate.enabled,
|
|
6918
|
+
reason: groupCreationGate.disabledReason
|
|
6919
|
+
}
|
|
6920
|
+
].map(({ id, label, icon: Icon, disabled, reason }) => {
|
|
6921
|
+
const tabButton = /* @__PURE__ */ jsxs(
|
|
6922
|
+
"button",
|
|
6923
|
+
{
|
|
6924
|
+
type: "button",
|
|
6925
|
+
disabled,
|
|
6926
|
+
onClick: () => {
|
|
6927
|
+
if (disabled) return;
|
|
6928
|
+
updateState({ activeTab: id });
|
|
6929
|
+
},
|
|
6930
|
+
className: cn(
|
|
6931
|
+
"flex w-full items-center justify-center gap-2 rounded-full border py-2 text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-40",
|
|
6932
|
+
state.activeTab === id ? "border-(--chat-theme-20) bg-(--chat-theme-5) text-(--chat-theme)" : "border-(--chat-border) text-(--chat-muted) hover:border-(--chat-theme-20) hover:text-(--chat-text)"
|
|
6933
|
+
),
|
|
6934
|
+
children: [
|
|
6935
|
+
/* @__PURE__ */ jsx(Icon, { className: "size-4" }),
|
|
6936
|
+
label
|
|
6937
|
+
]
|
|
6938
|
+
}
|
|
6939
|
+
);
|
|
6940
|
+
if (!disabled || !reason) {
|
|
6941
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: tabButton }, id);
|
|
6942
|
+
}
|
|
6943
|
+
return /* @__PURE__ */ jsx(AdminPermissionTooltip, { disabled: true, message: reason, children: tabButton }, id);
|
|
6944
|
+
}) }),
|
|
6486
6945
|
state.activeTab === "dm" && /* @__PURE__ */ jsx(
|
|
6487
6946
|
DmContactsTab,
|
|
6488
6947
|
{
|
|
@@ -6493,7 +6952,7 @@ var CreateChatDialog = (props) => {
|
|
|
6493
6952
|
onStartDM: handleStartDM
|
|
6494
6953
|
}
|
|
6495
6954
|
),
|
|
6496
|
-
state.activeTab === "group" && /* @__PURE__ */ jsx(
|
|
6955
|
+
state.activeTab === "group" && groupCreationGate.enabled && /* @__PURE__ */ jsx(
|
|
6497
6956
|
GroupCreateTab,
|
|
6498
6957
|
{
|
|
6499
6958
|
state,
|
|
@@ -6545,6 +7004,7 @@ function Switch({
|
|
|
6545
7004
|
|
|
6546
7005
|
// src/notifications/push.service.ts
|
|
6547
7006
|
init_client();
|
|
7007
|
+
init_api_version();
|
|
6548
7008
|
var PUSH_TOKEN_STORAGE_KEY = "realtimex-push-token";
|
|
6549
7009
|
var SERVICE_WORKER_PATH = "/firebase-messaging-sw.js";
|
|
6550
7010
|
var PUSH_CHANGED_EVENT = "realtimex:push-changed";
|
|
@@ -6556,33 +7016,33 @@ var emitPushChanged = (enabled) => {
|
|
|
6556
7016
|
} catch {
|
|
6557
7017
|
}
|
|
6558
7018
|
};
|
|
6559
|
-
var
|
|
7019
|
+
var pushApiUrl = (path) => buildVersionedApiUrl(path, { service: "v2" });
|
|
6560
7020
|
var apiGetPushConfig = async () => {
|
|
6561
|
-
const { data } = await apiClient.get(
|
|
7021
|
+
const { data } = await apiClient.get(pushApiUrl("/notifications/push/config"));
|
|
6562
7022
|
return data?.data;
|
|
6563
7023
|
};
|
|
6564
7024
|
var apiRegisterPushToken = async (token, deviceLabel) => {
|
|
6565
|
-
const { data } = await apiClient.post(
|
|
7025
|
+
const { data } = await apiClient.post(pushApiUrl("/notifications/push/token"), {
|
|
6566
7026
|
token,
|
|
6567
7027
|
deviceLabel
|
|
6568
7028
|
});
|
|
6569
7029
|
return data?.data;
|
|
6570
7030
|
};
|
|
6571
7031
|
var apiRemovePushToken = async (token) => {
|
|
6572
|
-
const { data } = await apiClient.delete(
|
|
7032
|
+
const { data } = await apiClient.delete(pushApiUrl("/notifications/push/token"), {
|
|
6573
7033
|
data: { token }
|
|
6574
7034
|
});
|
|
6575
7035
|
return data;
|
|
6576
7036
|
};
|
|
6577
7037
|
var apiGetPushPreference = async () => {
|
|
6578
7038
|
const { data } = await apiClient.get(
|
|
6579
|
-
|
|
7039
|
+
pushApiUrl("/notifications/push/preference")
|
|
6580
7040
|
);
|
|
6581
7041
|
return data?.data;
|
|
6582
7042
|
};
|
|
6583
7043
|
var apiUpdatePushPreference = async (enabled) => {
|
|
6584
7044
|
const { data } = await apiClient.patch(
|
|
6585
|
-
|
|
7045
|
+
pushApiUrl("/notifications/push/preference"),
|
|
6586
7046
|
{ enabled }
|
|
6587
7047
|
);
|
|
6588
7048
|
return data?.data;
|
|
@@ -6777,13 +7237,15 @@ var usePushNotifications = () => {
|
|
|
6777
7237
|
}, [refresh]);
|
|
6778
7238
|
const setUserEnabled = useCallback(
|
|
6779
7239
|
async (enabled) => {
|
|
6780
|
-
setState((prev) => ({ ...prev,
|
|
7240
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
6781
7241
|
try {
|
|
6782
7242
|
await apiUpdatePushPreference(enabled);
|
|
7243
|
+
setState((prev) => ({ ...prev, userEnabled: enabled, loading: false }));
|
|
6783
7244
|
} catch (error) {
|
|
6784
7245
|
setState((prev) => ({
|
|
6785
7246
|
...prev,
|
|
6786
7247
|
userEnabled: !enabled,
|
|
7248
|
+
loading: false,
|
|
6787
7249
|
error: error instanceof Error ? error.message : "Could not update push preference"
|
|
6788
7250
|
}));
|
|
6789
7251
|
}
|
|
@@ -6795,95 +7257,229 @@ var usePushNotifications = () => {
|
|
|
6795
7257
|
var PushNotificationToggle = ({
|
|
6796
7258
|
className,
|
|
6797
7259
|
label = "Push notifications",
|
|
6798
|
-
description = "Get notified about new messages on this device"
|
|
7260
|
+
description = "Get notified about new messages on this device",
|
|
7261
|
+
children
|
|
6799
7262
|
}) => {
|
|
6800
7263
|
const push = usePushNotifications();
|
|
6801
|
-
|
|
7264
|
+
const { getPushNotificationGate } = useEffectiveSettingsOptional();
|
|
7265
|
+
const adminGate = getPushNotificationGate();
|
|
7266
|
+
const [isToggling, setIsToggling] = useState(false);
|
|
7267
|
+
if (!push.supported) {
|
|
6802
7268
|
return null;
|
|
6803
7269
|
}
|
|
6804
7270
|
const isOn = push.deviceEnabled && push.userEnabled;
|
|
6805
7271
|
const permissionBlocked = push.permission === "denied";
|
|
7272
|
+
const adminBlocked = !adminGate.enabled;
|
|
7273
|
+
const notConfigured = !push.configured;
|
|
7274
|
+
const showLoader = isToggling;
|
|
7275
|
+
const isDisabled = showLoader || permissionBlocked || push.loading || adminBlocked || notConfigured;
|
|
6806
7276
|
const handleChange = async (checked) => {
|
|
6807
|
-
if (
|
|
6808
|
-
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
7277
|
+
if (adminBlocked || notConfigured) return;
|
|
7278
|
+
setIsToggling(true);
|
|
7279
|
+
try {
|
|
7280
|
+
if (checked) {
|
|
7281
|
+
if (!push.userEnabled) await push.setUserEnabled(true);
|
|
7282
|
+
if (!push.deviceEnabled) await push.enable();
|
|
7283
|
+
} else {
|
|
7284
|
+
await push.disable();
|
|
7285
|
+
}
|
|
7286
|
+
} finally {
|
|
7287
|
+
setIsToggling(false);
|
|
6812
7288
|
}
|
|
6813
7289
|
};
|
|
7290
|
+
const descriptionText = adminBlocked ? adminGate.disabledReason || description : notConfigured ? "Push notifications are not configured. Please contact your administrator." : permissionBlocked ? "Notifications are blocked in your browser settings" : push.error ?? description;
|
|
7291
|
+
const renderProps = {
|
|
7292
|
+
label,
|
|
7293
|
+
description: descriptionText,
|
|
7294
|
+
checked: adminBlocked || notConfigured ? false : isOn,
|
|
7295
|
+
disabled: isDisabled,
|
|
7296
|
+
loading: showLoader || push.loading,
|
|
7297
|
+
permissionBlocked,
|
|
7298
|
+
error: push.error,
|
|
7299
|
+
onCheckedChange: (checked) => void handleChange(checked)
|
|
7300
|
+
};
|
|
7301
|
+
if (children) {
|
|
7302
|
+
return /* @__PURE__ */ jsx(Fragment, { children: children(renderProps) });
|
|
7303
|
+
}
|
|
6814
7304
|
return /* @__PURE__ */ jsxs(
|
|
6815
7305
|
"div",
|
|
6816
7306
|
{
|
|
6817
|
-
className:
|
|
7307
|
+
className: cn(
|
|
7308
|
+
"flex items-center justify-between gap-4 rounded-xl border border-(--chat-border) bg-(--chat-surface) px-4 py-3",
|
|
7309
|
+
className
|
|
7310
|
+
),
|
|
6818
7311
|
children: [
|
|
6819
7312
|
/* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
6820
7313
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-(--chat-text)", children: label }),
|
|
6821
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-(--chat-muted)", children:
|
|
7314
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-(--chat-muted)", children: renderProps.description })
|
|
6822
7315
|
] }),
|
|
6823
|
-
/* @__PURE__ */ jsx(
|
|
6824
|
-
|
|
7316
|
+
showLoader ? /* @__PURE__ */ jsx(
|
|
7317
|
+
Loader2,
|
|
7318
|
+
{
|
|
7319
|
+
className: "size-5 shrink-0 animate-spin text-(--chat-theme)",
|
|
7320
|
+
"aria-label": "Updating push notifications"
|
|
7321
|
+
}
|
|
7322
|
+
) : /* @__PURE__ */ jsx(
|
|
7323
|
+
AdminPermissionTooltip,
|
|
6825
7324
|
{
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
7325
|
+
disabled: adminBlocked || notConfigured,
|
|
7326
|
+
message: adminBlocked ? adminGate.disabledReason : "Push notifications are not configured. Please contact your administrator.",
|
|
7327
|
+
children: /* @__PURE__ */ jsx(
|
|
7328
|
+
Switch,
|
|
7329
|
+
{
|
|
7330
|
+
checked: adminBlocked || notConfigured ? false : isOn,
|
|
7331
|
+
disabled: isDisabled,
|
|
7332
|
+
onCheckedChange: (checked) => void handleChange(checked),
|
|
7333
|
+
"aria-label": `Toggle ${label}`
|
|
7334
|
+
}
|
|
7335
|
+
)
|
|
6830
7336
|
}
|
|
6831
7337
|
)
|
|
6832
7338
|
]
|
|
6833
7339
|
}
|
|
6834
7340
|
);
|
|
6835
7341
|
};
|
|
6836
|
-
var
|
|
6837
|
-
|
|
7342
|
+
var LoggedUserSettingsContent = ({
|
|
7343
|
+
user,
|
|
7344
|
+
title = "Account settings",
|
|
7345
|
+
showProfile = true,
|
|
7346
|
+
showPushToggle = true,
|
|
7347
|
+
className
|
|
6838
7348
|
}) => {
|
|
6839
|
-
const
|
|
6840
|
-
const
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
"
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
7349
|
+
const { resolveComponent, slotClassName } = useChatCustomization();
|
|
7350
|
+
const PushToggleSlot = resolveComponent(
|
|
7351
|
+
"PushNotificationToggle",
|
|
7352
|
+
PushNotificationToggle
|
|
7353
|
+
);
|
|
7354
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7355
|
+
/* @__PURE__ */ jsx(
|
|
7356
|
+
"div",
|
|
7357
|
+
{
|
|
7358
|
+
className: cn(
|
|
7359
|
+
"border-b border-(--chat-border) px-5 py-4",
|
|
7360
|
+
slotClassName("loggedUserSettingsHeader")
|
|
7361
|
+
),
|
|
7362
|
+
children: /* @__PURE__ */ jsx(DialogTitle, { className: "text-left text-base font-semibold text-(--chat-text)", children: title })
|
|
7363
|
+
}
|
|
7364
|
+
),
|
|
7365
|
+
/* @__PURE__ */ jsxs(
|
|
7366
|
+
"div",
|
|
7367
|
+
{
|
|
7368
|
+
className: cn(
|
|
7369
|
+
"space-y-5 px-5 py-5",
|
|
7370
|
+
slotClassName("loggedUserSettingsContent", className)
|
|
7371
|
+
),
|
|
7372
|
+
children: [
|
|
7373
|
+
showProfile ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center text-center", children: [
|
|
7374
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
7375
|
+
/* @__PURE__ */ jsxs(
|
|
7376
|
+
Avatar,
|
|
7377
|
+
{
|
|
7378
|
+
className: cn(
|
|
7379
|
+
"size-16 ring-2 ring-(--chat-theme-20)",
|
|
7380
|
+
slotClassName("loggedUserSettingsAvatar")
|
|
7381
|
+
),
|
|
7382
|
+
children: [
|
|
7383
|
+
user.image ? /* @__PURE__ */ jsx(AvatarImage, { src: user.image, alt: user.name }) : null,
|
|
7384
|
+
/* @__PURE__ */ jsx(AvatarFallback, { className: "bg-(--chat-theme-10) text-lg font-medium text-(--chat-theme)", children: (user.name || "?").charAt(0).toUpperCase() })
|
|
7385
|
+
]
|
|
7386
|
+
}
|
|
7387
|
+
),
|
|
7388
|
+
/* @__PURE__ */ jsx("span", { className: "absolute bottom-0.5 right-0.5 size-3 rounded-full border-2 border-(--chat-surface) bg-(--chat-online)" })
|
|
6874
7389
|
] }),
|
|
6875
|
-
/* @__PURE__ */ jsx("
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
7390
|
+
/* @__PURE__ */ jsx("h3", { className: "mt-3 text-base font-semibold text-(--chat-text)", children: user.name }),
|
|
7391
|
+
/* @__PURE__ */ jsx("p", { className: "mt-0.5 text-sm text-(--chat-muted)", children: user.email }),
|
|
7392
|
+
/* @__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: [
|
|
7393
|
+
/* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-(--chat-online)" }),
|
|
7394
|
+
"Online"
|
|
7395
|
+
] })
|
|
7396
|
+
] }) : null,
|
|
7397
|
+
showPushToggle ? /* @__PURE__ */ jsx("div", { className: "border-t border-(--chat-border) pt-4", children: /* @__PURE__ */ jsx(
|
|
7398
|
+
PushToggleSlot,
|
|
7399
|
+
{
|
|
7400
|
+
className: cn(
|
|
7401
|
+
"flex items-center justify-between gap-4 rounded-xl border border-(--chat-border) bg-(--chat-theme-10) px-4 py-3",
|
|
7402
|
+
slotClassName("pushNotificationToggle")
|
|
7403
|
+
)
|
|
7404
|
+
}
|
|
7405
|
+
) }) : null
|
|
7406
|
+
]
|
|
7407
|
+
}
|
|
7408
|
+
)
|
|
7409
|
+
] });
|
|
7410
|
+
};
|
|
7411
|
+
var LoggedUserSettingsContent_default = LoggedUserSettingsContent;
|
|
7412
|
+
var LoggedUserSettingsTrigger = ({
|
|
7413
|
+
onClick,
|
|
7414
|
+
className,
|
|
7415
|
+
tooltip = "Settings",
|
|
7416
|
+
ariaLabel = "Account settings"
|
|
7417
|
+
}) => {
|
|
7418
|
+
const { slotClassName } = useChatCustomization();
|
|
7419
|
+
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
7420
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
7421
|
+
Button,
|
|
7422
|
+
{
|
|
7423
|
+
type: "button",
|
|
7424
|
+
variant: "ghost",
|
|
7425
|
+
size: "icon",
|
|
7426
|
+
className: cn(
|
|
7427
|
+
sidebarActionBtnClass,
|
|
7428
|
+
slotClassName("loggedUserSettingsTrigger", className)
|
|
7429
|
+
),
|
|
7430
|
+
"aria-label": ariaLabel,
|
|
7431
|
+
onClick,
|
|
7432
|
+
children: /* @__PURE__ */ jsx(Settings, { className: "size-3.5", strokeWidth: 2 })
|
|
7433
|
+
}
|
|
7434
|
+
) }),
|
|
7435
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "bottom", children: tooltip })
|
|
7436
|
+
] });
|
|
7437
|
+
};
|
|
7438
|
+
var LoggedUserSettingsTrigger_default = LoggedUserSettingsTrigger;
|
|
7439
|
+
var LoggedUserSettingsDialog = ({
|
|
7440
|
+
loggedUserDetails,
|
|
7441
|
+
open: controlledOpen,
|
|
7442
|
+
onOpenChange: controlledOnOpenChange,
|
|
7443
|
+
title,
|
|
7444
|
+
showProfile = true,
|
|
7445
|
+
showPushToggle = true,
|
|
7446
|
+
className
|
|
7447
|
+
}) => {
|
|
7448
|
+
const { resolveComponent, slotClassName } = useChatCustomization();
|
|
7449
|
+
const [internalOpen, setInternalOpen] = useState(false);
|
|
7450
|
+
const open = controlledOpen ?? internalOpen;
|
|
7451
|
+
const onOpenChange = controlledOnOpenChange ?? setInternalOpen;
|
|
7452
|
+
const TriggerSlot = resolveComponent(
|
|
7453
|
+
"LoggedUserSettingsTrigger",
|
|
7454
|
+
LoggedUserSettingsTrigger_default
|
|
7455
|
+
);
|
|
7456
|
+
const ContentSlot = resolveComponent(
|
|
7457
|
+
"LoggedUserSettingsContent",
|
|
7458
|
+
LoggedUserSettingsContent_default
|
|
7459
|
+
);
|
|
7460
|
+
const user = buildLoggedUserProfile(loggedUserDetails);
|
|
7461
|
+
return /* @__PURE__ */ jsxs(Dialog, { open, onOpenChange, children: [
|
|
7462
|
+
/* @__PURE__ */ jsx(TriggerSlot, { onClick: () => onOpenChange(true) }),
|
|
7463
|
+
/* @__PURE__ */ jsx(
|
|
7464
|
+
ChatDialogContent,
|
|
7465
|
+
{
|
|
7466
|
+
className: cn(
|
|
7467
|
+
"gap-0 overflow-hidden p-0 sm:max-w-[380px]",
|
|
7468
|
+
slotClassName("loggedUserSettingsDialog", className)
|
|
7469
|
+
),
|
|
7470
|
+
children: /* @__PURE__ */ jsx(
|
|
7471
|
+
ContentSlot,
|
|
7472
|
+
{
|
|
7473
|
+
loggedUserDetails,
|
|
7474
|
+
user,
|
|
7475
|
+
onClose: () => onOpenChange(false),
|
|
7476
|
+
title,
|
|
7477
|
+
showProfile,
|
|
7478
|
+
showPushToggle
|
|
7479
|
+
}
|
|
7480
|
+
)
|
|
7481
|
+
}
|
|
7482
|
+
)
|
|
6887
7483
|
] });
|
|
6888
7484
|
};
|
|
6889
7485
|
var LoggedUserSettingsDialog_default = LoggedUserSettingsDialog;
|
|
@@ -6896,16 +7492,12 @@ var LoggedUserDetails = ({
|
|
|
6896
7492
|
setSearchQuery
|
|
6897
7493
|
}) => {
|
|
6898
7494
|
const { showColorModeToggle } = useChatTheme();
|
|
6899
|
-
const
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
createdAt: loggedUserDetails?.createdAt ? new Date(loggedUserDetails.createdAt) : /* @__PURE__ */ new Date(),
|
|
6906
|
-
updatedAt: loggedUserDetails?.updatedAt ? new Date(loggedUserDetails.updatedAt) : /* @__PURE__ */ new Date(),
|
|
6907
|
-
image: loggedUserDetails?.image || void 0
|
|
6908
|
-
};
|
|
7495
|
+
const { resolveComponent } = useChatCustomization();
|
|
7496
|
+
const SettingsDialogSlot = resolveComponent(
|
|
7497
|
+
"LoggedUserSettingsDialog",
|
|
7498
|
+
LoggedUserSettingsDialog_default
|
|
7499
|
+
);
|
|
7500
|
+
const user = buildLoggedUserProfile(loggedUserDetails);
|
|
6909
7501
|
return /* @__PURE__ */ jsxs("div", { className: "shrink-0 border-b border-(--chat-border) bg-(--chat-surface) px-3 pb-3 pt-3", children: [
|
|
6910
7502
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [
|
|
6911
7503
|
/* @__PURE__ */ jsxs("div", { className: "relative shrink-0", children: [
|
|
@@ -6916,14 +7508,11 @@ var LoggedUserDetails = ({
|
|
|
6916
7508
|
/* @__PURE__ */ jsx("span", { className: "absolute -bottom-0.5 -right-0.5 size-2 rounded-full border-2 border-(--chat-surface) bg-(--chat-online)" })
|
|
6917
7509
|
] }),
|
|
6918
7510
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
6919
|
-
/* @__PURE__ */
|
|
6920
|
-
user.name,
|
|
6921
|
-
"123"
|
|
6922
|
-
] }),
|
|
7511
|
+
/* @__PURE__ */ jsx("h2", { className: "truncate text-xs font-medium leading-tight text-(--chat-text)", children: user.name }),
|
|
6923
7512
|
/* @__PURE__ */ jsx("p", { className: "truncate text-[10px] text-(--chat-muted)", children: user.email })
|
|
6924
7513
|
] }),
|
|
6925
7514
|
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-0.5", children: [
|
|
6926
|
-
/* @__PURE__ */ jsx(
|
|
7515
|
+
/* @__PURE__ */ jsx(SettingsDialogSlot, { loggedUserDetails }),
|
|
6927
7516
|
showColorModeToggle ? /* @__PURE__ */ jsx(ChatThemeToggle_default, {}) : null
|
|
6928
7517
|
] })
|
|
6929
7518
|
] }),
|
|
@@ -8164,7 +8753,7 @@ function highlightSearchMatch(text, query) {
|
|
|
8164
8753
|
children: part
|
|
8165
8754
|
},
|
|
8166
8755
|
`${part}-${index}`
|
|
8167
|
-
) : /* @__PURE__ */ jsx(
|
|
8756
|
+
) : /* @__PURE__ */ jsx(React3__default.Fragment, { children: part }, `${part}-${index}`)
|
|
8168
8757
|
);
|
|
8169
8758
|
}
|
|
8170
8759
|
function getMessagePreview(message) {
|
|
@@ -8344,7 +8933,7 @@ var HeaderSearchPopover = ({
|
|
|
8344
8933
|
] });
|
|
8345
8934
|
};
|
|
8346
8935
|
var HeaderSearchPopover_default = HeaderSearchPopover;
|
|
8347
|
-
var actionBtnClass = "size-8 rounded-lg text-(--chat-muted) transition-colors hover:bg-(--chat-surface) hover:text-(--chat-text)";
|
|
8936
|
+
var actionBtnClass = "size-8 rounded-lg text-(--chat-muted) transition-colors hover:bg-(--chat-surface) hover:text-(--chat-text) disabled:pointer-events-none disabled:opacity-40";
|
|
8348
8937
|
var DefaultHeaderCallActions = ({
|
|
8349
8938
|
activeChannel,
|
|
8350
8939
|
conversationId,
|
|
@@ -8355,48 +8944,91 @@ var DefaultHeaderCallActions = ({
|
|
|
8355
8944
|
className
|
|
8356
8945
|
}) => {
|
|
8357
8946
|
const { components, slotClassName, features } = useChatCustomizationOptional();
|
|
8947
|
+
const { getAudioCallGate, getVideoCallGate } = useEffectiveSettingsOptional();
|
|
8358
8948
|
const PhoneSlot = components.PhoneCallButton;
|
|
8359
8949
|
const VideoSlot = components.VideoCallButton;
|
|
8360
8950
|
const hideInGroups = features.hideCallActionsInGroupChats ?? false;
|
|
8951
|
+
const audioGate = getAudioCallGate();
|
|
8952
|
+
const videoGate = getVideoCallGate();
|
|
8361
8953
|
if (hideInGroups && activeChannel.isGroup) return null;
|
|
8362
8954
|
if (!showPhoneCall && !showVideoCall) return null;
|
|
8955
|
+
const phoneEnabled = showPhoneCall && audioGate.enabled;
|
|
8956
|
+
const videoEnabled = showVideoCall && videoGate.enabled;
|
|
8363
8957
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8364
8958
|
showPhoneCall && (PhoneSlot ? /* @__PURE__ */ jsx(
|
|
8365
|
-
|
|
8959
|
+
AdminPermissionTooltip,
|
|
8366
8960
|
{
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
|
|
8370
|
-
|
|
8961
|
+
disabled: !audioGate.enabled,
|
|
8962
|
+
message: audioGate.disabledReason,
|
|
8963
|
+
children: /* @__PURE__ */ jsx("span", { className: "inline-flex", children: /* @__PURE__ */ jsx(
|
|
8964
|
+
PhoneSlot,
|
|
8965
|
+
{
|
|
8966
|
+
activeChannel,
|
|
8967
|
+
conversationId,
|
|
8968
|
+
onPhoneCall: phoneEnabled ? onPhoneCall : void 0,
|
|
8969
|
+
className: cn(
|
|
8970
|
+
className,
|
|
8971
|
+
slotClassName("phoneCallButton"),
|
|
8972
|
+
!audioGate.enabled && "pointer-events-none opacity-40"
|
|
8973
|
+
)
|
|
8974
|
+
}
|
|
8975
|
+
) })
|
|
8371
8976
|
}
|
|
8372
8977
|
) : /* @__PURE__ */ jsx(
|
|
8373
|
-
|
|
8978
|
+
AdminPermissionTooltip,
|
|
8374
8979
|
{
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
8980
|
+
disabled: !audioGate.enabled,
|
|
8981
|
+
message: audioGate.disabledReason,
|
|
8982
|
+
children: /* @__PURE__ */ jsx(
|
|
8983
|
+
Button,
|
|
8984
|
+
{
|
|
8985
|
+
variant: "ghost",
|
|
8986
|
+
size: "icon",
|
|
8987
|
+
className: cn(actionBtnClass, className, slotClassName("phoneCallButton")),
|
|
8988
|
+
"aria-label": "Voice call",
|
|
8989
|
+
disabled: !audioGate.enabled,
|
|
8990
|
+
onClick: phoneEnabled ? onPhoneCall : void 0,
|
|
8991
|
+
children: /* @__PURE__ */ jsx(Phone, { size: 15 })
|
|
8992
|
+
}
|
|
8993
|
+
)
|
|
8381
8994
|
}
|
|
8382
8995
|
)),
|
|
8383
8996
|
showVideoCall && (VideoSlot ? /* @__PURE__ */ jsx(
|
|
8384
|
-
|
|
8997
|
+
AdminPermissionTooltip,
|
|
8385
8998
|
{
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
8999
|
+
disabled: !videoGate.enabled,
|
|
9000
|
+
message: videoGate.disabledReason,
|
|
9001
|
+
children: /* @__PURE__ */ jsx("span", { className: "inline-flex", children: /* @__PURE__ */ jsx(
|
|
9002
|
+
VideoSlot,
|
|
9003
|
+
{
|
|
9004
|
+
activeChannel,
|
|
9005
|
+
conversationId,
|
|
9006
|
+
onVideoCall: videoEnabled ? onVideoCall : void 0,
|
|
9007
|
+
className: cn(
|
|
9008
|
+
className,
|
|
9009
|
+
slotClassName("videoCallButton"),
|
|
9010
|
+
!videoGate.enabled && "pointer-events-none opacity-40"
|
|
9011
|
+
)
|
|
9012
|
+
}
|
|
9013
|
+
) })
|
|
8390
9014
|
}
|
|
8391
9015
|
) : /* @__PURE__ */ jsx(
|
|
8392
|
-
|
|
9016
|
+
AdminPermissionTooltip,
|
|
8393
9017
|
{
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
|
|
8397
|
-
|
|
8398
|
-
|
|
8399
|
-
|
|
9018
|
+
disabled: !videoGate.enabled,
|
|
9019
|
+
message: videoGate.disabledReason,
|
|
9020
|
+
children: /* @__PURE__ */ jsx(
|
|
9021
|
+
Button,
|
|
9022
|
+
{
|
|
9023
|
+
variant: "ghost",
|
|
9024
|
+
size: "icon",
|
|
9025
|
+
className: cn(actionBtnClass, className, slotClassName("videoCallButton")),
|
|
9026
|
+
"aria-label": "Video call",
|
|
9027
|
+
disabled: !videoGate.enabled,
|
|
9028
|
+
onClick: videoEnabled ? onVideoCall : void 0,
|
|
9029
|
+
children: /* @__PURE__ */ jsx(Video, { size: 15 })
|
|
9030
|
+
}
|
|
9031
|
+
)
|
|
8400
9032
|
}
|
|
8401
9033
|
))
|
|
8402
9034
|
] });
|
|
@@ -8418,19 +9050,38 @@ function OptionsMenuItem({
|
|
|
8418
9050
|
icon: Icon,
|
|
8419
9051
|
label,
|
|
8420
9052
|
onSelect,
|
|
8421
|
-
destructive = false
|
|
9053
|
+
destructive = false,
|
|
9054
|
+
disabled = false,
|
|
9055
|
+
disabledReason
|
|
8422
9056
|
}) {
|
|
8423
|
-
|
|
9057
|
+
const item = /* @__PURE__ */ jsxs(
|
|
8424
9058
|
DropdownMenuItem,
|
|
8425
9059
|
{
|
|
8426
|
-
className:
|
|
8427
|
-
|
|
9060
|
+
className: cn(
|
|
9061
|
+
destructive ? chatOptionsMenuItemDestructiveClass : chatOptionsMenuItemClass,
|
|
9062
|
+
disabled && "pointer-events-none opacity-40"
|
|
9063
|
+
),
|
|
9064
|
+
disabled,
|
|
9065
|
+
onSelect: (event) => {
|
|
9066
|
+
if (disabled) {
|
|
9067
|
+
event.preventDefault();
|
|
9068
|
+
return;
|
|
9069
|
+
}
|
|
9070
|
+
onSelect?.();
|
|
9071
|
+
},
|
|
8428
9072
|
children: [
|
|
8429
9073
|
/* @__PURE__ */ jsx(Icon, { strokeWidth: 1.75 }),
|
|
8430
9074
|
/* @__PURE__ */ jsx("span", { className: "flex-1", children: label })
|
|
8431
9075
|
]
|
|
8432
9076
|
}
|
|
8433
9077
|
);
|
|
9078
|
+
if (!disabled || !disabledReason) {
|
|
9079
|
+
return item;
|
|
9080
|
+
}
|
|
9081
|
+
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
9082
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "w-full", children: item }) }),
|
|
9083
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "left", className: "max-w-[220px] text-xs", children: disabledReason })
|
|
9084
|
+
] });
|
|
8434
9085
|
}
|
|
8435
9086
|
var HeaderRightSide = ({
|
|
8436
9087
|
activeChannel,
|
|
@@ -8465,6 +9116,8 @@ var HeaderRightSide = ({
|
|
|
8465
9116
|
const { scopeClassName, themeStyles, showColorModeToggle } = useChatTheme();
|
|
8466
9117
|
const { showDateTimeSettings } = useChatLocale();
|
|
8467
9118
|
const features = useChatFeaturesOptional();
|
|
9119
|
+
const { getBlockUsersGate } = useEffectiveSettingsOptional();
|
|
9120
|
+
const blockUsersGate = getBlockUsersGate();
|
|
8468
9121
|
const showPhoneCall = features.showPhoneCall ?? defaultChatFeatures.showPhoneCall;
|
|
8469
9122
|
const showVideoCall = features.showVideoCall ?? defaultChatFeatures.showVideoCall;
|
|
8470
9123
|
const handlePhoneCall = () => {
|
|
@@ -8613,7 +9266,9 @@ var HeaderRightSide = ({
|
|
|
8613
9266
|
icon: Ban,
|
|
8614
9267
|
label: isBlocked ? "Unblock User" : "Block User",
|
|
8615
9268
|
onSelect: onToggleBlock,
|
|
8616
|
-
destructive: true
|
|
9269
|
+
destructive: true,
|
|
9270
|
+
disabled: !blockUsersGate.enabled,
|
|
9271
|
+
disabledReason: blockUsersGate.disabledReason
|
|
8617
9272
|
}
|
|
8618
9273
|
)
|
|
8619
9274
|
]
|
|
@@ -12653,17 +13308,24 @@ var ChannelDetailsDrawer = (props) => {
|
|
|
12653
13308
|
};
|
|
12654
13309
|
var ChannelDetailsDrawer_default = ChannelDetailsDrawer;
|
|
12655
13310
|
init_useStore();
|
|
13311
|
+
init_settings_types();
|
|
12656
13312
|
var PermissionDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo }) => {
|
|
12657
13313
|
const updateGroupPermissions = useStore((s) => s.updateGroupPermissions);
|
|
13314
|
+
const { settings, isGroupPermissionLocked } = useEffectiveSettingsOptional();
|
|
12658
13315
|
const [permissions, setPermissions] = useState(null);
|
|
12659
13316
|
const [isSaving, setIsSaving] = useState(false);
|
|
12660
13317
|
useEffect(() => {
|
|
12661
13318
|
if (conversationInfo?.groupPermissions) {
|
|
12662
13319
|
setPermissions(conversationInfo.groupPermissions);
|
|
13320
|
+
return;
|
|
12663
13321
|
}
|
|
12664
|
-
|
|
13322
|
+
if (isOpen) {
|
|
13323
|
+
setPermissions({ ...settings.groupPolicy.defaults });
|
|
13324
|
+
}
|
|
13325
|
+
}, [conversationInfo, isOpen, settings.groupPolicy.defaults]);
|
|
12665
13326
|
if (!conversationId || !permissions) return null;
|
|
12666
13327
|
const handleToggle = (key) => {
|
|
13328
|
+
if (isGroupPermissionLocked(key)) return;
|
|
12667
13329
|
setPermissions((prev) => prev ? { ...prev, [key]: !prev[key] } : null);
|
|
12668
13330
|
};
|
|
12669
13331
|
const handleSave = async () => {
|
|
@@ -12695,31 +13357,43 @@ var PermissionDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo
|
|
|
12695
13357
|
/* @__PURE__ */ jsxs("div", { className: cn(chatSheetBodyClass, "flex flex-col px-2.5 py-2"), children: [
|
|
12696
13358
|
/* @__PURE__ */ jsxs("section", { className: "mb-2.5 flex-1", children: [
|
|
12697
13359
|
/* @__PURE__ */ jsx("h3", { className: "mb-1 px-0.5 text-[10px] font-semibold uppercase tracking-wide text-(--chat-muted)", children: "Permissions" }),
|
|
12698
|
-
/* @__PURE__ */ jsx("div", { className: "rounded-lg border border-(--chat-border) px-3", children: permissionItems.map((item, index) =>
|
|
12699
|
-
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
|
|
12703
|
-
|
|
12704
|
-
|
|
12705
|
-
|
|
12706
|
-
|
|
12707
|
-
|
|
12708
|
-
/* @__PURE__ */
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
|
|
12715
|
-
|
|
12716
|
-
|
|
12717
|
-
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
13360
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-lg border border-(--chat-border) px-3", children: permissionItems.map((item, index) => {
|
|
13361
|
+
const locked = isGroupPermissionLocked(item.key);
|
|
13362
|
+
return /* @__PURE__ */ jsxs(
|
|
13363
|
+
"div",
|
|
13364
|
+
{
|
|
13365
|
+
className: cn(
|
|
13366
|
+
"flex items-start justify-between gap-3 py-2.5",
|
|
13367
|
+
index < permissionItems.length - 1 && "border-b border-(--chat-border)"
|
|
13368
|
+
),
|
|
13369
|
+
children: [
|
|
13370
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-0.5", children: [
|
|
13371
|
+
/* @__PURE__ */ jsx("p", { className: "text-[12px] font-semibold leading-snug text-(--chat-text)", children: item.label }),
|
|
13372
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] leading-relaxed text-(--chat-muted)", children: item.desc }),
|
|
13373
|
+
locked ? /* @__PURE__ */ jsx("p", { className: "text-[10px] font-medium text-(--chat-theme)", children: "Locked by administrator" }) : null
|
|
13374
|
+
] }),
|
|
13375
|
+
/* @__PURE__ */ jsx(
|
|
13376
|
+
AdminPermissionTooltip,
|
|
13377
|
+
{
|
|
13378
|
+
disabled: locked,
|
|
13379
|
+
message: ADMIN_PERMISSION_DENIED_MESSAGE,
|
|
13380
|
+
children: /* @__PURE__ */ jsx(
|
|
13381
|
+
Switch,
|
|
13382
|
+
{
|
|
13383
|
+
size: "sm",
|
|
13384
|
+
className: "mt-0.5 shrink-0 data-[state=checked]:bg-(--chat-theme) data-[state=unchecked]:bg-(--chat-border)",
|
|
13385
|
+
disabled: locked,
|
|
13386
|
+
checked: item.inverted ? !permissions[item.key] : permissions[item.key],
|
|
13387
|
+
onCheckedChange: () => handleToggle(item.key)
|
|
13388
|
+
}
|
|
13389
|
+
)
|
|
13390
|
+
}
|
|
13391
|
+
)
|
|
13392
|
+
]
|
|
13393
|
+
},
|
|
13394
|
+
item.key
|
|
13395
|
+
);
|
|
13396
|
+
}) })
|
|
12723
13397
|
] }),
|
|
12724
13398
|
/* @__PURE__ */ jsx("div", { className: "sticky bottom-0 border-t border-(--chat-border) bg-(--chat-surface) px-0.5 pt-2.5 pb-1", children: /* @__PURE__ */ jsx(
|
|
12725
13399
|
Button,
|
|
@@ -12749,6 +13423,8 @@ function useAdminsDrawer({ conversationId, conversationInfo }) {
|
|
|
12749
13423
|
const [isManaging, setIsManaging] = useState(null);
|
|
12750
13424
|
const manageGroupAdmins = useStore((s) => s.manageGroupAdmins);
|
|
12751
13425
|
const { isOwner } = useGroupInfo(conversationId);
|
|
13426
|
+
const { settings } = useEffectiveSettingsOptional();
|
|
13427
|
+
const maxAdmins = settings.maxAdminsPerGroup;
|
|
12752
13428
|
const participants = useMemo(
|
|
12753
13429
|
() => conversationInfo?.participants ?? [],
|
|
12754
13430
|
[conversationInfo?.participants]
|
|
@@ -12788,8 +13464,16 @@ function useAdminsDrawer({ conversationId, conversationInfo }) {
|
|
|
12788
13464
|
}),
|
|
12789
13465
|
[filteredParticipants, adminIds, ownerId]
|
|
12790
13466
|
);
|
|
13467
|
+
const adminCount = admins.length + (ownerId ? 1 : 0);
|
|
13468
|
+
const atAdminLimit = adminCount >= maxAdmins;
|
|
12791
13469
|
const handleManageAdmin = async (userId, type) => {
|
|
12792
13470
|
if (!conversationId) return;
|
|
13471
|
+
if (type === "add" && adminCount >= maxAdmins) {
|
|
13472
|
+
useStore.getState().handleAppError(
|
|
13473
|
+
`You can have up to ${maxAdmins} admins in this group.`
|
|
13474
|
+
);
|
|
13475
|
+
return;
|
|
13476
|
+
}
|
|
12793
13477
|
setIsManaging(userId);
|
|
12794
13478
|
try {
|
|
12795
13479
|
await manageGroupAdmins({
|
|
@@ -12801,7 +13485,6 @@ function useAdminsDrawer({ conversationId, conversationInfo }) {
|
|
|
12801
13485
|
setIsManaging(null);
|
|
12802
13486
|
}
|
|
12803
13487
|
};
|
|
12804
|
-
const adminCount = admins.length + (ownerId ? 1 : 0);
|
|
12805
13488
|
return {
|
|
12806
13489
|
searchQuery,
|
|
12807
13490
|
setSearchQuery,
|
|
@@ -12813,6 +13496,8 @@ function useAdminsDrawer({ conversationId, conversationInfo }) {
|
|
|
12813
13496
|
promotableParticipants,
|
|
12814
13497
|
handleManageAdmin,
|
|
12815
13498
|
adminCount,
|
|
13499
|
+
maxAdmins,
|
|
13500
|
+
atAdminLimit,
|
|
12816
13501
|
hasRequiredData: Boolean(conversationId && conversationInfo)
|
|
12817
13502
|
};
|
|
12818
13503
|
}
|
|
@@ -12825,6 +13510,8 @@ function AdminParticipantRow({
|
|
|
12825
13510
|
isAdmin,
|
|
12826
13511
|
showPromote,
|
|
12827
13512
|
showDemote,
|
|
13513
|
+
promoteDisabled = false,
|
|
13514
|
+
promoteDisabledReason,
|
|
12828
13515
|
isOwnerViewer,
|
|
12829
13516
|
isManaging,
|
|
12830
13517
|
onManageAdmin
|
|
@@ -12865,14 +13552,24 @@ function AdminParticipantRow({
|
|
|
12865
13552
|
}
|
|
12866
13553
|
),
|
|
12867
13554
|
showPromote && isOwnerViewer && /* @__PURE__ */ jsx(
|
|
12868
|
-
|
|
13555
|
+
AdminPermissionTooltip,
|
|
12869
13556
|
{
|
|
12870
|
-
|
|
12871
|
-
|
|
12872
|
-
|
|
12873
|
-
|
|
12874
|
-
|
|
12875
|
-
|
|
13557
|
+
disabled: promoteDisabled,
|
|
13558
|
+
message: promoteDisabledReason,
|
|
13559
|
+
children: /* @__PURE__ */ jsx(
|
|
13560
|
+
Button,
|
|
13561
|
+
{
|
|
13562
|
+
variant: "ghost",
|
|
13563
|
+
size: "sm",
|
|
13564
|
+
className: "size-7 rounded-md p-0 text-(--chat-muted) hover:bg-(--chat-theme-10) hover:text-(--chat-theme) disabled:opacity-40",
|
|
13565
|
+
onClick: () => {
|
|
13566
|
+
if (promoteDisabled) return;
|
|
13567
|
+
onManageAdmin(memberId, "add");
|
|
13568
|
+
},
|
|
13569
|
+
disabled: isManaging === memberId || promoteDisabled,
|
|
13570
|
+
children: isManaging === memberId ? /* @__PURE__ */ jsx(Loader2, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsx(UserPlus, { size: 13 })
|
|
13571
|
+
}
|
|
13572
|
+
)
|
|
12876
13573
|
}
|
|
12877
13574
|
)
|
|
12878
13575
|
] })
|
|
@@ -12896,7 +13593,9 @@ function AdminParticipantList({
|
|
|
12896
13593
|
isAdmin,
|
|
12897
13594
|
onManageAdmin,
|
|
12898
13595
|
showPromote,
|
|
12899
|
-
showDemoteForAdmins
|
|
13596
|
+
showDemoteForAdmins,
|
|
13597
|
+
promoteDisabled = false,
|
|
13598
|
+
promoteDisabledReason
|
|
12900
13599
|
}) {
|
|
12901
13600
|
return /* @__PURE__ */ jsx(Fragment, { children: members.map((member, index) => {
|
|
12902
13601
|
const { memberId, memberName, memberEmail, memberImage } = getMemberFields(member);
|
|
@@ -12914,6 +13613,8 @@ function AdminParticipantList({
|
|
|
12914
13613
|
isAdmin: userIsAdmin,
|
|
12915
13614
|
showPromote: showPromote && !userIsAdmin && !userIsOwner,
|
|
12916
13615
|
showDemote: showDemoteForAdmins ? userIsAdmin && !userIsOwner : false,
|
|
13616
|
+
promoteDisabled,
|
|
13617
|
+
promoteDisabledReason,
|
|
12917
13618
|
isOwnerViewer,
|
|
12918
13619
|
isManaging,
|
|
12919
13620
|
onManageAdmin
|
|
@@ -12933,6 +13634,8 @@ var AdminsDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo })
|
|
|
12933
13634
|
promotableParticipants,
|
|
12934
13635
|
handleManageAdmin,
|
|
12935
13636
|
adminCount,
|
|
13637
|
+
maxAdmins,
|
|
13638
|
+
atAdminLimit,
|
|
12936
13639
|
hasRequiredData
|
|
12937
13640
|
} = useAdminsDrawer({ conversationId, conversationInfo });
|
|
12938
13641
|
if (!hasRequiredData) return null;
|
|
@@ -12952,7 +13655,10 @@ var AdminsDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo })
|
|
|
12952
13655
|
/* @__PURE__ */ jsx(SheetTitle, { className: chatSheetTitleClass, children: "Group Administrators" }),
|
|
12953
13656
|
/* @__PURE__ */ jsx("span", { className: "rounded-full bg-(--chat-theme-10) px-2 py-0.5 text-[11px] font-medium leading-none text-(--chat-theme)", children: adminCount })
|
|
12954
13657
|
] }),
|
|
12955
|
-
/* @__PURE__ */
|
|
13658
|
+
/* @__PURE__ */ jsxs("p", { className: chatSheetSubtitleClass, children: [
|
|
13659
|
+
"Manage who can adjust group settings and members",
|
|
13660
|
+
maxAdmins ? ` (max ${maxAdmins}).` : "."
|
|
13661
|
+
] })
|
|
12956
13662
|
] }),
|
|
12957
13663
|
/* @__PURE__ */ jsxs("div", { className: cn(chatSheetBodyClass, "px-2.5 py-2"), children: [
|
|
12958
13664
|
/* @__PURE__ */ jsx("div", { className: "mb-2.5 px-0.5", children: /* @__PURE__ */ jsx(
|
|
@@ -12995,7 +13701,9 @@ var AdminsDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo })
|
|
|
12995
13701
|
ownerId,
|
|
12996
13702
|
isAdmin,
|
|
12997
13703
|
onManageAdmin: handleManageAdmin,
|
|
12998
|
-
showPromote: true
|
|
13704
|
+
showPromote: true,
|
|
13705
|
+
promoteDisabled: atAdminLimit,
|
|
13706
|
+
promoteDisabledReason: `Maximum ${maxAdmins} admins allowed in this group.`
|
|
12999
13707
|
}
|
|
13000
13708
|
) })
|
|
13001
13709
|
] }),
|
|
@@ -13012,7 +13720,9 @@ var AdminsDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo })
|
|
|
13012
13720
|
isAdmin,
|
|
13013
13721
|
onManageAdmin: handleManageAdmin,
|
|
13014
13722
|
showPromote: true,
|
|
13015
|
-
showDemoteForAdmins: true
|
|
13723
|
+
showDemoteForAdmins: true,
|
|
13724
|
+
promoteDisabled: atAdminLimit,
|
|
13725
|
+
promoteDisabledReason: `Maximum ${maxAdmins} admins allowed in this group.`
|
|
13016
13726
|
}
|
|
13017
13727
|
) })
|
|
13018
13728
|
] }),
|
|
@@ -13040,9 +13750,12 @@ var MembersDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo })
|
|
|
13040
13750
|
);
|
|
13041
13751
|
}, [allUsers, searchQuery]);
|
|
13042
13752
|
const { userPermissions } = useGroupInfo(conversationId);
|
|
13753
|
+
const { settings } = useEffectiveSettingsOptional();
|
|
13754
|
+
const maxParticipants = settings.maxParticipantsPerGroup;
|
|
13043
13755
|
if (!conversationId || !conversationInfo) return null;
|
|
13044
13756
|
const participants = conversationInfo.participants || [];
|
|
13045
13757
|
const admins = conversationInfo.groupAdmins || [];
|
|
13758
|
+
const atParticipantLimit = participants.length >= maxParticipants;
|
|
13046
13759
|
let ownerId = null;
|
|
13047
13760
|
if (conversationInfo.owner) {
|
|
13048
13761
|
ownerId = typeof conversationInfo.owner === "object" && conversationInfo.owner !== null ? conversationInfo.owner._id || conversationInfo.owner.id : conversationInfo.owner;
|
|
@@ -13096,14 +13809,24 @@ var MembersDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo })
|
|
|
13096
13809
|
}
|
|
13097
13810
|
),
|
|
13098
13811
|
options.showAdd && /* @__PURE__ */ jsx(
|
|
13099
|
-
|
|
13812
|
+
AdminPermissionTooltip,
|
|
13100
13813
|
{
|
|
13101
|
-
|
|
13102
|
-
|
|
13103
|
-
|
|
13104
|
-
|
|
13105
|
-
|
|
13106
|
-
|
|
13814
|
+
disabled: atParticipantLimit,
|
|
13815
|
+
message: `Maximum ${maxParticipants} participants allowed in this group.`,
|
|
13816
|
+
children: /* @__PURE__ */ jsx(
|
|
13817
|
+
Button,
|
|
13818
|
+
{
|
|
13819
|
+
variant: "ghost",
|
|
13820
|
+
size: "sm",
|
|
13821
|
+
className: "size-7 rounded-md p-0 text-(--chat-muted) hover:bg-(--chat-theme-10) hover:text-(--chat-theme) disabled:opacity-40",
|
|
13822
|
+
onClick: () => {
|
|
13823
|
+
if (atParticipantLimit) return;
|
|
13824
|
+
handleManageMember(memberId, "add");
|
|
13825
|
+
},
|
|
13826
|
+
disabled: isManaging === memberId || atParticipantLimit,
|
|
13827
|
+
children: isManaging === memberId ? /* @__PURE__ */ jsx(Loader2, { size: 12, className: "animate-spin" }) : /* @__PURE__ */ jsx(UserPlus, { size: 13 })
|
|
13828
|
+
}
|
|
13829
|
+
)
|
|
13107
13830
|
}
|
|
13108
13831
|
)
|
|
13109
13832
|
] })
|
|
@@ -13125,7 +13848,11 @@ var MembersDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo })
|
|
|
13125
13848
|
/* @__PURE__ */ jsx(SheetTitle, { className: chatSheetTitleClass, children: "Group Management" }),
|
|
13126
13849
|
/* @__PURE__ */ jsx("span", { className: "rounded-full bg-(--chat-theme-10) px-2 py-0.5 text-[11px] font-medium leading-none text-(--chat-theme)", children: participants.length })
|
|
13127
13850
|
] }),
|
|
13128
|
-
/* @__PURE__ */
|
|
13851
|
+
/* @__PURE__ */ jsxs("p", { className: chatSheetSubtitleClass, children: [
|
|
13852
|
+
"Manage members and invite people (max ",
|
|
13853
|
+
maxParticipants,
|
|
13854
|
+
")."
|
|
13855
|
+
] })
|
|
13129
13856
|
] }),
|
|
13130
13857
|
/* @__PURE__ */ jsxs("div", { className: cn(chatSheetBodyClass, "px-2.5 py-2"), children: [
|
|
13131
13858
|
!searchQuery && /* @__PURE__ */ jsxs("section", { className: "mb-2.5", children: [
|
|
@@ -13267,6 +13994,8 @@ init_store_helpers();
|
|
|
13267
13994
|
function useBlockUser(activeChannel, conversationId, onActiveChannelPatch) {
|
|
13268
13995
|
const loggedUserDetails = useStore((s) => s.loggedUserDetails);
|
|
13269
13996
|
const composerDisabledByConversation = useStore((s) => s.composerDisabledByConversation);
|
|
13997
|
+
const { getBlockUsersGate } = useEffectiveSettingsOptional();
|
|
13998
|
+
const blockUsersGate = getBlockUsersGate();
|
|
13270
13999
|
const [isBlocking, setIsBlocking] = useState(false);
|
|
13271
14000
|
const resolvedConversationId = conversationId ?? activeChannel?.conversationId ?? null;
|
|
13272
14001
|
const composerDisabledReason = resolvedConversationId ? composerDisabledByConversation[resolvedConversationId] : void 0;
|
|
@@ -13288,6 +14017,12 @@ function useBlockUser(activeChannel, conversationId, onActiveChannelPatch) {
|
|
|
13288
14017
|
const toggleBlock = useCallback(async () => {
|
|
13289
14018
|
if (!activeChannel?.id || activeChannel.isGroup) return false;
|
|
13290
14019
|
const nextBlocked = !isBlocked;
|
|
14020
|
+
if (nextBlocked && !blockUsersGate.enabled) {
|
|
14021
|
+
useStore.getState().handleAppError(
|
|
14022
|
+
blockUsersGate.disabledReason || "Blocking users is disabled by your administrator."
|
|
14023
|
+
);
|
|
14024
|
+
return false;
|
|
14025
|
+
}
|
|
13291
14026
|
const type = nextBlocked ? "block" : "unblock";
|
|
13292
14027
|
try {
|
|
13293
14028
|
setIsBlocking(true);
|
|
@@ -13308,8 +14043,8 @@ function useBlockUser(activeChannel, conversationId, onActiveChannelPatch) {
|
|
|
13308
14043
|
} finally {
|
|
13309
14044
|
setIsBlocking(false);
|
|
13310
14045
|
}
|
|
13311
|
-
}, [activeChannel, isBlocked, onActiveChannelPatch, resolvedConversationId]);
|
|
13312
|
-
return { isBlocked, isBlocking, toggleBlock };
|
|
14046
|
+
}, [activeChannel, isBlocked, onActiveChannelPatch, resolvedConversationId, blockUsersGate]);
|
|
14047
|
+
return { isBlocked, isBlocking, toggleBlock, blockUsersGate };
|
|
13313
14048
|
}
|
|
13314
14049
|
|
|
13315
14050
|
// src/chat/channel-header/useChannelHeader.ts
|
|
@@ -13845,6 +14580,7 @@ var MessageReactions_default = MessageReactions;
|
|
|
13845
14580
|
var MessageToolbar = ({
|
|
13846
14581
|
isSender,
|
|
13847
14582
|
isRecent,
|
|
14583
|
+
isWithinDeleteWindow = isRecent,
|
|
13848
14584
|
isPinned,
|
|
13849
14585
|
isStarred,
|
|
13850
14586
|
isPinPending,
|
|
@@ -13868,7 +14604,7 @@ var MessageToolbar = ({
|
|
|
13868
14604
|
}) => {
|
|
13869
14605
|
const { isDark, scopeClassName, themeStyles } = useChatTheme();
|
|
13870
14606
|
const showDeleteMenu = isSender || hasAttachments || attachmentDeleteMode;
|
|
13871
|
-
const showDeleteForEveryone = isSender &&
|
|
14607
|
+
const showDeleteForEveryone = isSender && isWithinDeleteWindow;
|
|
13872
14608
|
return /* @__PURE__ */ jsxs(
|
|
13873
14609
|
"div",
|
|
13874
14610
|
{
|
|
@@ -14190,16 +14926,59 @@ function resolveForwardItems(selectedKeys, messages) {
|
|
|
14190
14926
|
}
|
|
14191
14927
|
|
|
14192
14928
|
// src/chat/lib/chat-edit-window.ts
|
|
14193
|
-
|
|
14194
|
-
|
|
14195
|
-
|
|
14929
|
+
init_settings_types();
|
|
14930
|
+
|
|
14931
|
+
// src/lib/effective-settings.helpers.ts
|
|
14932
|
+
function minutesToMs(minutes) {
|
|
14933
|
+
return Math.max(0, minutes) * 60 * 1e3;
|
|
14934
|
+
}
|
|
14935
|
+
function getEditWindowMs(timers, isGroup) {
|
|
14936
|
+
return minutesToMs(isGroup ? timers.groupEditMinutes : timers.dmEditMinutes);
|
|
14937
|
+
}
|
|
14938
|
+
function getDeleteWindowMs(timers, isGroup) {
|
|
14939
|
+
return minutesToMs(
|
|
14940
|
+
isGroup ? timers.groupDeleteMinutes : timers.dmDeleteMinutes
|
|
14941
|
+
);
|
|
14196
14942
|
}
|
|
14197
|
-
function
|
|
14943
|
+
function isWithinWindow(createdAt, windowMs) {
|
|
14198
14944
|
if (!createdAt) return false;
|
|
14199
14945
|
const date = new Date(createdAt);
|
|
14200
14946
|
if (isNaN(date.getTime())) return false;
|
|
14201
14947
|
const diff = Date.now() - date.getTime();
|
|
14202
|
-
return diff >= 0 && diff <
|
|
14948
|
+
return diff >= 0 && diff < windowMs;
|
|
14949
|
+
}
|
|
14950
|
+
function isWithinMessageEditWindow(createdAt, timers, isGroup) {
|
|
14951
|
+
return isWithinWindow(createdAt, getEditWindowMs(timers, isGroup));
|
|
14952
|
+
}
|
|
14953
|
+
function isWithinMessageDeleteWindow(createdAt, timers, isGroup) {
|
|
14954
|
+
return isWithinWindow(createdAt, getDeleteWindowMs(timers, isGroup));
|
|
14955
|
+
}
|
|
14956
|
+
function matchesAllowedMimeType(fileType, allowedMimeTypes) {
|
|
14957
|
+
const mime = (fileType || "application/octet-stream").toLowerCase();
|
|
14958
|
+
return allowedMimeTypes.some((pattern) => {
|
|
14959
|
+
const normalized = pattern.trim().toLowerCase();
|
|
14960
|
+
if (!normalized) return false;
|
|
14961
|
+
if (normalized.endsWith("/*")) {
|
|
14962
|
+
const prefix = normalized.slice(0, -1);
|
|
14963
|
+
return mime.startsWith(prefix);
|
|
14964
|
+
}
|
|
14965
|
+
return mime === normalized;
|
|
14966
|
+
});
|
|
14967
|
+
}
|
|
14968
|
+
function buildAcceptFromMimeTypes(allowedMimeTypes) {
|
|
14969
|
+
return allowedMimeTypes.map((type) => type.trim()).filter(Boolean).join(",");
|
|
14970
|
+
}
|
|
14971
|
+
function formatFileSizeMB(sizeBytes) {
|
|
14972
|
+
return `${(sizeBytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
14973
|
+
}
|
|
14974
|
+
|
|
14975
|
+
// src/chat/lib/chat-edit-window.ts
|
|
14976
|
+
var FALLBACK_TIMERS = DEFAULT_EFFECTIVE_SETTINGS.messageTimers;
|
|
14977
|
+
function isWithinMessageEditWindow2(createdAt, isGroup, timers = FALLBACK_TIMERS) {
|
|
14978
|
+
return isWithinMessageEditWindow(createdAt, timers, isGroup);
|
|
14979
|
+
}
|
|
14980
|
+
function isWithinMessageDeleteWindow2(createdAt, isGroup, timers = FALLBACK_TIMERS) {
|
|
14981
|
+
return isWithinMessageDeleteWindow(createdAt, timers, isGroup);
|
|
14203
14982
|
}
|
|
14204
14983
|
|
|
14205
14984
|
// src/chat/message-item/useMessageItemActions.ts
|
|
@@ -14277,6 +15056,9 @@ function useMessageItemActions({
|
|
|
14277
15056
|
const canUnpin = !isPinned || isPinnedByMe;
|
|
14278
15057
|
const { userPermissions } = useGroupInfo(conversationId || null);
|
|
14279
15058
|
const { formatMessageTime } = useChatLocale();
|
|
15059
|
+
const { settings } = useEffectiveSettingsOptional();
|
|
15060
|
+
const messageTimers = settings.messageTimers;
|
|
15061
|
+
const maxPinnedMessages = settings.maxPinnedMessagesPerConversation;
|
|
14280
15062
|
const visibleAttachments = getVisibleAttachments(attachments);
|
|
14281
15063
|
const hasAttachments = visibleAttachments.length > 0;
|
|
14282
15064
|
const hasMultiAttachments = hasAttachments && messageUsesAttachmentSelection({ attachments: visibleAttachments });
|
|
@@ -14293,7 +15075,8 @@ function useMessageItemActions({
|
|
|
14293
15075
|
const hasText = Boolean(message?.trim());
|
|
14294
15076
|
const isSelected = !!mid && !!selectedKeys && isMessageWhollySelected(selectedKeys, mid) && !hasMultiAttachments;
|
|
14295
15077
|
const canEdit = (!isGroup || userPermissions.canEditMessage) && hasText;
|
|
14296
|
-
const isWithinEditWindow = () =>
|
|
15078
|
+
const isWithinEditWindow = () => isWithinMessageEditWindow2(createdAt, isGroup, messageTimers);
|
|
15079
|
+
const isWithinDeleteWindow = () => isWithinMessageDeleteWindow2(createdAt, isGroup, messageTimers);
|
|
14297
15080
|
const canEditAttachmentCaption = isSender && isWithinEditWindow() && (!isGroup || userPermissions.canEditMessage) && !isDeletedForEveryone && !!mid;
|
|
14298
15081
|
const handleAttachmentCaptionClick = (attachment) => {
|
|
14299
15082
|
if (!canEditAttachmentCaption) return;
|
|
@@ -14462,6 +15245,15 @@ function useMessageItemActions({
|
|
|
14462
15245
|
});
|
|
14463
15246
|
}
|
|
14464
15247
|
} else {
|
|
15248
|
+
if (conversationId) {
|
|
15249
|
+
const pinnedCount = (pinnedMessagesByConversation[conversationId] || []).length || useStore.getState().liveConversationCounts[conversationId]?.pinnedCount || 0;
|
|
15250
|
+
if (pinnedCount >= maxPinnedMessages) {
|
|
15251
|
+
useStore.getState().handleAppError(
|
|
15252
|
+
`You can pin up to ${maxPinnedMessages} messages in this conversation.`
|
|
15253
|
+
);
|
|
15254
|
+
return;
|
|
15255
|
+
}
|
|
15256
|
+
}
|
|
14465
15257
|
if (isGroup) {
|
|
14466
15258
|
if (!conversationId) return;
|
|
14467
15259
|
emitGroupPin({
|
|
@@ -14520,6 +15312,7 @@ function useMessageItemActions({
|
|
|
14520
15312
|
canUnpin,
|
|
14521
15313
|
canEdit,
|
|
14522
15314
|
isWithinEditWindow,
|
|
15315
|
+
isWithinDeleteWindow,
|
|
14523
15316
|
canEditAttachmentCaption,
|
|
14524
15317
|
visibleAttachments,
|
|
14525
15318
|
hasAttachments,
|
|
@@ -14551,7 +15344,7 @@ function useMessageItemActions({
|
|
|
14551
15344
|
}
|
|
14552
15345
|
|
|
14553
15346
|
// src/chat/lib/reply-preview.ts
|
|
14554
|
-
function
|
|
15347
|
+
function normalizeAttachments2(replyTo, loggedUserId) {
|
|
14555
15348
|
const raw = replyTo?.attachments;
|
|
14556
15349
|
if (!Array.isArray(raw) || raw.length === 0) return [];
|
|
14557
15350
|
return raw.map((att, index) => {
|
|
@@ -14564,7 +15357,7 @@ function resolveReplyToMessage(replyTo, messagesById, loggedUserId) {
|
|
|
14564
15357
|
if (typeof replyTo === "object" && (replyTo.content?.trim() || replyTo.attachments?.length)) {
|
|
14565
15358
|
return {
|
|
14566
15359
|
...replyTo,
|
|
14567
|
-
attachments:
|
|
15360
|
+
attachments: normalizeAttachments2(replyTo, loggedUserId)
|
|
14568
15361
|
};
|
|
14569
15362
|
}
|
|
14570
15363
|
const replyId = String(
|
|
@@ -15001,6 +15794,7 @@ function MessageItemView(props) {
|
|
|
15001
15794
|
canUnpin,
|
|
15002
15795
|
canEdit,
|
|
15003
15796
|
isWithinEditWindow,
|
|
15797
|
+
isWithinDeleteWindow,
|
|
15004
15798
|
canEditAttachmentCaption,
|
|
15005
15799
|
visibleAttachments,
|
|
15006
15800
|
hasAttachments,
|
|
@@ -15092,6 +15886,7 @@ function MessageItemView(props) {
|
|
|
15092
15886
|
{
|
|
15093
15887
|
isSender,
|
|
15094
15888
|
isRecent: isWithinEditWindow(),
|
|
15889
|
+
isWithinDeleteWindow: isWithinDeleteWindow(),
|
|
15095
15890
|
messageId: mid,
|
|
15096
15891
|
isPinned,
|
|
15097
15892
|
isStarred,
|
|
@@ -15386,6 +16181,7 @@ function MessageSelectionBar({
|
|
|
15386
16181
|
}
|
|
15387
16182
|
|
|
15388
16183
|
// src/chat/active-channel-messages/utils.ts
|
|
16184
|
+
init_settings_types();
|
|
15389
16185
|
var getMessageSenderId2 = (msg) => msg ? String(msg.senderId || msg.sender?._id || "") : "";
|
|
15390
16186
|
var isLikelyObjectId = (value) => /^[a-f\d]{24}$/i.test(value);
|
|
15391
16187
|
function resolveGroupSenderDisplay(message, allUsers = [], participants = []) {
|
|
@@ -15417,7 +16213,7 @@ var isSameMessageSide = (a, b, isGroupChat) => {
|
|
|
15417
16213
|
const bId = getMessageSenderId2(b);
|
|
15418
16214
|
return aId !== "" && aId === bId;
|
|
15419
16215
|
};
|
|
15420
|
-
function canDeleteSelectionForEveryone(selectedKeys, messages, isGroup) {
|
|
16216
|
+
function canDeleteSelectionForEveryone(selectedKeys, messages, isGroup, timers = DEFAULT_EFFECTIVE_SETTINGS.messageTimers) {
|
|
15421
16217
|
if (selectedKeys.size === 0) return false;
|
|
15422
16218
|
const parsed = [...selectedKeys].map((key) => parseSelectionKey(key));
|
|
15423
16219
|
const messageIds = new Set(parsed.map((entry) => entry.messageId));
|
|
@@ -15425,7 +16221,7 @@ function canDeleteSelectionForEveryone(selectedKeys, messages, isGroup) {
|
|
|
15425
16221
|
const messageId2 = [...messageIds][0];
|
|
15426
16222
|
const message = messages.find((entry) => String(entry._id || entry.id) === messageId2);
|
|
15427
16223
|
if (!message?.isOwnMessage) return false;
|
|
15428
|
-
if (!
|
|
16224
|
+
if (!isWithinMessageDeleteWindow2(message.timestamp, isGroup, timers)) return false;
|
|
15429
16225
|
const hasAttachmentKey = parsed.some((entry) => entry.attachmentId);
|
|
15430
16226
|
if (!hasAttachmentKey) {
|
|
15431
16227
|
return selectedKeys.size === 1;
|
|
@@ -15594,6 +16390,8 @@ function useActiveChannelMessages({
|
|
|
15594
16390
|
const emitDmDelete = useStore((s) => s.emitDmDelete);
|
|
15595
16391
|
const emitGroupDelete = useStore((s) => s.emitGroupDelete);
|
|
15596
16392
|
const loggedUserDetails = useStore((s) => s.loggedUserDetails);
|
|
16393
|
+
const { settings } = useEffectiveSettingsOptional();
|
|
16394
|
+
const messageTimers = settings.messageTimers;
|
|
15597
16395
|
const scrollContainerRef = useRef(null);
|
|
15598
16396
|
const bottomRef = useRef(null);
|
|
15599
16397
|
const messageListInitializedRef = useRef(false);
|
|
@@ -15712,8 +16510,13 @@ function useActiveChannelMessages({
|
|
|
15712
16510
|
}, []);
|
|
15713
16511
|
const selectedForwardItems = resolveForwardItems(selectedKeys, displayMessages);
|
|
15714
16512
|
const canDeleteForEveryone = useMemo(
|
|
15715
|
-
() => canDeleteSelectionForEveryone(
|
|
15716
|
-
|
|
16513
|
+
() => canDeleteSelectionForEveryone(
|
|
16514
|
+
selectedKeys,
|
|
16515
|
+
displayMessages,
|
|
16516
|
+
!!activeChannel?.isGroup,
|
|
16517
|
+
messageTimers
|
|
16518
|
+
),
|
|
16519
|
+
[selectedKeys, displayMessages, activeChannel?.isGroup, messageTimers]
|
|
15717
16520
|
);
|
|
15718
16521
|
const emitSelectionDelete = useCallback(
|
|
15719
16522
|
(deleteType) => {
|
|
@@ -15721,7 +16524,8 @@ function useActiveChannelMessages({
|
|
|
15721
16524
|
if (deleteType === "everyone" && !canDeleteSelectionForEveryone(
|
|
15722
16525
|
selectedKeys,
|
|
15723
16526
|
displayMessages,
|
|
15724
|
-
!!activeChannel?.isGroup
|
|
16527
|
+
!!activeChannel?.isGroup,
|
|
16528
|
+
messageTimers
|
|
15725
16529
|
)) {
|
|
15726
16530
|
return;
|
|
15727
16531
|
}
|
|
@@ -15762,7 +16566,8 @@ function useActiveChannelMessages({
|
|
|
15762
16566
|
conversationId,
|
|
15763
16567
|
emitGroupDelete,
|
|
15764
16568
|
emitDmDelete,
|
|
15765
|
-
clearSelection
|
|
16569
|
+
clearSelection,
|
|
16570
|
+
messageTimers
|
|
15766
16571
|
]
|
|
15767
16572
|
);
|
|
15768
16573
|
const handleBatchDeleteForMe = useCallback(() => {
|
|
@@ -16100,8 +16905,8 @@ function CalendarDayButton({
|
|
|
16100
16905
|
...props
|
|
16101
16906
|
}) {
|
|
16102
16907
|
const defaultClassNames = getDefaultClassNames();
|
|
16103
|
-
const ref =
|
|
16104
|
-
|
|
16908
|
+
const ref = React3.useRef(null);
|
|
16909
|
+
React3.useEffect(() => {
|
|
16105
16910
|
if (modifiers.focused) ref.current?.focus();
|
|
16106
16911
|
}, [modifiers.focused]);
|
|
16107
16912
|
return /* @__PURE__ */ jsx(
|
|
@@ -17005,7 +17810,6 @@ var getAttachmentType = (file) => {
|
|
|
17005
17810
|
};
|
|
17006
17811
|
|
|
17007
17812
|
// src/chat/channel-message-box/useChannelMessageBox.ts
|
|
17008
|
-
var MAX_ATTACHMENTS = COMPOSER_MAX_ATTACHMENTS;
|
|
17009
17813
|
function useChannelMessageBox({
|
|
17010
17814
|
activeChannel,
|
|
17011
17815
|
conversationId,
|
|
@@ -17019,6 +17823,12 @@ function useChannelMessageBox({
|
|
|
17019
17823
|
conversationId,
|
|
17020
17824
|
onActiveChannelPatch
|
|
17021
17825
|
);
|
|
17826
|
+
const { settings, getAttachmentsGate } = useEffectiveSettingsOptional();
|
|
17827
|
+
const attachmentsGate = getAttachmentsGate();
|
|
17828
|
+
const maxAttachments = settings.attachments.maxAttachmentsPerMessage;
|
|
17829
|
+
const maxFileSizeBytes = settings.attachments.maxFileSizeMB * 1024 * 1024;
|
|
17830
|
+
const allowedMimeTypes = settings.attachments.allowedMimeTypes;
|
|
17831
|
+
const acceptAttribute = buildAcceptFromMimeTypes(allowedMimeTypes);
|
|
17022
17832
|
const [state, setState] = useState({
|
|
17023
17833
|
messageInput: "",
|
|
17024
17834
|
attachments: [],
|
|
@@ -17043,10 +17853,10 @@ function useChannelMessageBox({
|
|
|
17043
17853
|
const composerDisabledReason = conversationId ? composerDisabledByConversation[conversationId] : void 0;
|
|
17044
17854
|
const fileInputRef = useRef(null);
|
|
17045
17855
|
const attachmentsCountRef = useRef(0);
|
|
17046
|
-
|
|
17856
|
+
React3__default.useEffect(() => {
|
|
17047
17857
|
attachmentsCountRef.current = state.attachments.length;
|
|
17048
17858
|
}, [state.attachments.length]);
|
|
17049
|
-
|
|
17859
|
+
React3__default.useEffect(() => {
|
|
17050
17860
|
const draft = {
|
|
17051
17861
|
messageInput: state.messageInput,
|
|
17052
17862
|
attachments: state.attachments
|
|
@@ -17054,7 +17864,7 @@ function useChannelMessageBox({
|
|
|
17054
17864
|
syncComposerRef(draft);
|
|
17055
17865
|
updateConversationDraft(conversationIdRef.current, draft);
|
|
17056
17866
|
}, [state.messageInput, state.attachments, syncComposerRef]);
|
|
17057
|
-
|
|
17867
|
+
React3__default.useEffect(() => {
|
|
17058
17868
|
if (typingTimeoutRef.current) {
|
|
17059
17869
|
clearTimeout(typingTimeoutRef.current);
|
|
17060
17870
|
typingTimeoutRef.current = null;
|
|
@@ -17114,21 +17924,52 @@ function useChannelMessageBox({
|
|
|
17114
17924
|
const handleFileChange = (e) => {
|
|
17115
17925
|
const files = e.target.files ? Array.from(e.target.files) : [];
|
|
17116
17926
|
if (!files.length) return;
|
|
17927
|
+
if (!attachmentsGate.enabled) {
|
|
17928
|
+
updateState({
|
|
17929
|
+
attachmentError: attachmentsGate.disabledReason || "Attachments are disabled by your administrator."
|
|
17930
|
+
});
|
|
17931
|
+
if (fileInputRef.current) fileInputRef.current.value = "";
|
|
17932
|
+
return;
|
|
17933
|
+
}
|
|
17117
17934
|
const currentCount = attachmentsCountRef.current;
|
|
17118
|
-
const remaining =
|
|
17935
|
+
const remaining = maxAttachments - currentCount;
|
|
17119
17936
|
if (remaining <= 0) {
|
|
17120
|
-
updateState({ attachmentError: `Maximum ${
|
|
17937
|
+
updateState({ attachmentError: `Maximum ${maxAttachments} files allowed` });
|
|
17938
|
+
if (fileInputRef.current) fileInputRef.current.value = "";
|
|
17939
|
+
return;
|
|
17940
|
+
}
|
|
17941
|
+
const validFiles = [];
|
|
17942
|
+
const rejectionMessages = [];
|
|
17943
|
+
for (const file of files) {
|
|
17944
|
+
if (!matchesAllowedMimeType(file.type, allowedMimeTypes)) {
|
|
17945
|
+
rejectionMessages.push(`"${file.name}" type is not allowed`);
|
|
17946
|
+
continue;
|
|
17947
|
+
}
|
|
17948
|
+
if (file.size > maxFileSizeBytes) {
|
|
17949
|
+
rejectionMessages.push(
|
|
17950
|
+
`"${file.name}" exceeds ${settings.attachments.maxFileSizeMB} MB (got ${formatFileSizeMB(file.size)})`
|
|
17951
|
+
);
|
|
17952
|
+
continue;
|
|
17953
|
+
}
|
|
17954
|
+
validFiles.push(file);
|
|
17955
|
+
}
|
|
17956
|
+
if (validFiles.length === 0) {
|
|
17957
|
+
updateState({
|
|
17958
|
+
attachmentError: rejectionMessages[0] || "Selected files are not allowed"
|
|
17959
|
+
});
|
|
17121
17960
|
if (fileInputRef.current) fileInputRef.current.value = "";
|
|
17122
17961
|
return;
|
|
17123
17962
|
}
|
|
17124
|
-
if (
|
|
17963
|
+
if (validFiles.length > remaining) {
|
|
17125
17964
|
updateState({
|
|
17126
17965
|
attachmentError: `You can upload only ${remaining} more file${remaining > 1 ? "s" : ""}`
|
|
17127
17966
|
});
|
|
17967
|
+
} else if (rejectionMessages.length > 0) {
|
|
17968
|
+
updateState({ attachmentError: rejectionMessages[0] });
|
|
17128
17969
|
} else {
|
|
17129
17970
|
updateState({ attachmentError: "" });
|
|
17130
17971
|
}
|
|
17131
|
-
const filesToAdd =
|
|
17972
|
+
const filesToAdd = validFiles.slice(0, remaining);
|
|
17132
17973
|
attachmentsCountRef.current = currentCount + filesToAdd.length;
|
|
17133
17974
|
const newAttachments = filesToAdd.map((file) => ({
|
|
17134
17975
|
id: `att-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
|
|
@@ -17185,7 +18026,7 @@ function useChannelMessageBox({
|
|
|
17185
18026
|
return {
|
|
17186
18027
|
...prev,
|
|
17187
18028
|
attachments: nextAttachments,
|
|
17188
|
-
attachmentError: nextAttachments.length <
|
|
18029
|
+
attachmentError: nextAttachments.length < maxAttachments ? "" : prev.attachmentError
|
|
17189
18030
|
};
|
|
17190
18031
|
});
|
|
17191
18032
|
};
|
|
@@ -17292,7 +18133,10 @@ function useChannelMessageBox({
|
|
|
17292
18133
|
onlyAdminCanSendMessage,
|
|
17293
18134
|
fileInputRef,
|
|
17294
18135
|
hasUploadingAttachments,
|
|
17295
|
-
maxAttachments
|
|
18136
|
+
maxAttachments,
|
|
18137
|
+
acceptAttribute,
|
|
18138
|
+
attachmentsEnabled: attachmentsGate.enabled,
|
|
18139
|
+
attachmentsDisabledReason: attachmentsGate.disabledReason,
|
|
17296
18140
|
handleInputChange,
|
|
17297
18141
|
handleFileChange,
|
|
17298
18142
|
handleRemoveAttachment,
|
|
@@ -17320,6 +18164,9 @@ var ChannelMessageBoxView = (props) => {
|
|
|
17320
18164
|
fileInputRef,
|
|
17321
18165
|
hasUploadingAttachments,
|
|
17322
18166
|
maxAttachments,
|
|
18167
|
+
acceptAttribute,
|
|
18168
|
+
attachmentsEnabled,
|
|
18169
|
+
attachmentsDisabledReason,
|
|
17323
18170
|
handleInputChange,
|
|
17324
18171
|
handleFileChange,
|
|
17325
18172
|
handleRemoveAttachment,
|
|
@@ -17417,16 +18264,23 @@ var ChannelMessageBoxView = (props) => {
|
|
|
17417
18264
|
),
|
|
17418
18265
|
/* @__PURE__ */ jsxs("div", { className: "flex items-end gap-1.5 p-1.5", children: [
|
|
17419
18266
|
/* @__PURE__ */ jsx(
|
|
17420
|
-
|
|
18267
|
+
AdminPermissionTooltip,
|
|
17421
18268
|
{
|
|
17422
|
-
|
|
17423
|
-
|
|
17424
|
-
|
|
17425
|
-
|
|
17426
|
-
|
|
17427
|
-
|
|
17428
|
-
|
|
17429
|
-
|
|
18269
|
+
disabled: !attachmentsEnabled,
|
|
18270
|
+
message: attachmentsDisabledReason,
|
|
18271
|
+
children: /* @__PURE__ */ jsx(
|
|
18272
|
+
Button,
|
|
18273
|
+
{
|
|
18274
|
+
type: "button",
|
|
18275
|
+
variant: "ghost",
|
|
18276
|
+
size: "icon",
|
|
18277
|
+
className: "shrink-0 size-9 rounded-xl text-(--chat-muted) transition-all hover:bg-(--chat-hover) hover:text-(--chat-text) disabled:opacity-40",
|
|
18278
|
+
onClick: () => attachmentsEnabled && !hasUploadingAttachments && fileInputRef.current?.click(),
|
|
18279
|
+
disabled: !attachmentsEnabled || hasUploadingAttachments,
|
|
18280
|
+
"aria-label": "Attach files",
|
|
18281
|
+
children: /* @__PURE__ */ jsx(Paperclip, { size: 16 })
|
|
18282
|
+
}
|
|
18283
|
+
)
|
|
17430
18284
|
}
|
|
17431
18285
|
),
|
|
17432
18286
|
/* @__PURE__ */ jsx(
|
|
@@ -17436,8 +18290,9 @@ var ChannelMessageBoxView = (props) => {
|
|
|
17436
18290
|
ref: fileInputRef,
|
|
17437
18291
|
className: "hidden",
|
|
17438
18292
|
multiple: true,
|
|
17439
|
-
accept:
|
|
17440
|
-
onChange: handleFileChange
|
|
18293
|
+
accept: acceptAttribute || void 0,
|
|
18294
|
+
onChange: handleFileChange,
|
|
18295
|
+
disabled: !attachmentsEnabled
|
|
17441
18296
|
}
|
|
17442
18297
|
),
|
|
17443
18298
|
/* @__PURE__ */ jsxs(Popover, { children: [
|
|
@@ -18325,6 +19180,7 @@ var ChatMain = ({
|
|
|
18325
19180
|
queryParams,
|
|
18326
19181
|
queryParamApis,
|
|
18327
19182
|
queryParamsByApi,
|
|
19183
|
+
apiVersions: apiVersions2,
|
|
18328
19184
|
themeColor = "#7494ec",
|
|
18329
19185
|
theme,
|
|
18330
19186
|
uiConfig,
|
|
@@ -18351,8 +19207,8 @@ var ChatMain = ({
|
|
|
18351
19207
|
viewportHeight = "full",
|
|
18352
19208
|
viewportClassName
|
|
18353
19209
|
}) => {
|
|
18354
|
-
const clientObj =
|
|
18355
|
-
const uiConfigObj =
|
|
19210
|
+
const clientObj = React3__default.useMemo(() => ({ id: clientId }), [clientId]);
|
|
19211
|
+
const uiConfigObj = React3__default.useMemo(
|
|
18356
19212
|
() => ({
|
|
18357
19213
|
...uiConfig || {},
|
|
18358
19214
|
components: { ...uiConfig?.components, ...components },
|
|
@@ -18394,6 +19250,7 @@ var ChatMain = ({
|
|
|
18394
19250
|
queryParams,
|
|
18395
19251
|
queryParamApis,
|
|
18396
19252
|
queryParamsByApi,
|
|
19253
|
+
apiVersions: apiVersions2,
|
|
18397
19254
|
children: [
|
|
18398
19255
|
/* @__PURE__ */ jsx(ForegroundPushBridge, {}),
|
|
18399
19256
|
/* @__PURE__ */ jsx(
|
|
@@ -18686,6 +19543,10 @@ var ChannelListItem_default = ChannelListItem2;
|
|
|
18686
19543
|
var packageDefaultComponents = {
|
|
18687
19544
|
ChatLayout: DefaultChatLayout_default,
|
|
18688
19545
|
LoggedUserDetails: LoggedUserDetails_default,
|
|
19546
|
+
LoggedUserSettingsDialog: LoggedUserSettingsDialog_default,
|
|
19547
|
+
LoggedUserSettingsTrigger: LoggedUserSettingsTrigger_default,
|
|
19548
|
+
LoggedUserSettingsContent: LoggedUserSettingsContent_default,
|
|
19549
|
+
PushNotificationToggle,
|
|
18689
19550
|
ChannelList: ChannelListView_default,
|
|
18690
19551
|
ChannelListItem: DefaultChannelListItem,
|
|
18691
19552
|
ChannelHeader: ChannelHeaderView_default,
|
|
@@ -18718,8 +19579,10 @@ var packageDefaultComponents = {
|
|
|
18718
19579
|
};
|
|
18719
19580
|
|
|
18720
19581
|
// src/index.ts
|
|
19582
|
+
init_settings_types();
|
|
19583
|
+
init_api_service();
|
|
18721
19584
|
var index_default = ChatMain_default;
|
|
18722
19585
|
|
|
18723
|
-
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, PUSH_DATA_CACHE_NAME, PushNotificationToggle, apiGetPushConfig, apiGetPushPreference, apiRegisterPushToken, apiRemovePushToken, apiUpdatePushPreference, buildChannelFromPushRequest, capitalizeFirst, clampJumpDate, consumePendingOpenConversation, consumePendingOpenFromPushCache, 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 };
|
|
19586
|
+
export { ADMIN_PERMISSION_DENIED_MESSAGE, CALLS_NOT_CONFIGURED_MESSAGE, 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, ChatEffectiveSettingsProvider, ChatLayout_default as ChatLayout, ChatLocaleProvider, ChatMain_default as ChatMain, ChatThemeProvider, ChatViewport, DEFAULT_EFFECTIVE_SETTINGS, 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, fetchEffectiveSettings, 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, useEffectiveSettings, useEffectiveSettingsOptional, usePushNotifications };
|
|
18724
19587
|
//# sourceMappingURL=index.mjs.map
|
|
18725
19588
|
//# sourceMappingURL=index.mjs.map
|