@natoe/colab 0.1.1 → 0.1.2

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
@@ -1,4 +1,4 @@
1
- import { createContext, forwardRef, useRef, useImperativeHandle, useEffect, useCallback, useState, useContext, useMemo } from 'react';
1
+ import React4, { createContext, forwardRef, useRef, useImperativeHandle, useEffect, useCallback, useState, useContext, useMemo } from 'react';
2
2
  import { Socket, Presence } from 'phoenix';
3
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
4
 
@@ -1755,6 +1755,82 @@ var styles5 = {
1755
1755
  color: "#d1d5db"
1756
1756
  }
1757
1757
  };
1758
+
1759
+ // src/core/dateLabels.ts
1760
+ var SHORT_MONTHS = [
1761
+ "Jan",
1762
+ "Feb",
1763
+ "Mar",
1764
+ "Apr",
1765
+ "May",
1766
+ "Jun",
1767
+ "Jul",
1768
+ "Aug",
1769
+ "Sep",
1770
+ "Oct",
1771
+ "Nov",
1772
+ "Dec"
1773
+ ];
1774
+ var LONG_WEEKDAYS = [
1775
+ "Sunday",
1776
+ "Monday",
1777
+ "Tuesday",
1778
+ "Wednesday",
1779
+ "Thursday",
1780
+ "Friday",
1781
+ "Saturday"
1782
+ ];
1783
+ var ONE_DAY_MS = 864e5;
1784
+ function parseSafe(iso) {
1785
+ const d = new Date(iso);
1786
+ return Number.isNaN(d.getTime()) ? null : d;
1787
+ }
1788
+ function startOfDay(d) {
1789
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate());
1790
+ }
1791
+ function daysBetween(a, b) {
1792
+ return Math.floor((startOfDay(a).getTime() - startOfDay(b).getTime()) / ONE_DAY_MS);
1793
+ }
1794
+ function formatFullDate(d) {
1795
+ return `${d.getDate()} ${SHORT_MONTHS[d.getMonth()]} ${d.getFullYear()}`;
1796
+ }
1797
+ function formatLocaleTime(d) {
1798
+ try {
1799
+ return d.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" });
1800
+ } catch {
1801
+ const h = d.getHours();
1802
+ const m = d.getMinutes().toString().padStart(2, "0");
1803
+ const suffix = h >= 12 ? "PM" : "AM";
1804
+ const h12 = (h + 11) % 12 + 1;
1805
+ return `${h12}:${m} ${suffix}`;
1806
+ }
1807
+ }
1808
+ function formatInboxTimestamp(iso) {
1809
+ if (!iso) return "";
1810
+ const d = parseSafe(iso);
1811
+ if (!d) return "";
1812
+ const diffDays = daysBetween(/* @__PURE__ */ new Date(), d);
1813
+ if (diffDays === 0) return formatLocaleTime(d);
1814
+ if (diffDays === 1) return "Yesterday";
1815
+ if (diffDays > 1 && diffDays < 7) return LONG_WEEKDAYS[d.getDay()];
1816
+ return formatFullDate(d);
1817
+ }
1818
+ function formatDayDivider(iso) {
1819
+ if (!iso) return "";
1820
+ const d = parseSafe(iso);
1821
+ if (!d) return "";
1822
+ const diffDays = daysBetween(/* @__PURE__ */ new Date(), d);
1823
+ if (diffDays === 0) return "Today";
1824
+ if (diffDays === 1) return "Yesterday";
1825
+ if (diffDays > 1 && diffDays < 7) return LONG_WEEKDAYS[d.getDay()];
1826
+ return formatFullDate(d);
1827
+ }
1828
+ function dayBucketKey(iso) {
1829
+ if (!iso) return "";
1830
+ const d = parseSafe(iso);
1831
+ if (!d) return "";
1832
+ return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
1833
+ }
1758
1834
  var MessageList = forwardRef(function MessageList2({
1759
1835
  messages,
1760
1836
  currentUserId,
@@ -1840,22 +1916,30 @@ var MessageList = forwardRef(function MessageList2({
1840
1916
  /* @__PURE__ */ jsx("p", { style: styles6.emptyTitle, children: "No messages yet" }),
1841
1917
  /* @__PURE__ */ jsx("p", { style: styles6.emptySubtitle, children: "Start the conversation about this study" })
1842
1918
  ] }),
1843
- messages.map((message) => /* @__PURE__ */ jsx("div", { "data-message-id": message.id, children: /* @__PURE__ */ jsx(
1844
- MessageBubble,
1845
- {
1846
- message,
1847
- isOwn: message.senderId === currentUserId,
1848
- participants,
1849
- currentUserId,
1850
- showSeenBy,
1851
- onDeepLinkClick,
1852
- onReply,
1853
- onPin,
1854
- onUnpin,
1855
- onCopy,
1856
- pinDisabled
1857
- }
1858
- ) }, message.id)),
1919
+ messages.map((message, index) => {
1920
+ const currentBucket = dayBucketKey(message.insertedAt);
1921
+ const prevBucket = index === 0 ? null : dayBucketKey(messages[index - 1].insertedAt);
1922
+ const showDivider = currentBucket && currentBucket !== prevBucket;
1923
+ return /* @__PURE__ */ jsxs(React4.Fragment, { children: [
1924
+ showDivider && /* @__PURE__ */ jsx("div", { style: styles6.dayDivider, role: "separator", "aria-label": "Date", children: /* @__PURE__ */ jsx("span", { style: styles6.dayDividerPill, children: formatDayDivider(message.insertedAt) }) }),
1925
+ /* @__PURE__ */ jsx("div", { "data-message-id": message.id, children: /* @__PURE__ */ jsx(
1926
+ MessageBubble,
1927
+ {
1928
+ message,
1929
+ isOwn: message.senderId === currentUserId,
1930
+ participants,
1931
+ currentUserId,
1932
+ showSeenBy,
1933
+ onDeepLinkClick,
1934
+ onReply,
1935
+ onPin,
1936
+ onUnpin,
1937
+ onCopy,
1938
+ pinDisabled
1939
+ }
1940
+ ) })
1941
+ ] }, message.id);
1942
+ }),
1859
1943
  typingUsers.length > 0 && /* @__PURE__ */ jsxs("div", { style: styles6.typingIndicator, children: [
1860
1944
  typingUsers.map((t) => t.userName ?? "Someone").join(", "),
1861
1945
  typingUsers.length === 1 ? " is " : " are ",
@@ -1917,6 +2001,22 @@ var styles6 = {
1917
2001
  fontSize: "12px",
1918
2002
  color: "#9ca3af",
1919
2003
  fontStyle: "italic"
2004
+ },
2005
+ dayDivider: {
2006
+ display: "flex",
2007
+ justifyContent: "center",
2008
+ margin: "12px 0 8px"
2009
+ },
2010
+ dayDividerPill: {
2011
+ display: "inline-block",
2012
+ padding: "4px 12px",
2013
+ fontSize: "12px",
2014
+ fontWeight: 500,
2015
+ color: "#475569",
2016
+ backgroundColor: "#f1f5f9",
2017
+ border: "1px solid #e2e8f0",
2018
+ borderRadius: "12px",
2019
+ letterSpacing: "0.2px"
1920
2020
  }
1921
2021
  };
1922
2022
  function ReplyPreview({ message, onCancel, className }) {
@@ -3901,7 +4001,7 @@ function ConversationListItem({
3901
4001
  ...styles14.time,
3902
4002
  ...hasUnread ? styles14.timeUnread : {}
3903
4003
  },
3904
- children: formatRelativeTime(item.lastActivityAt)
4004
+ children: formatInboxTimestamp(item.lastActivityAt)
3905
4005
  }
3906
4006
  )
3907
4007
  ] }),
@@ -3944,23 +4044,6 @@ function renderLastMessagePreview(message) {
3944
4044
  }
3945
4045
  }
3946
4046
  }
3947
- function formatRelativeTime(iso) {
3948
- try {
3949
- const date = new Date(iso);
3950
- const now = /* @__PURE__ */ new Date();
3951
- const diffMs = now.getTime() - date.getTime();
3952
- const diffMin = Math.floor(diffMs / 6e4);
3953
- const diffHr = Math.floor(diffMs / 36e5);
3954
- const diffDay = Math.floor(diffMs / 864e5);
3955
- if (diffMin < 1) return "now";
3956
- if (diffMin < 60) return `${diffMin}m`;
3957
- if (diffHr < 24) return `${diffHr}h`;
3958
- if (diffDay < 7) return `${diffDay}d`;
3959
- return date.toLocaleDateString([], { month: "short", day: "numeric" });
3960
- } catch {
3961
- return "";
3962
- }
3963
- }
3964
4047
  var styles14 = {
3965
4048
  container: {
3966
4049
  display: "flex",