ugly-app 0.1.333 → 0.1.335
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/cli/version.d.ts +1 -1
- package/dist/cli/version.js +1 -1
- package/dist/conversation/client/ChatContext.d.ts +23 -0
- package/dist/conversation/client/ChatContext.d.ts.map +1 -0
- package/dist/conversation/client/ChatContext.js +9 -0
- package/dist/conversation/client/ChatContext.js.map +1 -0
- package/dist/conversation/client/ChatMarkdownContent.d.ts +7 -0
- package/dist/conversation/client/ChatMarkdownContent.d.ts.map +1 -0
- package/dist/conversation/client/ChatMarkdownContent.js +6 -0
- package/dist/conversation/client/ChatMarkdownContent.js.map +1 -0
- package/dist/conversation/client/ChatMarkdownInput.d.ts +8 -0
- package/dist/conversation/client/ChatMarkdownInput.d.ts.map +1 -0
- package/dist/conversation/client/ChatMarkdownInput.js +23 -0
- package/dist/conversation/client/ChatMarkdownInput.js.map +1 -0
- package/dist/conversation/client/ChatMessageBubble.d.ts +7 -0
- package/dist/conversation/client/ChatMessageBubble.d.ts.map +1 -0
- package/dist/conversation/client/ChatMessageBubble.js +93 -0
- package/dist/conversation/client/ChatMessageBubble.js.map +1 -0
- package/dist/conversation/client/ChatScrollButton.d.ts +6 -0
- package/dist/conversation/client/ChatScrollButton.d.ts.map +1 -0
- package/dist/conversation/client/ChatScrollButton.js +35 -0
- package/dist/conversation/client/ChatScrollButton.js.map +1 -0
- package/dist/conversation/client/ChatTextContent.d.ts +5 -0
- package/dist/conversation/client/ChatTextContent.d.ts.map +1 -0
- package/dist/conversation/client/ChatTextContent.js +9 -0
- package/dist/conversation/client/ChatTextContent.js.map +1 -0
- package/dist/conversation/client/ChatTextInput.d.ts +7 -0
- package/dist/conversation/client/ChatTextInput.d.ts.map +1 -0
- package/dist/conversation/client/ChatTextInput.js +39 -0
- package/dist/conversation/client/ChatTextInput.js.map +1 -0
- package/dist/conversation/client/ChatTypingIndicator.d.ts +2 -0
- package/dist/conversation/client/ChatTypingIndicator.d.ts.map +1 -0
- package/dist/conversation/client/ChatTypingIndicator.js +45 -0
- package/dist/conversation/client/ChatTypingIndicator.js.map +1 -0
- package/dist/conversation/client/ChatView.d.ts +21 -0
- package/dist/conversation/client/ChatView.d.ts.map +1 -0
- package/dist/conversation/client/ChatView.js +154 -0
- package/dist/conversation/client/ChatView.js.map +1 -0
- package/dist/conversation/client/index.d.ts +18 -0
- package/dist/conversation/client/index.d.ts.map +1 -0
- package/dist/conversation/client/index.js +10 -0
- package/dist/conversation/client/index.js.map +1 -0
- package/dist/conversation/shared/index.d.ts +3 -0
- package/dist/conversation/shared/index.d.ts.map +1 -0
- package/dist/conversation/shared/index.js +2 -0
- package/dist/conversation/shared/index.js.map +1 -0
- package/dist/conversation/shared/types.d.ts +91 -0
- package/dist/conversation/shared/types.d.ts.map +1 -0
- package/dist/conversation/shared/types.js +30 -0
- package/dist/conversation/shared/types.js.map +1 -0
- package/dist/markdown/client/MarkdownTheme.css +907 -0
- package/dist/markdown/client/ProseMirrorEditor/schema.d.ts +6 -6
- package/dist/markdown/client/ui.module.css +1475 -0
- package/package.json +4 -2
- package/src/cli/version.ts +1 -1
- package/src/conversation/client/ChatContext.ts +36 -0
- package/src/conversation/client/ChatMarkdownContent.tsx +21 -0
- package/src/conversation/client/ChatMarkdownInput.tsx +55 -0
- package/src/conversation/client/ChatMessageBubble.tsx +145 -0
- package/src/conversation/client/ChatScrollButton.tsx +50 -0
- package/src/conversation/client/ChatTextContent.tsx +14 -0
- package/src/conversation/client/ChatTextInput.tsx +66 -0
- package/src/conversation/client/ChatTypingIndicator.tsx +62 -0
- package/src/conversation/client/ChatView.tsx +262 -0
- package/src/conversation/client/index.ts +25 -0
- package/src/conversation/shared/index.ts +20 -0
- package/src/conversation/shared/types.ts +160 -0
- package/templates/client/pages/ChatDemoPage.tsx +225 -0
package/dist/cli/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CLI_VERSION = "0.1.
|
|
1
|
+
export declare const CLI_VERSION = "0.1.335";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/cli/version.js
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { ChatMessage, ChatMessageAction, ChatReaction, ChatTypingEntry, ChatUser } from '../shared/types.js';
|
|
3
|
+
export interface ChatContextValue {
|
|
4
|
+
messages: ChatMessage[];
|
|
5
|
+
userId: string;
|
|
6
|
+
onSend: (text: string, parentMessageId?: string | null) => void;
|
|
7
|
+
onDelete?: (messageId: string) => void;
|
|
8
|
+
onEdit?: (messageId: string, text: string) => void;
|
|
9
|
+
onReact?: (messageId: string, reaction: ChatReaction) => void;
|
|
10
|
+
typingEntries?: ChatTypingEntry[];
|
|
11
|
+
onTypingStart?: () => void;
|
|
12
|
+
getUser?: (userId: string) => ChatUser | null;
|
|
13
|
+
hasMore?: boolean;
|
|
14
|
+
onLoadMore?: () => void;
|
|
15
|
+
renderContent?: (message: ChatMessage, width: number) => ReactNode;
|
|
16
|
+
renderMessage?: (message: ChatMessage, defaultRender: () => ReactNode) => ReactNode;
|
|
17
|
+
getMessageActions?: (message: ChatMessage) => ChatMessageAction[];
|
|
18
|
+
selectedMessageId: string | null;
|
|
19
|
+
setSelectedMessageId: (id: string | null) => void;
|
|
20
|
+
}
|
|
21
|
+
export declare const ChatContext: import("react").Context<ChatContextValue | null>;
|
|
22
|
+
export declare function useChatContext(): ChatContextValue;
|
|
23
|
+
//# sourceMappingURL=ChatContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatContext.d.ts","sourceRoot":"","sources":["../../../src/conversation/client/ChatContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,QAAQ,EACT,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChE,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IAC9D,aAAa,CAAC,EAAE,eAAe,EAAE,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,QAAQ,GAAG,IAAI,CAAC;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IACnE,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,KAAK,SAAS,CAAC;IACpF,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,iBAAiB,EAAE,CAAC;IAClE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,oBAAoB,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CACnD;AAED,eAAO,MAAM,WAAW,kDAA+C,CAAC;AAExE,wBAAgB,cAAc,IAAI,gBAAgB,CAIjD"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
export const ChatContext = createContext(null);
|
|
3
|
+
export function useChatContext() {
|
|
4
|
+
const ctx = useContext(ChatContext);
|
|
5
|
+
if (!ctx)
|
|
6
|
+
throw new Error('useChatContext must be used within a ChatView');
|
|
7
|
+
return ctx;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=ChatContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatContext.js","sourceRoot":"","sources":["../../../src/conversation/client/ChatContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AA6BlD,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAA0B,IAAI,CAAC,CAAC;AAExE,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC3E,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ChatMarkdownContentProps {
|
|
2
|
+
markdown: string;
|
|
3
|
+
width: number;
|
|
4
|
+
textIndex?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function ChatMarkdownContent({ markdown, width, textIndex, }: ChatMarkdownContentProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=ChatMarkdownContent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatMarkdownContent.d.ts","sourceRoot":"","sources":["../../../src/conversation/client/ChatMarkdownContent.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,KAAK,EACL,SAAS,GACV,EAAE,wBAAwB,2CAQ1B"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { MdastViewer } from '../../markdown/client/MdastViewer.js';
|
|
3
|
+
export function ChatMarkdownContent({ markdown, width, textIndex, }) {
|
|
4
|
+
return (_jsx(MdastViewer, { markdown: markdown, width: width, textIndex: textIndex ?? null }));
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=ChatMarkdownContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatMarkdownContent.js","sourceRoot":"","sources":["../../../src/conversation/client/ChatMarkdownContent.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAQnE,MAAM,UAAU,mBAAmB,CAAC,EAClC,QAAQ,EACR,KAAK,EACL,SAAS,GACgB;IACzB,OAAO,CACL,KAAC,WAAW,IACV,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,IAAI,IAAI,GAC5B,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ChatMarkdownInputProps {
|
|
2
|
+
placeholder?: string;
|
|
3
|
+
disabled?: boolean;
|
|
4
|
+
autoFocus?: boolean;
|
|
5
|
+
width?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function ChatMarkdownInput({ placeholder, disabled, autoFocus, width, }: ChatMarkdownInputProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=ChatMarkdownInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatMarkdownInput.d.ts","sourceRoot":"","sources":["../../../src/conversation/client/ChatMarkdownInput.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,WAAiC,EACjC,QAAgB,EAChB,SAAiB,EACjB,KAAW,GACZ,EAAE,sBAAsB,2CAqCxB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useRef, useState } from 'react';
|
|
3
|
+
import { MarkdownEditor } from '../../markdown/client/MarkdownEditor.js';
|
|
4
|
+
import { useChatContext } from './ChatContext.js';
|
|
5
|
+
export function ChatMarkdownInput({ placeholder = 'Type a message...', disabled = false, autoFocus = false, width = 600, }) {
|
|
6
|
+
const ctx = useChatContext();
|
|
7
|
+
const editorRef = useRef(null);
|
|
8
|
+
const [value, setValue] = useState('');
|
|
9
|
+
const handleSend = useCallback(() => {
|
|
10
|
+
const text = value.trim();
|
|
11
|
+
if (!text)
|
|
12
|
+
return;
|
|
13
|
+
ctx.onSend(text);
|
|
14
|
+
setValue('');
|
|
15
|
+
editorRef.current?.setValue('');
|
|
16
|
+
}, [value, ctx]);
|
|
17
|
+
const handleValueChanged = useCallback((newValue) => {
|
|
18
|
+
setValue(newValue);
|
|
19
|
+
ctx.onTypingStart?.();
|
|
20
|
+
}, [ctx]);
|
|
21
|
+
return (_jsx(MarkdownEditor, { value: value, onValueChanged: handleValueChanged, disabled: disabled, autoFocus: autoFocus, compact: true, limitedToolbar: true, menuAbove: true, editorMode: "prose", width: width, fileId: null, placeholder: placeholder, editorRef: editorRef }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=ChatMarkdownInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatMarkdownInput.js","sourceRoot":"","sources":["../../../src/conversation/client/ChatMarkdownInput.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AASlD,MAAM,UAAU,iBAAiB,CAAC,EAChC,WAAW,GAAG,mBAAmB,EACjC,QAAQ,GAAG,KAAK,EAChB,SAAS,GAAG,KAAK,EACjB,KAAK,GAAG,GAAG,GACY;IACvB,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAC7B,MAAM,SAAS,GAAG,MAAM,CAA0B,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEvC,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;QAClC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,EAAE,CAAC,CAAC;QACb,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAEjB,MAAM,kBAAkB,GAAG,WAAW,CACpC,CAAC,QAAgB,EAAE,EAAE;QACnB,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnB,GAAG,CAAC,aAAa,EAAE,EAAE,CAAC;IACxB,CAAC,EACD,CAAC,GAAG,CAAC,CACN,CAAC;IAEF,OAAO,CACL,KAAC,cAAc,IACb,KAAK,EAAE,KAAK,EACZ,cAAc,EAAE,kBAAkB,EAClC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,IAAI,EACb,cAAc,EAAE,IAAI,EACpB,SAAS,EAAE,IAAI,EACf,UAAU,EAAC,OAAO,EAClB,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,IAAI,EACZ,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,GACpB,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ChatMessage } from '../shared/types.js';
|
|
2
|
+
export interface ChatMessageBubbleProps {
|
|
3
|
+
message: ChatMessage;
|
|
4
|
+
isGrouped: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function ChatMessageBubble({ message, isGrouped }: ChatMessageBubbleProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=ChatMessageBubble.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatMessageBubble.d.ts","sourceRoot":"","sources":["../../../src/conversation/client/ChatMessageBubble.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,WAAW,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB;AAsFD,wBAAgB,iBAAiB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,sBAAsB,2CAkD/E"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useChatContext } from './ChatContext.js';
|
|
3
|
+
import { ChatTextContent } from './ChatTextContent.js';
|
|
4
|
+
const rowStyle = {
|
|
5
|
+
display: 'flex',
|
|
6
|
+
flexDirection: 'row',
|
|
7
|
+
alignItems: 'flex-start',
|
|
8
|
+
gap: 8,
|
|
9
|
+
padding: '2px 12px',
|
|
10
|
+
};
|
|
11
|
+
const rowWithHeaderStyle = {
|
|
12
|
+
...rowStyle,
|
|
13
|
+
paddingTop: 8,
|
|
14
|
+
};
|
|
15
|
+
const avatarStyle = {
|
|
16
|
+
width: 32,
|
|
17
|
+
height: 32,
|
|
18
|
+
borderRadius: '50%',
|
|
19
|
+
display: 'flex',
|
|
20
|
+
alignItems: 'center',
|
|
21
|
+
justifyContent: 'center',
|
|
22
|
+
fontSize: 14,
|
|
23
|
+
fontWeight: 600,
|
|
24
|
+
color: '#fff',
|
|
25
|
+
flexShrink: 0,
|
|
26
|
+
};
|
|
27
|
+
const avatarPlaceholderStyle = {
|
|
28
|
+
width: 32,
|
|
29
|
+
flexShrink: 0,
|
|
30
|
+
};
|
|
31
|
+
const contentColumnStyle = {
|
|
32
|
+
display: 'flex',
|
|
33
|
+
flexDirection: 'column',
|
|
34
|
+
minWidth: 0,
|
|
35
|
+
flex: 1,
|
|
36
|
+
};
|
|
37
|
+
const headerStyle = {
|
|
38
|
+
display: 'flex',
|
|
39
|
+
alignItems: 'baseline',
|
|
40
|
+
gap: 6,
|
|
41
|
+
marginBottom: 2,
|
|
42
|
+
};
|
|
43
|
+
const nameStyle = {
|
|
44
|
+
fontWeight: 600,
|
|
45
|
+
fontSize: 14,
|
|
46
|
+
color: 'var(--app-foreground)',
|
|
47
|
+
};
|
|
48
|
+
const timeStyle = {
|
|
49
|
+
fontSize: 11,
|
|
50
|
+
color: 'var(--app-foreground)',
|
|
51
|
+
opacity: 0.5,
|
|
52
|
+
};
|
|
53
|
+
const bodyStyle = {
|
|
54
|
+
fontSize: 14,
|
|
55
|
+
lineHeight: '1.45',
|
|
56
|
+
color: 'var(--app-foreground)',
|
|
57
|
+
};
|
|
58
|
+
const colorMap = {
|
|
59
|
+
accent: { color: 'var(--app-primary)' },
|
|
60
|
+
error: { color: '#e53935' },
|
|
61
|
+
notice: { color: 'var(--app-primary)', opacity: 0.8 },
|
|
62
|
+
};
|
|
63
|
+
/** Simple hash to pick a consistent avatar color */
|
|
64
|
+
function avatarColor(userId) {
|
|
65
|
+
const colors = ['#e57373', '#64b5f6', '#81c784', '#ffb74d', '#ba68c8', '#4dd0e1'];
|
|
66
|
+
let hash = 0;
|
|
67
|
+
for (let i = 0; i < userId.length; i++) {
|
|
68
|
+
hash = (hash * 31 + userId.charCodeAt(i)) | 0;
|
|
69
|
+
}
|
|
70
|
+
return colors[Math.abs(hash) % colors.length];
|
|
71
|
+
}
|
|
72
|
+
function formatTime(ts) {
|
|
73
|
+
const d = new Date(ts);
|
|
74
|
+
return d.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });
|
|
75
|
+
}
|
|
76
|
+
export function ChatMessageBubble({ message, isGrouped }) {
|
|
77
|
+
const ctx = useChatContext();
|
|
78
|
+
const user = ctx.getUser?.(message.userId);
|
|
79
|
+
const displayName = user?.name ?? 'Unknown';
|
|
80
|
+
const initial = displayName.charAt(0).toUpperCase();
|
|
81
|
+
const handleClick = () => {
|
|
82
|
+
ctx.setSelectedMessageId(ctx.selectedMessageId === message.id ? null : message.id);
|
|
83
|
+
};
|
|
84
|
+
const colorStyle = message.color ? colorMap[message.color] : undefined;
|
|
85
|
+
const defaultRender = () => (_jsx("div", { style: { ...bodyStyle, ...colorStyle }, children: ctx.renderContent
|
|
86
|
+
? ctx.renderContent(message, 600)
|
|
87
|
+
: _jsx(ChatTextContent, { text: message.text ?? '' }) }));
|
|
88
|
+
const content = ctx.renderMessage
|
|
89
|
+
? ctx.renderMessage(message, defaultRender)
|
|
90
|
+
: defaultRender();
|
|
91
|
+
return (_jsxs("div", { "data-message-id": message.id, style: isGrouped ? rowStyle : rowWithHeaderStyle, onClick: handleClick, children: [isGrouped ? (_jsx("div", { style: avatarPlaceholderStyle })) : (_jsx("div", { style: { ...avatarStyle, backgroundColor: avatarColor(message.userId) }, children: initial })), _jsxs("div", { style: contentColumnStyle, children: [!isGrouped && (_jsxs("div", { style: headerStyle, children: [_jsx("span", { style: nameStyle, children: displayName }), _jsx("span", { style: timeStyle, children: formatTime(message.created) })] })), content] })] }));
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=ChatMessageBubble.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatMessageBubble.js","sourceRoot":"","sources":["../../../src/conversation/client/ChatMessageBubble.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatScrollButton.d.ts","sourceRoot":"","sources":["../../../src/conversation/client/ChatScrollButton.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB;AA6BD,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,qBAAqB,2CAe3E"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
const buttonStyle = {
|
|
3
|
+
position: 'absolute',
|
|
4
|
+
bottom: 16,
|
|
5
|
+
right: 16,
|
|
6
|
+
width: 36,
|
|
7
|
+
height: 36,
|
|
8
|
+
borderRadius: '50%',
|
|
9
|
+
border: '1px solid var(--app-border)',
|
|
10
|
+
backgroundColor: 'var(--app-background)',
|
|
11
|
+
color: 'var(--app-foreground)',
|
|
12
|
+
cursor: 'pointer',
|
|
13
|
+
display: 'flex',
|
|
14
|
+
alignItems: 'center',
|
|
15
|
+
justifyContent: 'center',
|
|
16
|
+
boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
|
|
17
|
+
transition: 'opacity 0.2s, transform 0.2s',
|
|
18
|
+
zIndex: 10,
|
|
19
|
+
};
|
|
20
|
+
const arrowStyle = {
|
|
21
|
+
width: 0,
|
|
22
|
+
height: 0,
|
|
23
|
+
borderLeft: '5px solid transparent',
|
|
24
|
+
borderRight: '5px solid transparent',
|
|
25
|
+
borderTop: '6px solid currentColor',
|
|
26
|
+
};
|
|
27
|
+
export function ChatScrollButton({ onClick, visible }) {
|
|
28
|
+
return (_jsx("button", { onClick: onClick, style: {
|
|
29
|
+
...buttonStyle,
|
|
30
|
+
opacity: visible ? 1 : 0,
|
|
31
|
+
transform: visible ? 'translateY(0)' : 'translateY(8px)',
|
|
32
|
+
pointerEvents: visible ? 'auto' : 'none',
|
|
33
|
+
}, "aria-label": "Scroll to bottom", children: _jsx("span", { style: arrowStyle }) }));
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=ChatScrollButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatScrollButton.js","sourceRoot":"","sources":["../../../src/conversation/client/ChatScrollButton.tsx"],"names":[],"mappings":";AAOA,MAAM,WAAW,GAAkB;IACjC,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,EAAE;IACV,YAAY,EAAE,KAAK;IACnB,MAAM,EAAE,6BAA6B;IACrC,eAAe,EAAE,uBAAuB;IACxC,KAAK,EAAE,uBAAuB;IAC9B,MAAM,EAAE,SAAS;IACjB,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,QAAQ;IACpB,cAAc,EAAE,QAAQ;IACxB,SAAS,EAAE,4BAA4B;IACvC,UAAU,EAAE,8BAA8B;IAC1C,MAAM,EAAE,EAAE;CACX,CAAC;AAEF,MAAM,UAAU,GAAkB;IAChC,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,UAAU,EAAE,uBAAuB;IACnC,WAAW,EAAE,uBAAuB;IACpC,SAAS,EAAE,wBAAwB;CACpC,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAyB;IAC1E,OAAO,CACL,iBACE,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE;YACL,GAAG,WAAW;YACd,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACxB,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,iBAAiB;YACxD,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;SACzC,gBACU,kBAAkB,YAE7B,eAAM,KAAK,EAAE,UAAU,GAAI,GACpB,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatTextContent.d.ts","sourceRoot":"","sources":["../../../src/conversation/client/ChatTextContent.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;CACd;AAOD,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,EAAE,oBAAoB,2CAE7D"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
const textStyle = {
|
|
3
|
+
whiteSpace: 'pre-wrap',
|
|
4
|
+
wordBreak: 'break-word',
|
|
5
|
+
};
|
|
6
|
+
export function ChatTextContent({ text }) {
|
|
7
|
+
return _jsx("span", { style: textStyle, children: text });
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=ChatTextContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatTextContent.js","sourceRoot":"","sources":["../../../src/conversation/client/ChatTextContent.tsx"],"names":[],"mappings":";AAMA,MAAM,SAAS,GAAkB;IAC/B,UAAU,EAAE,UAAU;IACtB,SAAS,EAAE,YAAY;CACxB,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,EAAE,IAAI,EAAwB;IAC5D,OAAO,eAAM,KAAK,EAAE,SAAS,YAAG,IAAI,GAAQ,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ChatTextInputProps {
|
|
2
|
+
placeholder?: string;
|
|
3
|
+
disabled?: boolean;
|
|
4
|
+
autoFocus?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function ChatTextInput({ placeholder, disabled, autoFocus, }: ChatTextInputProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=ChatTextInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatTextInput.d.ts","sourceRoot":"","sources":["../../../src/conversation/client/ChatTextInput.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAmBD,wBAAgB,aAAa,CAAC,EAC5B,WAAiC,EACjC,QAAgB,EAChB,SAAiB,GAClB,EAAE,kBAAkB,2CAkCpB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useRef } from 'react';
|
|
3
|
+
import { useChatContext } from './ChatContext.js';
|
|
4
|
+
const textareaStyle = {
|
|
5
|
+
width: '100%',
|
|
6
|
+
minHeight: 40,
|
|
7
|
+
maxHeight: 160,
|
|
8
|
+
padding: '8px 12px',
|
|
9
|
+
fontSize: 14,
|
|
10
|
+
lineHeight: '1.45',
|
|
11
|
+
border: '1px solid var(--app-border)',
|
|
12
|
+
borderRadius: 8,
|
|
13
|
+
backgroundColor: 'var(--app-background)',
|
|
14
|
+
color: 'var(--app-foreground)',
|
|
15
|
+
resize: 'none',
|
|
16
|
+
outline: 'none',
|
|
17
|
+
fontFamily: 'inherit',
|
|
18
|
+
boxSizing: 'border-box',
|
|
19
|
+
};
|
|
20
|
+
export function ChatTextInput({ placeholder = 'Type a message...', disabled = false, autoFocus = false, }) {
|
|
21
|
+
const ctx = useChatContext();
|
|
22
|
+
const ref = useRef(null);
|
|
23
|
+
const handleKeyDown = useCallback((e) => {
|
|
24
|
+
if (e.key === 'Enter' && !e.shiftKey) {
|
|
25
|
+
e.preventDefault();
|
|
26
|
+
const text = ref.current?.value.trim();
|
|
27
|
+
if (text) {
|
|
28
|
+
ctx.onSend(text);
|
|
29
|
+
if (ref.current)
|
|
30
|
+
ref.current.value = '';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}, [ctx]);
|
|
34
|
+
const handleInput = useCallback(() => {
|
|
35
|
+
ctx.onTypingStart?.();
|
|
36
|
+
}, [ctx]);
|
|
37
|
+
return (_jsx("textarea", { ref: ref, style: textareaStyle, placeholder: placeholder, disabled: disabled, autoFocus: autoFocus, onKeyDown: handleKeyDown, onInput: handleInput, rows: 1 }));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=ChatTextInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatTextInput.js","sourceRoot":"","sources":["../../../src/conversation/client/ChatTextInput.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAQlD,MAAM,aAAa,GAAkB;IACnC,KAAK,EAAE,MAAM;IACb,SAAS,EAAE,EAAE;IACb,SAAS,EAAE,GAAG;IACd,OAAO,EAAE,UAAU;IACnB,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,MAAM;IAClB,MAAM,EAAE,6BAA6B;IACrC,YAAY,EAAE,CAAC;IACf,eAAe,EAAE,uBAAuB;IACxC,KAAK,EAAE,uBAAuB;IAC9B,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,SAAS;IACrB,SAAS,EAAE,YAAY;CACxB,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,EAC5B,WAAW,GAAG,mBAAmB,EACjC,QAAQ,GAAG,KAAK,EAChB,SAAS,GAAG,KAAK,GACE;IACnB,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,MAAM,CAAsB,IAAI,CAAC,CAAC;IAE9C,MAAM,aAAa,GAAG,WAAW,CAC/B,CAAC,CAAqC,EAAE,EAAE;QACxC,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;YACrC,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;YACvC,IAAI,IAAI,EAAE,CAAC;gBACT,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACjB,IAAI,GAAG,CAAC,OAAO;oBAAE,GAAG,CAAC,OAAO,CAAC,KAAK,GAAG,EAAE,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC,EACD,CAAC,GAAG,CAAC,CACN,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,GAAG,CAAC,aAAa,EAAE,EAAE,CAAC;IACxB,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,OAAO,CACL,mBACE,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,CAAC,GACP,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatTypingIndicator.d.ts","sourceRoot":"","sources":["../../../src/conversation/client/ChatTypingIndicator.tsx"],"names":[],"mappings":"AA2BA,wBAAgB,mBAAmB,mDAkClC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useChatContext } from './ChatContext.js';
|
|
3
|
+
const containerStyle = {
|
|
4
|
+
display: 'flex',
|
|
5
|
+
alignItems: 'center',
|
|
6
|
+
gap: 4,
|
|
7
|
+
padding: '4px 12px',
|
|
8
|
+
fontSize: 13,
|
|
9
|
+
color: 'var(--app-foreground)',
|
|
10
|
+
opacity: 0.6,
|
|
11
|
+
minHeight: 24,
|
|
12
|
+
};
|
|
13
|
+
const dotsStyle = {
|
|
14
|
+
display: 'inline-flex',
|
|
15
|
+
gap: 2,
|
|
16
|
+
};
|
|
17
|
+
const dotBaseStyle = {
|
|
18
|
+
width: 4,
|
|
19
|
+
height: 4,
|
|
20
|
+
borderRadius: '50%',
|
|
21
|
+
backgroundColor: 'currentColor',
|
|
22
|
+
animation: 'chat-typing-dot 1.4s infinite ease-in-out both',
|
|
23
|
+
};
|
|
24
|
+
export function ChatTypingIndicator() {
|
|
25
|
+
const { typingEntries, userId, getUser } = useChatContext();
|
|
26
|
+
const others = typingEntries?.filter((e) => e.userId !== userId) ?? [];
|
|
27
|
+
if (others.length === 0)
|
|
28
|
+
return null;
|
|
29
|
+
const names = others.map((e) => {
|
|
30
|
+
const user = getUser?.(e.userId);
|
|
31
|
+
return user?.name ?? 'Someone';
|
|
32
|
+
});
|
|
33
|
+
const label = names.length === 1
|
|
34
|
+
? `${names[0]} is typing`
|
|
35
|
+
: names.length === 2
|
|
36
|
+
? `${names[0]} and ${names[1]} are typing`
|
|
37
|
+
: `${names.length} people are typing`;
|
|
38
|
+
return (_jsxs("div", { style: containerStyle, children: [_jsx("style", { children: `
|
|
39
|
+
@keyframes chat-typing-dot {
|
|
40
|
+
0%, 80%, 100% { transform: scale(0); }
|
|
41
|
+
40% { transform: scale(1); }
|
|
42
|
+
}
|
|
43
|
+
` }), _jsx("span", { children: label }), _jsxs("span", { style: dotsStyle, children: [_jsx("span", { style: { ...dotBaseStyle, animationDelay: '-0.32s' } }), _jsx("span", { style: { ...dotBaseStyle, animationDelay: '-0.16s' } }), _jsx("span", { style: { ...dotBaseStyle, animationDelay: '0s' } })] })] }));
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=ChatTypingIndicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatTypingIndicator.js","sourceRoot":"","sources":["../../../src/conversation/client/ChatTypingIndicator.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,cAAc,GAAkB;IACpC,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,QAAQ;IACpB,GAAG,EAAE,CAAC;IACN,OAAO,EAAE,UAAU;IACnB,QAAQ,EAAE,EAAE;IACZ,KAAK,EAAE,uBAAuB;IAC9B,OAAO,EAAE,GAAG;IACZ,SAAS,EAAE,EAAE;CACd,CAAC;AAEF,MAAM,SAAS,GAAkB;IAC/B,OAAO,EAAE,aAAa;IACtB,GAAG,EAAE,CAAC;CACP,CAAC;AAEF,MAAM,YAAY,GAAkB;IAClC,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,YAAY,EAAE,KAAK;IACnB,eAAe,EAAE,cAAc;IAC/B,SAAS,EAAE,gDAAgD;CAC5D,CAAC;AAEF,MAAM,UAAU,mBAAmB;IACjC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAE5D,MAAM,MAAM,GAAG,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC;IACvE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACjC,OAAO,IAAI,EAAE,IAAI,IAAI,SAAS,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GACT,KAAK,CAAC,MAAM,KAAK,CAAC;QAChB,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,YAAY;QACzB,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAClB,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,aAAa;YAC1C,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,oBAAoB,CAAC;IAE5C,OAAO,CACL,eAAK,KAAK,EAAE,cAAc,aACxB,0BAAQ;;;;;OAKP,GAAS,EACV,yBAAO,KAAK,GAAQ,EACpB,gBAAM,KAAK,EAAE,SAAS,aACpB,eAAM,KAAK,EAAE,EAAE,GAAG,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAI,EAC9D,eAAM,KAAK,EAAE,EAAE,GAAG,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAI,EAC9D,eAAM,KAAK,EAAE,EAAE,GAAG,YAAY,EAAE,cAAc,EAAE,IAAI,EAAE,GAAI,IACrD,IACH,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { ChatMessage, ChatMessageAction, ChatReaction, ChatTypingEntry, ChatUser } from '../shared/types.js';
|
|
3
|
+
export interface ChatViewProps {
|
|
4
|
+
messages: ChatMessage[];
|
|
5
|
+
userId: string;
|
|
6
|
+
onSend: (text: string, parentMessageId?: string | null) => void;
|
|
7
|
+
onDelete?: (messageId: string) => void;
|
|
8
|
+
onEdit?: (messageId: string, text: string) => void;
|
|
9
|
+
onReact?: (messageId: string, reaction: ChatReaction) => void;
|
|
10
|
+
typingEntries?: ChatTypingEntry[];
|
|
11
|
+
onTypingStart?: () => void;
|
|
12
|
+
getUser?: (userId: string) => ChatUser | null;
|
|
13
|
+
hasMore?: boolean;
|
|
14
|
+
onLoadMore?: () => void;
|
|
15
|
+
renderContent?: (message: ChatMessage, width: number) => ReactNode;
|
|
16
|
+
renderMessage?: (message: ChatMessage, defaultRender: () => ReactNode) => ReactNode;
|
|
17
|
+
getMessageActions?: (message: ChatMessage) => ChatMessageAction[];
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
}
|
|
20
|
+
export declare function ChatView({ messages, userId, onSend, onDelete, onEdit, onReact, typingEntries, onTypingStart, getUser, hasMore, onLoadMore, renderContent, renderMessage, getMessageActions, children, }: ChatViewProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=ChatView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatView.d.ts","sourceRoot":"","sources":["../../../src/conversation/client/ChatView.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,QAAQ,EACT,MAAM,oBAAoB,CAAC;AA+E5B,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChE,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IAC9D,aAAa,CAAC,EAAE,eAAe,EAAE,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,QAAQ,GAAG,IAAI,CAAC;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IACnE,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,KAAK,SAAS,CAAC;IACpF,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,iBAAiB,EAAE,CAAC;IAClE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAID,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,MAAM,EACN,OAAO,EACP,aAAa,EACb,aAAa,EACb,OAAO,EACP,OAAO,EACP,UAAU,EACV,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,QAAQ,GACT,EAAE,aAAa,2CAoIf"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
3
|
+
import { ChatContext } from './ChatContext.js';
|
|
4
|
+
import { ChatMessageBubble } from './ChatMessageBubble.js';
|
|
5
|
+
import { ChatTypingIndicator } from './ChatTypingIndicator.js';
|
|
6
|
+
import { ChatScrollButton } from './ChatScrollButton.js';
|
|
7
|
+
// ─── Duration separator ─────────────────────────────────────────────────────
|
|
8
|
+
const DURATION_SEPARATOR_MS = 5 * 60 * 1000; // 5 minutes
|
|
9
|
+
function formatDateSeparator(ts) {
|
|
10
|
+
const d = new Date(ts);
|
|
11
|
+
const now = new Date();
|
|
12
|
+
const isToday = d.getDate() === now.getDate() &&
|
|
13
|
+
d.getMonth() === now.getMonth() &&
|
|
14
|
+
d.getFullYear() === now.getFullYear();
|
|
15
|
+
if (isToday) {
|
|
16
|
+
return 'Today at ' + d.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });
|
|
17
|
+
}
|
|
18
|
+
return d.toLocaleDateString(undefined, {
|
|
19
|
+
month: 'short',
|
|
20
|
+
day: 'numeric',
|
|
21
|
+
year: d.getFullYear() !== now.getFullYear() ? 'numeric' : undefined,
|
|
22
|
+
}) + ' at ' + d.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });
|
|
23
|
+
}
|
|
24
|
+
// ─── Styles ─────────────────────────────────────────────────────────────────
|
|
25
|
+
const outerStyle = {
|
|
26
|
+
display: 'flex',
|
|
27
|
+
flexDirection: 'column',
|
|
28
|
+
flex: 1,
|
|
29
|
+
minHeight: 0,
|
|
30
|
+
position: 'relative',
|
|
31
|
+
};
|
|
32
|
+
const scrollContainerStyle = {
|
|
33
|
+
flex: 1,
|
|
34
|
+
overflowY: 'auto',
|
|
35
|
+
display: 'flex',
|
|
36
|
+
flexDirection: 'column',
|
|
37
|
+
};
|
|
38
|
+
const innerStyle = {
|
|
39
|
+
display: 'flex',
|
|
40
|
+
flexDirection: 'column',
|
|
41
|
+
marginTop: 'auto',
|
|
42
|
+
};
|
|
43
|
+
const separatorStyle = {
|
|
44
|
+
display: 'flex',
|
|
45
|
+
alignItems: 'center',
|
|
46
|
+
justifyContent: 'center',
|
|
47
|
+
padding: '12px 0',
|
|
48
|
+
fontSize: 11,
|
|
49
|
+
color: 'var(--app-foreground)',
|
|
50
|
+
opacity: 0.45,
|
|
51
|
+
userSelect: 'none',
|
|
52
|
+
};
|
|
53
|
+
const loadMoreStyle = {
|
|
54
|
+
display: 'flex',
|
|
55
|
+
justifyContent: 'center',
|
|
56
|
+
padding: 8,
|
|
57
|
+
};
|
|
58
|
+
const loadMoreButtonStyle = {
|
|
59
|
+
background: 'none',
|
|
60
|
+
border: 'none',
|
|
61
|
+
color: 'var(--app-primary)',
|
|
62
|
+
cursor: 'pointer',
|
|
63
|
+
fontSize: 13,
|
|
64
|
+
padding: '4px 12px',
|
|
65
|
+
};
|
|
66
|
+
// ─── Component ──────────────────────────────────────────────────────────────
|
|
67
|
+
export function ChatView({ messages, userId, onSend, onDelete, onEdit, onReact, typingEntries, onTypingStart, getUser, hasMore, onLoadMore, renderContent, renderMessage, getMessageActions, children, }) {
|
|
68
|
+
const scrollRef = useRef(null);
|
|
69
|
+
const [selectedMessageId, setSelectedMessageId] = useState(null);
|
|
70
|
+
const [showScrollButton, setShowScrollButton] = useState(false);
|
|
71
|
+
const isAtBottomRef = useRef(true);
|
|
72
|
+
const prevMessageCountRef = useRef(messages.length);
|
|
73
|
+
// ─── Context value ──────────────────────────────────────────────────────
|
|
74
|
+
const ctxValue = useMemo(() => ({
|
|
75
|
+
messages,
|
|
76
|
+
userId,
|
|
77
|
+
onSend,
|
|
78
|
+
onDelete,
|
|
79
|
+
onEdit,
|
|
80
|
+
onReact,
|
|
81
|
+
typingEntries,
|
|
82
|
+
onTypingStart,
|
|
83
|
+
getUser,
|
|
84
|
+
hasMore,
|
|
85
|
+
onLoadMore,
|
|
86
|
+
renderContent,
|
|
87
|
+
renderMessage,
|
|
88
|
+
getMessageActions,
|
|
89
|
+
selectedMessageId,
|
|
90
|
+
setSelectedMessageId,
|
|
91
|
+
}), [
|
|
92
|
+
messages,
|
|
93
|
+
userId,
|
|
94
|
+
onSend,
|
|
95
|
+
onDelete,
|
|
96
|
+
onEdit,
|
|
97
|
+
onReact,
|
|
98
|
+
typingEntries,
|
|
99
|
+
onTypingStart,
|
|
100
|
+
getUser,
|
|
101
|
+
hasMore,
|
|
102
|
+
onLoadMore,
|
|
103
|
+
renderContent,
|
|
104
|
+
renderMessage,
|
|
105
|
+
getMessageActions,
|
|
106
|
+
selectedMessageId,
|
|
107
|
+
]);
|
|
108
|
+
// ─── Scroll handling ──────────────────────────────────────────────────
|
|
109
|
+
const scrollToBottom = useCallback(() => {
|
|
110
|
+
const el = scrollRef.current;
|
|
111
|
+
if (el) {
|
|
112
|
+
el.scrollTop = el.scrollHeight;
|
|
113
|
+
}
|
|
114
|
+
}, []);
|
|
115
|
+
const handleScroll = useCallback(() => {
|
|
116
|
+
const el = scrollRef.current;
|
|
117
|
+
if (!el)
|
|
118
|
+
return;
|
|
119
|
+
const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
120
|
+
const atBottom = distanceFromBottom < 40;
|
|
121
|
+
isAtBottomRef.current = atBottom;
|
|
122
|
+
setShowScrollButton(!atBottom);
|
|
123
|
+
}, []);
|
|
124
|
+
// Auto-scroll on new messages
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
if (messages.length > prevMessageCountRef.current && isAtBottomRef.current) {
|
|
127
|
+
scrollToBottom();
|
|
128
|
+
}
|
|
129
|
+
prevMessageCountRef.current = messages.length;
|
|
130
|
+
}, [messages.length, scrollToBottom]);
|
|
131
|
+
// Initial scroll
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
scrollToBottom();
|
|
134
|
+
}, [scrollToBottom]);
|
|
135
|
+
// ─── Build message rows with separators ────────────────────────────────
|
|
136
|
+
const rows = useMemo(() => {
|
|
137
|
+
const result = [];
|
|
138
|
+
for (let i = 0; i < messages.length; i++) {
|
|
139
|
+
const msg = messages[i];
|
|
140
|
+
const prev = i > 0 ? messages[i - 1] : null;
|
|
141
|
+
// Duration separator
|
|
142
|
+
if (prev && msg.created - prev.created > DURATION_SEPARATOR_MS) {
|
|
143
|
+
result.push(_jsx("div", { style: separatorStyle, children: formatDateSeparator(msg.created) }, `sep-${msg.id}`));
|
|
144
|
+
}
|
|
145
|
+
const isGrouped = !!prev &&
|
|
146
|
+
prev.userId === msg.userId &&
|
|
147
|
+
msg.created - prev.created <= DURATION_SEPARATOR_MS;
|
|
148
|
+
result.push(_jsx(ChatMessageBubble, { message: msg, isGrouped: isGrouped }, msg.id));
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
}, [messages]);
|
|
152
|
+
return (_jsx(ChatContext.Provider, { value: ctxValue, children: _jsxs("div", { style: outerStyle, children: [_jsx("div", { ref: scrollRef, style: scrollContainerStyle, onScroll: handleScroll, "data-testid": "conversation-scroll-container", children: _jsxs("div", { "data-testid": "message-list-inner", style: innerStyle, children: [hasMore && onLoadMore && (_jsx("div", { style: loadMoreStyle, children: _jsx("button", { style: loadMoreButtonStyle, onClick: onLoadMore, children: "Load more" }) })), rows] }) }), _jsx(ChatTypingIndicator, {}), _jsx(ChatScrollButton, { onClick: scrollToBottom, visible: showScrollButton }), children] }) }));
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=ChatView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatView.js","sourceRoot":"","sources":["../../../src/conversation/client/ChatView.tsx"],"names":[],"mappings":"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"}
|