@realtimexsco/live-chat 1.4.14 → 1.4.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -12894,9 +12894,91 @@ init_useStore();
12894
12894
 
12895
12895
  // src/hooks/useGroupInfo.ts
12896
12896
  init_useStore();
12897
+
12898
+ // src/lib/effective-settings.helpers.ts
12899
+ function minutesToMs(minutes) {
12900
+ return Math.max(0, minutes) * 60 * 1e3;
12901
+ }
12902
+ function getEditWindowMs(timers, isGroup) {
12903
+ return minutesToMs(isGroup ? timers.groupEditMinutes : timers.dmEditMinutes);
12904
+ }
12905
+ function getDeleteWindowMs(timers, isGroup) {
12906
+ return minutesToMs(
12907
+ isGroup ? timers.groupDeleteMinutes : timers.dmDeleteMinutes
12908
+ );
12909
+ }
12910
+ function isWithinWindow(createdAt, windowMs) {
12911
+ if (!createdAt) return false;
12912
+ const date = new Date(createdAt);
12913
+ if (isNaN(date.getTime())) return false;
12914
+ const diff = Date.now() - date.getTime();
12915
+ return diff >= 0 && diff < windowMs;
12916
+ }
12917
+ function isWithinMessageEditWindow(createdAt, timers, isGroup) {
12918
+ return isWithinWindow(createdAt, getEditWindowMs(timers, isGroup));
12919
+ }
12920
+ function isWithinMessageDeleteWindow(createdAt, timers, isGroup) {
12921
+ return isWithinWindow(createdAt, getDeleteWindowMs(timers, isGroup));
12922
+ }
12923
+ function allowsAllMimeTypes(allowedMimeTypes) {
12924
+ return allowedMimeTypes.some((pattern) => {
12925
+ const normalized = pattern.trim().toLowerCase();
12926
+ return normalized === "*" || normalized === "*/*";
12927
+ });
12928
+ }
12929
+ function matchesAllowedMimeType(fileType, allowedMimeTypes) {
12930
+ if (!allowedMimeTypes.length) return false;
12931
+ if (allowsAllMimeTypes(allowedMimeTypes)) return true;
12932
+ const mime = (fileType || "application/octet-stream").toLowerCase();
12933
+ return allowedMimeTypes.some((pattern) => {
12934
+ const normalized = pattern.trim().toLowerCase();
12935
+ if (!normalized) return false;
12936
+ if (normalized.endsWith("/*")) {
12937
+ const prefix = normalized.slice(0, -1);
12938
+ return mime.startsWith(prefix);
12939
+ }
12940
+ return mime === normalized;
12941
+ });
12942
+ }
12943
+ function buildAcceptFromMimeTypes(allowedMimeTypes) {
12944
+ if (allowsAllMimeTypes(allowedMimeTypes)) return "";
12945
+ return allowedMimeTypes.map((type) => type.trim()).filter(Boolean).join(",");
12946
+ }
12947
+ function formatFileSizeMB(sizeBytes) {
12948
+ return `${(sizeBytes / (1024 * 1024)).toFixed(1)} MB`;
12949
+ }
12950
+ var GROUP_PERMISSION_KEYS = [
12951
+ "onlyAdminCanSendMessage",
12952
+ "onlyAdminCanEditInfo",
12953
+ "senderCanEditMessage",
12954
+ "allowMemberAdd",
12955
+ "allowMemberRemove",
12956
+ "moderationEnabled"
12957
+ ];
12958
+ function resolveGroupPermissions(conversationPermissions, defaults, locked = []) {
12959
+ const next = { ...defaults };
12960
+ if (conversationPermissions) {
12961
+ for (const key of GROUP_PERMISSION_KEYS) {
12962
+ const value = conversationPermissions[key];
12963
+ if (typeof value === "boolean") {
12964
+ next[key] = value;
12965
+ }
12966
+ }
12967
+ }
12968
+ for (const key of locked) {
12969
+ if (GROUP_PERMISSION_KEYS.includes(String(key))) {
12970
+ const typedKey = key;
12971
+ next[typedKey] = defaults[typedKey];
12972
+ }
12973
+ }
12974
+ return next;
12975
+ }
12976
+
12977
+ // src/hooks/useGroupInfo.ts
12897
12978
  var useGroupInfo = (conversationId) => {
12898
12979
  const conversationInfos = useStore((s) => s.conversationInfos);
12899
12980
  const loggedUserDetails = useStore((s) => s.loggedUserDetails);
12981
+ const { settings } = useEffectiveSettingsOptional();
12900
12982
  const info = conversationId ? conversationInfos[conversationId] : null;
12901
12983
  const isAdmin = useMemo(() => {
12902
12984
  if (!info || !loggedUserDetails) return false;
@@ -12912,7 +12994,14 @@ var useGroupInfo = (conversationId) => {
12912
12994
  }
12913
12995
  return String(ownerId) === String(loggedUserDetails._id);
12914
12996
  }, [info, loggedUserDetails]);
12915
- const permissions = info?.groupPermissions || null;
12997
+ const permissions = useMemo(() => {
12998
+ if (!info) return null;
12999
+ return resolveGroupPermissions(
13000
+ info.groupPermissions,
13001
+ settings.groupPolicy.defaults,
13002
+ settings.groupPolicy.locked
13003
+ );
13004
+ }, [info, settings.groupPolicy.defaults, settings.groupPolicy.locked]);
12916
13005
  const userPermissions = useMemo(() => {
12917
13006
  return {
12918
13007
  canSendMessage: isOwner || isAdmin || !permissions?.onlyAdminCanSendMessage,
@@ -12920,7 +13009,6 @@ var useGroupInfo = (conversationId) => {
12920
13009
  canAddMember: isOwner || !!permissions?.allowMemberAdd,
12921
13010
  canRemoveMember: isOwner || !!permissions?.allowMemberRemove,
12922
13011
  canEditMessage: isOwner || isAdmin || !!permissions?.senderCanEditMessage
12923
- // You can add more derived permissions here as needed
12924
13012
  };
12925
13013
  }, [isOwner, isAdmin, permissions]);
12926
13014
  return {
@@ -13347,14 +13435,20 @@ var PermissionDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo
13347
13435
  const [permissions, setPermissions] = useState(null);
13348
13436
  const [isSaving, setIsSaving] = useState(false);
13349
13437
  useEffect(() => {
13350
- if (conversationInfo?.groupPermissions) {
13351
- setPermissions(conversationInfo.groupPermissions);
13352
- return;
13353
- }
13354
- if (isOpen) {
13355
- setPermissions({ ...settings.groupPolicy.defaults });
13356
- }
13357
- }, [conversationInfo, isOpen, settings.groupPolicy.defaults]);
13438
+ if (!isOpen) return;
13439
+ setPermissions(
13440
+ resolveGroupPermissions(
13441
+ conversationInfo?.groupPermissions,
13442
+ settings.groupPolicy.defaults,
13443
+ settings.groupPolicy.locked
13444
+ )
13445
+ );
13446
+ }, [
13447
+ isOpen,
13448
+ conversationInfo?.groupPermissions,
13449
+ settings.groupPolicy.defaults,
13450
+ settings.groupPolicy.locked
13451
+ ]);
13358
13452
  if (!conversationId || !permissions) return null;
13359
13453
  const handleToggle = (key) => {
13360
13454
  if (isGroupPermissionLocked(key)) return;
@@ -13364,7 +13458,12 @@ var PermissionDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo
13364
13458
  if (!conversationId || !permissions) return;
13365
13459
  setIsSaving(true);
13366
13460
  try {
13367
- await updateGroupPermissions(conversationId, permissions);
13461
+ const payload = resolveGroupPermissions(
13462
+ permissions,
13463
+ settings.groupPolicy.defaults,
13464
+ settings.groupPolicy.locked
13465
+ );
13466
+ await updateGroupPermissions(conversationId, payload);
13368
13467
  onOpenChange(false);
13369
13468
  } finally {
13370
13469
  setIsSaving(false);
@@ -13391,6 +13490,7 @@ var PermissionDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo
13391
13490
  /* @__PURE__ */ jsx("h3", { className: "mb-1 px-0.5 text-[10px] font-semibold uppercase tracking-wide text-(--chat-muted)", children: "Permissions" }),
13392
13491
  /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-(--chat-border) px-3", children: permissionItems.map((item, index) => {
13393
13492
  const locked = isGroupPermissionLocked(item.key);
13493
+ const checked = item.inverted ? !permissions[item.key] : permissions[item.key];
13394
13494
  return /* @__PURE__ */ jsxs(
13395
13495
  "div",
13396
13496
  {
@@ -13415,7 +13515,7 @@ var PermissionDrawer = ({ isOpen, onOpenChange, conversationId, conversationInfo
13415
13515
  size: "sm",
13416
13516
  className: "mt-0.5 shrink-0 data-[state=checked]:bg-(--chat-theme) data-[state=unchecked]:bg-(--chat-border)",
13417
13517
  disabled: locked,
13418
- checked: item.inverted ? !permissions[item.key] : permissions[item.key],
13518
+ checked,
13419
13519
  onCheckedChange: () => handleToggle(item.key)
13420
13520
  }
13421
13521
  )
@@ -14959,61 +15059,6 @@ function resolveForwardItems(selectedKeys, messages) {
14959
15059
 
14960
15060
  // src/chat/lib/chat-edit-window.ts
14961
15061
  init_settings_types();
14962
-
14963
- // src/lib/effective-settings.helpers.ts
14964
- function minutesToMs(minutes) {
14965
- return Math.max(0, minutes) * 60 * 1e3;
14966
- }
14967
- function getEditWindowMs(timers, isGroup) {
14968
- return minutesToMs(isGroup ? timers.groupEditMinutes : timers.dmEditMinutes);
14969
- }
14970
- function getDeleteWindowMs(timers, isGroup) {
14971
- return minutesToMs(
14972
- isGroup ? timers.groupDeleteMinutes : timers.dmDeleteMinutes
14973
- );
14974
- }
14975
- function isWithinWindow(createdAt, windowMs) {
14976
- if (!createdAt) return false;
14977
- const date = new Date(createdAt);
14978
- if (isNaN(date.getTime())) return false;
14979
- const diff = Date.now() - date.getTime();
14980
- return diff >= 0 && diff < windowMs;
14981
- }
14982
- function isWithinMessageEditWindow(createdAt, timers, isGroup) {
14983
- return isWithinWindow(createdAt, getEditWindowMs(timers, isGroup));
14984
- }
14985
- function isWithinMessageDeleteWindow(createdAt, timers, isGroup) {
14986
- return isWithinWindow(createdAt, getDeleteWindowMs(timers, isGroup));
14987
- }
14988
- function allowsAllMimeTypes(allowedMimeTypes) {
14989
- return allowedMimeTypes.some((pattern) => {
14990
- const normalized = pattern.trim().toLowerCase();
14991
- return normalized === "*" || normalized === "*/*";
14992
- });
14993
- }
14994
- function matchesAllowedMimeType(fileType, allowedMimeTypes) {
14995
- if (!allowedMimeTypes.length) return false;
14996
- if (allowsAllMimeTypes(allowedMimeTypes)) return true;
14997
- const mime = (fileType || "application/octet-stream").toLowerCase();
14998
- return allowedMimeTypes.some((pattern) => {
14999
- const normalized = pattern.trim().toLowerCase();
15000
- if (!normalized) return false;
15001
- if (normalized.endsWith("/*")) {
15002
- const prefix = normalized.slice(0, -1);
15003
- return mime.startsWith(prefix);
15004
- }
15005
- return mime === normalized;
15006
- });
15007
- }
15008
- function buildAcceptFromMimeTypes(allowedMimeTypes) {
15009
- if (allowsAllMimeTypes(allowedMimeTypes)) return "";
15010
- return allowedMimeTypes.map((type) => type.trim()).filter(Boolean).join(",");
15011
- }
15012
- function formatFileSizeMB(sizeBytes) {
15013
- return `${(sizeBytes / (1024 * 1024)).toFixed(1)} MB`;
15014
- }
15015
-
15016
- // src/chat/lib/chat-edit-window.ts
15017
15062
  var FALLBACK_TIMERS = DEFAULT_EFFECTIVE_SETTINGS.messageTimers;
15018
15063
  function isWithinMessageEditWindow2(createdAt, isGroup, timers = FALLBACK_TIMERS) {
15019
15064
  return isWithinMessageEditWindow(createdAt, timers, isGroup);