Skip to content

Commit 7f272a8

Browse files
committed
feat: minor imporements
1 parent f5e93da commit 7f272a8

File tree

11 files changed

+513
-369
lines changed

11 files changed

+513
-369
lines changed

mobile/app/_layout.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import { Stack } from 'expo-router';
22
import { StatusBar } from 'expo-status-bar';
3+
import { LogBox } from 'react-native';
34
import Toast from 'react-native-toast-message';
45
import { SafeAreaProvider } from 'react-native-safe-area-context';
56
import { ThemeProvider } from '../src/contexts/ThemeContext';
67

8+
// Ignore all LogBox warnings and logs in development
9+
LogBox.ignoreAllLogs(true);
10+
711
export default function RootLayout() {
812
return (
913
<SafeAreaProvider>
Lines changed: 71 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,33 @@
1-
import React from 'react';
2-
import {
3-
View,
4-
Text,
5-
StyleSheet,
6-
TouchableOpacity,
7-
} from 'react-native';
8-
import { Ionicons } from '@expo/vector-icons';
9-
import Markdown from 'react-native-markdown-display';
10-
import { Message } from '../../types/api';
11-
import { spacing, fontSize, borderRadius } from '../../constants/theme';
12-
import { useTheme } from '../../contexts/ThemeContext';
1+
import React from "react";
2+
import { View, Text, StyleSheet, Linking } from "react-native";
3+
import Markdown from "react-native-markdown-display";
4+
import { ThinkingAnimation } from "./ThinkingAnimation";
5+
import { Message } from "../../types/api";
6+
import { spacing, fontSize, borderRadius } from "../../constants/theme";
7+
import { useTheme } from "../../contexts/ThemeContext";
138

149
interface MessageBubbleProps {
1510
message: Message;
16-
onCopy?: () => void;
1711
}
1812

19-
export const MessageBubble: React.FC<MessageBubbleProps> = ({
20-
message,
21-
onCopy,
22-
}) => {
13+
export const MessageBubble: React.FC<MessageBubbleProps> = ({ message }) => {
2314
const { colors } = useTheme();
24-
const isUser = message.role === 'user';
15+
const isUser = message.role === "user";
2516
const styles = createStyles(colors, isUser);
2617

2718
return (
28-
<View style={[
29-
styles.container,
30-
isUser ? styles.userContainer : styles.agentContainer,
31-
]}>
19+
<View
20+
style={[
21+
styles.container,
22+
isUser ? styles.userContainer : styles.agentContainer,
23+
]}
24+
>
3225
<View style={styles.bubble}>
3326
{isUser ? (
34-
<Text style={[
35-
styles.messageText,
36-
styles.userText,
37-
]}>
27+
<Text style={[styles.messageText, styles.userText]}>
3828
{message.content}
3929
</Text>
40-
) : (
30+
) : message.content ? (
4131
<Markdown
4232
style={{
4333
body: {
@@ -62,14 +52,15 @@ export const MessageBubble: React.FC<MessageBubbleProps> = ({
6252
},
6353
strong: {
6454
color: colors.foreground,
65-
fontWeight: '700',
55+
fontWeight: "700",
6656
},
6757
em: {
6858
color: colors.foreground,
69-
fontStyle: 'italic',
59+
fontStyle: "italic",
7060
},
7161
link: {
7262
color: colors.primary,
63+
textDecorationLine: "underline",
7364
},
7465
blockquote: {
7566
backgroundColor: colors.muted,
@@ -81,19 +72,19 @@ export const MessageBubble: React.FC<MessageBubbleProps> = ({
8172
},
8273
heading1: {
8374
fontSize: fontSize.xl,
84-
fontWeight: 'bold',
75+
fontWeight: "bold",
8576
color: colors.foreground,
8677
marginVertical: spacing.xs,
8778
},
8879
heading2: {
8980
fontSize: fontSize.lg,
90-
fontWeight: 'bold',
81+
fontWeight: "bold",
9182
color: colors.foreground,
9283
marginVertical: spacing.xs,
9384
},
9485
heading3: {
9586
fontSize: fontSize.base,
96-
fontWeight: 'bold',
87+
fontWeight: "bold",
9788
color: colors.foreground,
9889
marginVertical: spacing.xs,
9990
},
@@ -102,78 +93,62 @@ export const MessageBubble: React.FC<MessageBubbleProps> = ({
10293
fontSize: fontSize.base,
10394
},
10495
}}
96+
onLinkPress={(url) => {
97+
Linking.openURL(url).catch(() => {
98+
// Failed to open link
99+
});
100+
return false;
101+
}}
105102
>
106103
{message.content}
107104
</Markdown>
108-
)}
109-
110-
{!isUser && onCopy && (
111-
<TouchableOpacity
112-
style={styles.copyButton}
113-
onPress={onCopy}
114-
hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
115-
>
116-
<Ionicons
117-
name="copy-outline"
118-
size={16}
119-
color={colors.mutedForeground}
120-
/>
121-
</TouchableOpacity>
105+
) : (
106+
<ThinkingAnimation />
122107
)}
123108
</View>
124-
125-
<Text style={[
126-
styles.timestamp,
127-
{ color: colors.mutedForeground }
128-
]}>
129-
{new Date(message.createdAt).toLocaleTimeString([], {
130-
hour: '2-digit',
131-
minute: '2-digit'
109+
110+
<Text style={[styles.timestamp, { color: colors.mutedForeground }]}>
111+
{new Date(message.createdAt).toLocaleTimeString([], {
112+
hour: "2-digit",
113+
minute: "2-digit",
132114
})}
133115
</Text>
134116
</View>
135117
);
136118
};
137119

138-
const createStyles = (colors: any, isUser: boolean) => StyleSheet.create({
139-
container: {
140-
marginVertical: spacing.xs,
141-
paddingHorizontal: spacing.md,
142-
},
143-
userContainer: {
144-
alignItems: 'flex-end',
145-
},
146-
agentContainer: {
147-
alignItems: 'flex-start',
148-
},
149-
bubble: {
150-
maxWidth: '85%',
151-
paddingHorizontal: spacing.md,
152-
paddingVertical: spacing.sm,
153-
borderRadius: borderRadius.lg,
154-
position: 'relative',
155-
backgroundColor: isUser ? colors.primary : colors.secondary,
156-
borderBottomRightRadius: isUser ? 6 : borderRadius.lg,
157-
borderBottomLeftRadius: isUser ? borderRadius.lg : 6,
158-
},
159-
messageText: {
160-
fontSize: fontSize.base,
161-
lineHeight: 22,
162-
},
163-
userText: {
164-
color: colors.primaryForeground,
165-
},
166-
copyButton: {
167-
position: 'absolute',
168-
top: spacing.xs,
169-
right: spacing.xs,
170-
padding: spacing.xs,
171-
backgroundColor: colors.background,
172-
borderRadius: 12,
173-
},
174-
timestamp: {
175-
fontSize: fontSize.xs,
176-
marginTop: spacing.xs,
177-
marginHorizontal: spacing.xs,
178-
},
179-
});
120+
const createStyles = (colors: any, isUser: boolean) =>
121+
StyleSheet.create({
122+
container: {
123+
marginVertical: spacing.xs,
124+
paddingHorizontal: spacing.md,
125+
},
126+
userContainer: {
127+
alignItems: "flex-end",
128+
},
129+
agentContainer: {
130+
alignItems: "flex-start",
131+
},
132+
bubble: {
133+
maxWidth: "85%",
134+
paddingHorizontal: spacing.md,
135+
paddingVertical: spacing.sm,
136+
borderRadius: borderRadius.lg,
137+
position: "relative",
138+
backgroundColor: isUser ? colors.primary : colors.secondary,
139+
borderBottomRightRadius: isUser ? 6 : borderRadius.lg,
140+
borderBottomLeftRadius: isUser ? borderRadius.lg : 6,
141+
},
142+
messageText: {
143+
fontSize: fontSize.base,
144+
lineHeight: 22,
145+
},
146+
userText: {
147+
color: colors.primaryForeground,
148+
},
149+
timestamp: {
150+
fontSize: fontSize.xs,
151+
marginTop: spacing.xs,
152+
marginHorizontal: spacing.xs,
153+
},
154+
});

0 commit comments

Comments
 (0)