@usechatting/react-native 0.1.1 → 0.1.3

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.
@@ -4,18 +4,20 @@ import { useChattingConversation } from "./use-chatting-conversation";
4
4
  import { styles } from "./chatting-screen-styles";
5
5
  export function ChattingConversationScreen(input) {
6
6
  const conversation = useChattingConversation(input);
7
- const title = conversation.siteConfig?.widgetTitle ?? "Chatting";
8
- const subtitle = conversation.siteConfig?.showOnlineStatus !== false && conversation.siteStatus
7
+ const title = conversation.siteConfig?.widgetTitle ?? "";
8
+ const greeting = conversation.siteConfig?.greetingText?.trim() || "Start a conversation";
9
+ const brandColor = conversation.siteConfig?.brandColor?.trim() || "#2563EB";
10
+ const teamStatus = conversation.siteConfig?.showOnlineStatus !== false && conversation.siteStatus
9
11
  ? conversation.siteStatus.online
10
12
  ? "Team is online"
11
13
  : "Team is away"
12
- : conversation.siteConfig?.greetingText ?? "Start a conversation";
13
- return (_jsxs(View, { style: styles.screen, children: [_jsxs(View, { style: styles.header, children: [_jsx(Text, { style: styles.title, children: title }), _jsx(Text, { style: styles.subtitle, children: subtitle })] }), _jsxs(ScrollView, { style: styles.scroll, contentContainerStyle: styles.content, children: [conversation.errorMessage ? (_jsx(View, { style: styles.banner, children: _jsx(Text, { style: [styles.bannerText, styles.error], children: conversation.errorMessage }) })) : null, conversation.isLoading ? _jsx(ActivityIndicator, { color: "#2563EB" }) : null, !conversation.isLoading && conversation.messages.length === 0 ? (_jsx(View, { style: styles.banner, children: _jsx(Text, { style: styles.bannerText, children: "Open support inside your app without rebuilding visitor chat from scratch." }) })) : null, conversation.messages.map((message) => (_jsx(View, { style: styles.row, children: message.sender === "team" ? (_jsxs(_Fragment, { children: [_jsx(Bubble, { message: message.content || "(attachment placeholder)", isUser: false }), _jsx(View, { style: styles.spacer })] })) : (_jsxs(_Fragment, { children: [_jsx(View, { style: styles.spacer }), _jsx(Bubble, { message: message.content || "(attachment placeholder)", isUser: true })] })) }, message.id))), conversation.teamTyping ? (_jsxs(View, { style: styles.row, children: [_jsx(Bubble, { message: "Team is typing...", isUser: false, subtle: true }), _jsx(View, { style: styles.spacer })] })) : null, conversation.faqSuggestions?.items.map((item) => (_jsxs(View, { style: styles.faqCard, children: [_jsx(Text, { style: styles.faqTitle, children: item.question }), _jsx(Text, { style: styles.faqText, children: item.answer })] }, item.id))), conversation.faqSuggestions?.fallbackMessage ? (_jsx(Text, { style: styles.meta, children: conversation.faqSuggestions.fallbackMessage })) : null] }), _jsxs(View, { style: styles.footer, children: [_jsx(TextInput, { value: conversation.emailAddress, onChangeText: conversation.setEmailAddress, placeholder: "Email for follow-up", autoCapitalize: "none", autoCorrect: false, style: styles.input }), _jsx(TextInput, { value: conversation.draftMessage, onChangeText: conversation.setDraftMessage, placeholder: "Type a message", multiline: true, style: [styles.input, styles.composer] }), _jsxs(View, { style: styles.actions, children: [_jsx(TouchableOpacity, { style: [styles.button, styles.secondaryButton], onPress: () => void conversation.saveEmail(), children: _jsx(Text, { style: styles.secondaryButtonText, children: conversation.isSavingEmail ? "Saving..." : "Save email" }) }), _jsx(TouchableOpacity, { style: styles.button, onPress: () => void conversation.sendMessage(), children: _jsx(Text, { style: styles.buttonText, children: conversation.isSending ? "Sending..." : "Send" }) })] })] })] }));
14
+ : null;
15
+ return (_jsxs(View, { style: styles.screen, children: [_jsxs(View, { style: [styles.header, { backgroundColor: brandColor }], children: [title ? _jsx(Text, { style: styles.title, children: title }) : null, teamStatus ? _jsx(Text, { style: styles.subtitle, children: teamStatus }) : null] }), _jsxs(ScrollView, { style: styles.scroll, contentContainerStyle: styles.content, children: [conversation.errorMessage ? (_jsx(View, { style: styles.banner, children: _jsx(Text, { style: [styles.bannerText, styles.error], children: conversation.errorMessage }) })) : null, conversation.isLoading ? _jsx(ActivityIndicator, { color: brandColor }) : null, !conversation.isLoading && conversation.messages.length === 0 ? (_jsxs(View, { style: styles.row, children: [_jsx(Bubble, { message: greeting, isUser: false, brandColor: brandColor }), _jsx(View, { style: styles.spacer })] })) : null, conversation.messages.map((message) => (_jsx(View, { style: styles.row, children: message.sender === "team" ? (_jsxs(_Fragment, { children: [_jsx(Bubble, { message: message.content || "(attachment placeholder)", isUser: false, brandColor: brandColor }), _jsx(View, { style: styles.spacer })] })) : (_jsxs(_Fragment, { children: [_jsx(View, { style: styles.spacer }), _jsx(Bubble, { message: message.content || "(attachment placeholder)", isUser: true, brandColor: brandColor })] })) }, message.id))), conversation.teamTyping ? (_jsxs(View, { style: styles.row, children: [_jsx(Bubble, { message: "Team is typing...", isUser: false, subtle: true, brandColor: brandColor }), _jsx(View, { style: styles.spacer })] })) : null, conversation.faqSuggestions?.items.map((item) => (_jsxs(View, { style: styles.faqCard, children: [_jsx(Text, { style: styles.faqTitle, children: item.question }), _jsx(Text, { style: styles.faqText, children: item.answer })] }, item.id))), conversation.faqSuggestions?.fallbackMessage ? (_jsx(Text, { style: styles.meta, children: conversation.faqSuggestions.fallbackMessage })) : null] }), _jsx(View, { style: styles.footer, children: _jsxs(View, { style: styles.composerRow, children: [_jsx(TextInput, { value: conversation.draftMessage, onChangeText: conversation.setDraftMessage, placeholder: "Type a message", multiline: true, style: [styles.input, styles.composer] }), _jsx(TouchableOpacity, { style: [styles.button, styles.sendButton, { backgroundColor: brandColor }], onPress: () => void conversation.sendMessage(), children: _jsx(Text, { style: styles.buttonText, children: conversation.isSending ? "Sending..." : "Send" }) })] }) })] }));
14
16
  }
15
17
  function Bubble(input) {
16
18
  return (_jsx(View, { style: [
17
19
  styles.bubble,
18
- input.isUser ? styles.userBubble : styles.teamBubble,
20
+ input.isUser ? { backgroundColor: input.brandColor } : styles.teamBubble,
19
21
  input.subtle ? styles.typingBubble : null
20
22
  ], children: _jsx(Text, { style: input.isUser ? styles.userText : styles.teamText, children: input.message }) }));
21
23
  }
@@ -4,10 +4,9 @@ export declare const styles: {
4
4
  backgroundColor: string;
5
5
  };
6
6
  header: {
7
- padding: number;
8
- borderBottomWidth: number;
9
- borderBottomColor: string;
10
- backgroundColor: string;
7
+ paddingHorizontal: number;
8
+ paddingTop: number;
9
+ paddingBottom: number;
11
10
  };
12
11
  title: {
13
12
  fontSize: number;
@@ -25,6 +24,7 @@ export declare const styles: {
25
24
  content: {
26
25
  padding: number;
27
26
  gap: number;
27
+ flexGrow: number;
28
28
  };
29
29
  banner: {
30
30
  padding: number;
@@ -55,13 +55,17 @@ export declare const styles: {
55
55
  paddingHorizontal: number;
56
56
  paddingVertical: number;
57
57
  };
58
- userBubble: {
59
- backgroundColor: string;
60
- };
61
58
  teamBubble: {
62
59
  backgroundColor: string;
63
- borderWidth: number;
64
- borderColor: string;
60
+ borderBottomLeftRadius: number;
61
+ shadowColor: string;
62
+ shadowOpacity: number;
63
+ shadowRadius: number;
64
+ shadowOffset: {
65
+ width: number;
66
+ height: number;
67
+ };
68
+ elevation: number;
65
69
  };
66
70
  typingBubble: {
67
71
  opacity: number;
@@ -100,12 +104,16 @@ export declare const styles: {
100
104
  color: string;
101
105
  };
102
106
  footer: {
103
- gap: number;
104
107
  padding: number;
105
108
  borderTopWidth: number;
106
109
  borderTopColor: string;
107
110
  backgroundColor: string;
108
111
  };
112
+ composerRow: {
113
+ flexDirection: string;
114
+ alignItems: string;
115
+ gap: number;
116
+ };
109
117
  input: {
110
118
  borderWidth: number;
111
119
  borderColor: string;
@@ -116,31 +124,25 @@ export declare const styles: {
116
124
  color: string;
117
125
  };
118
126
  composer: {
127
+ flex: number;
119
128
  minHeight: number;
120
129
  maxHeight: number;
121
130
  textAlignVertical: string;
122
131
  };
123
- actions: {
124
- flexDirection: string;
125
- gap: number;
126
- };
127
132
  button: {
128
133
  flex: number;
129
134
  borderRadius: number;
130
135
  paddingVertical: number;
131
136
  alignItems: string;
132
137
  justifyContent: string;
133
- backgroundColor: string;
134
138
  };
135
- secondaryButton: {
136
- backgroundColor: string;
139
+ sendButton: {
140
+ flex: number;
141
+ minHeight: number;
142
+ paddingHorizontal: number;
137
143
  };
138
144
  buttonText: {
139
145
  color: string;
140
146
  fontWeight: string;
141
147
  };
142
- secondaryButtonText: {
143
- color: string;
144
- fontWeight: string;
145
- };
146
148
  };
@@ -1,19 +1,26 @@
1
1
  import { StyleSheet } from "react-native";
2
2
  export const styles = StyleSheet.create({
3
- screen: { flex: 1, backgroundColor: "#F8FAFC" },
4
- header: { padding: 16, borderBottomWidth: 1, borderBottomColor: "#E2E8F0", backgroundColor: "#FFFFFF" },
5
- title: { fontSize: 18, fontWeight: "700", color: "#0F172A" },
6
- subtitle: { marginTop: 4, fontSize: 14, color: "#475569" },
3
+ screen: { flex: 1, backgroundColor: "#F6F8FB" },
4
+ header: { paddingHorizontal: 18, paddingTop: 18, paddingBottom: 16 },
5
+ title: { fontSize: 19, fontWeight: "700", color: "#FFFFFF" },
6
+ subtitle: { marginTop: 4, fontSize: 13, color: "#DBEAFE" },
7
7
  scroll: { flex: 1 },
8
- content: { padding: 16, gap: 12 },
8
+ content: { padding: 16, gap: 12, flexGrow: 1 },
9
9
  banner: { padding: 12, borderRadius: 16, backgroundColor: "#FFFFFF", borderWidth: 1, borderColor: "#E2E8F0" },
10
10
  bannerText: { color: "#334155", fontSize: 14, lineHeight: 20 },
11
11
  error: { color: "#B91C1C" },
12
12
  row: { flexDirection: "row", alignItems: "flex-end" },
13
13
  spacer: { flex: 1, minWidth: 40 },
14
14
  bubble: { maxWidth: "78%", borderRadius: 18, paddingHorizontal: 14, paddingVertical: 10 },
15
- userBubble: { backgroundColor: "#2563EB" },
16
- teamBubble: { backgroundColor: "#FFFFFF", borderWidth: 1, borderColor: "#E2E8F0" },
15
+ teamBubble: {
16
+ backgroundColor: "#FFFFFF",
17
+ borderBottomLeftRadius: 6,
18
+ shadowColor: "#0F172A",
19
+ shadowOpacity: 0.08,
20
+ shadowRadius: 10,
21
+ shadowOffset: { width: 0, height: 4 },
22
+ elevation: 2
23
+ },
17
24
  typingBubble: { opacity: 0.8 },
18
25
  userText: { color: "#FFFFFF", fontSize: 15, lineHeight: 22 },
19
26
  teamText: { color: "#0F172A", fontSize: 15, lineHeight: 22 },
@@ -21,12 +28,11 @@ export const styles = StyleSheet.create({
21
28
  faqCard: { padding: 12, borderRadius: 14, backgroundColor: "#FFFFFF", borderWidth: 1, borderColor: "#E2E8F0", gap: 4 },
22
29
  faqTitle: { fontSize: 14, fontWeight: "700", color: "#0F172A" },
23
30
  faqText: { fontSize: 13, lineHeight: 19, color: "#475569" },
24
- footer: { gap: 12, padding: 16, borderTopWidth: 1, borderTopColor: "#E2E8F0", backgroundColor: "#FFFFFF" },
25
- input: { borderWidth: 1, borderColor: "#CBD5E1", borderRadius: 14, paddingHorizontal: 12, paddingVertical: 10, backgroundColor: "#FFFFFF", color: "#0F172A" },
26
- composer: { minHeight: 44, maxHeight: 120, textAlignVertical: "top" },
27
- actions: { flexDirection: "row", gap: 12 },
28
- button: { flex: 1, borderRadius: 14, paddingVertical: 12, alignItems: "center", justifyContent: "center", backgroundColor: "#2563EB" },
29
- secondaryButton: { backgroundColor: "#EFF6FF" },
30
- buttonText: { color: "#FFFFFF", fontWeight: "700" },
31
- secondaryButtonText: { color: "#2563EB", fontWeight: "700" }
31
+ footer: { padding: 14, borderTopWidth: 1, borderTopColor: "#E2E8F0", backgroundColor: "#FFFFFF" },
32
+ composerRow: { flexDirection: "row", alignItems: "flex-end", gap: 8 },
33
+ input: { borderWidth: 1, borderColor: "#CBD5E1", borderRadius: 20, paddingHorizontal: 14, paddingVertical: 10, backgroundColor: "#F8FAFC", color: "#0F172A" },
34
+ composer: { flex: 1, minHeight: 44, maxHeight: 120, textAlignVertical: "top" },
35
+ button: { flex: 1, borderRadius: 20, paddingVertical: 12, alignItems: "center", justifyContent: "center" },
36
+ sendButton: { flex: 0, minHeight: 44, paddingHorizontal: 18 },
37
+ buttonText: { color: "#FFFFFF", fontWeight: "700" }
32
38
  });
@@ -10,7 +10,7 @@ export function useChattingConversation(input) {
10
10
  const [emailAddress, setEmailAddress] = useState(input.draftVisitorEmail ?? "");
11
11
  const [teamTyping, setTeamTyping] = useState(false);
12
12
  const [errorMessage, setErrorMessage] = useState(null);
13
- const [isLoading, setIsLoading] = useState(false);
13
+ const [isLoading, setIsLoading] = useState(true);
14
14
  const [isSending, setIsSending] = useState(false);
15
15
  const [isSavingEmail, setIsSavingEmail] = useState(false);
16
16
  const stopSyncRef = useRef(null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usechatting/react-native",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "React Native and Expo visitor chat SDK for Chatting.",
5
5
  "license": "Proprietary",
6
6
  "main": "dist/index.js",