Skip to content

Commit d823b9d

Browse files
committed
AI + Weather
1 parent 66f6e21 commit d823b9d

20 files changed

+1286
-162
lines changed

client/package.json

+8-8
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,25 @@
55
"scripts": {
66
"dev": "conc -c 'auto' 'pnpm:start:*'",
77
"build": "conc -c 'auto' -g 'pnpm:build:*'",
8-
98
"web": "open http://localhost:6206",
109
"ios": "react-native run-ios --no-packager",
1110
"android": "react-native run-android --no-packager",
1211
"macos": "react-native run-macos --no-packager --scheme EXO",
1312
"windows": "react-native run-windows --no-packager",
1413
"visionos": "react-native run-visionos --no-packager",
15-
1614
"build:web": "vite build",
1715
"_build:ios": "react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.ios.jsbundle --assets-dest dist",
1816
"_build:android": "react-native bundle --entry-file index.js --platform android --dev true --bundle-output dist/main.android.jsbundle --assets-dest dist/res",
1917
"_build:macos": "react-native bundle --entry-file index.js --platform macos --dev true --bundle-output dist/main.macos.jsbundle --assets-dest dist",
2018
"_build:windows": "react-native bundle --entry-file index.js --platform windows --dev true --bundle-output dist/main.windows.bundle --assets-dest dist",
2119
"_build:visionos": "react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.visionos.jsbundle --assets-dest dist",
22-
2320
"start:vite": "vite dev --port 6206",
2421
"start:metro": "react-native rnx-start --reset-cache",
25-
2622
"generate": "pod install --project-directory=ios && pod install --project-directory=macos && pod install --project-directory=visionos",
2723
"_postinstall": "pnpm generate"
2824
},
2925
"dependencies": {
26+
"@ai-sdk/openai": "^0.0.34",
3027
"@callstack/react-native-visionos": "^0.73.0",
3128
"@candlefinance/faster-image": "^1.4.3",
3229
"@lingui/core": "^4.10.0",
@@ -38,15 +35,20 @@
3835
"@react-native-community/slider": "^4.5.2",
3936
"@react-native-picker/picker": "^2.7.5",
4037
"@shopify/react-native-skia": "1.3.6",
38+
"ai": "^3.2.15",
4139
"burnt": "^0.12.2",
4240
"design": "workspace:react-exo-ui@*",
41+
"openmeteo": "^1.1.4",
42+
"react": "^18.2.0",
4343
"react-dom": "^18.2.0",
4444
"react-exo": "workspace:*",
4545
"react-exo-ui": "workspace:*",
46+
"react-native": "^0.73.0",
4647
"react-native-gesture-handler": "^2.16.0",
4748
"react-native-get-random-values": "^1.11.0",
4849
"react-native-linear-gradient": "^2.8.3",
4950
"react-native-macos": "^0.73.0",
51+
"react-native-markdown-display": "^7.0.2",
5052
"react-native-mmkv": "^2.12.2",
5153
"react-native-navigation": "7.39.1",
5254
"react-native-reanimated": "^3.8.1",
@@ -57,12 +59,10 @@
5759
"react-native-unistyles": "^2.7.1",
5860
"react-native-url-polyfill": "^2.0.0",
5961
"react-native-video": "5.2.1",
60-
"react-native-web-linear-gradient": "^1.1.2",
6162
"react-native-web": "^0.19.10",
63+
"react-native-web-linear-gradient": "^1.1.2",
6264
"react-native-windows": "^0.73.0",
63-
"react-native": "^0.73.0",
6465
"react-redux": "^9.1.2",
65-
"react": "^18.2.0",
6666
"rive-react-native": "^7.0.0",
6767
"vite-plugin-node-polyfills": "^0.21.0"
6868
},
@@ -80,10 +80,10 @@
8080
"@rnx-kit/metro-plugin-typescript": "^0.4.4",
8181
"@rnx-kit/metro-resolver-symlinks": "^0.1.36",
8282
"@types/babel__core": "^7.20.5",
83+
"@types/react": "^18.2.0",
8384
"@types/react-dom": "^18.2.0",
8485
"@types/react-native-video": "^5.0.20",
8586
"@types/react-test-renderer": "^18.2.0",
86-
"@types/react": "^18.2.0",
8787
"babel-plugin-macros": "^3.1.0",
8888
"babel-plugin-tsconfig-paths-module-resolver": "^1.0.4",
8989
"bundler": "workspace:*",

client/src/app/base/Markdown.tsx

+227
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
import {memo} from 'react';
2+
import {useStyles} from 'design/styles';
3+
import {ScrollView, Platform} from 'react-native';
4+
import Render from 'react-native-markdown-display';
5+
6+
export const Markdown = memo(({text}: {text: string}) => {
7+
const {theme} = useStyles();
8+
9+
if (!text) {
10+
return null;
11+
}
12+
13+
return (
14+
<ScrollView
15+
contentInsetAdjustmentBehavior="automatic"
16+
style={{height: '100%'}}>
17+
<Render
18+
mergeStyle={false}
19+
style={{
20+
body: {
21+
gap: theme.display.space2,
22+
fontFamily: theme.font.family,
23+
letterSpacing: theme.font.spacing,
24+
lineHeight: theme.typography.lineHeight2,
25+
color: theme.colors.foreground,
26+
},
27+
// Headings
28+
heading1: {
29+
flexDirection: 'row',
30+
fontSize: theme.typography.size8,
31+
lineHeight: theme.typography.size8,
32+
letterSpacing: theme.typography.letterSpacing8,
33+
},
34+
heading2: {
35+
flexDirection: 'row',
36+
fontSize: theme.typography.size6,
37+
lineHeight: theme.typography.size6,
38+
letterSpacing: theme.typography.letterSpacing6,
39+
},
40+
heading3: {
41+
flexDirection: 'row',
42+
fontSize: theme.typography.size4,
43+
lineHeight: theme.typography.size4,
44+
letterSpacing: theme.typography.letterSpacing4,
45+
},
46+
heading4: {
47+
flexDirection: 'row',
48+
fontSize: theme.typography.size3,
49+
lineHeight: theme.typography.size3,
50+
letterSpacing: theme.typography.letterSpacing3,
51+
},
52+
heading5: {
53+
flexDirection: 'row',
54+
fontSize: theme.typography.size2,
55+
lineHeight: theme.typography.size2,
56+
letterSpacing: theme.typography.letterSpacing2,
57+
},
58+
heading6: {
59+
flexDirection: 'row',
60+
fontSize: theme.typography.size1,
61+
lineHeight: theme.typography.size1,
62+
letterSpacing: theme.typography.letterSpacing1,
63+
},
64+
// Horizontal Rule
65+
hr: {
66+
height: 1,
67+
backgroundColor: theme.colors.border,
68+
},
69+
// Emphasis
70+
strong: {
71+
fontWeight: 'bold',
72+
},
73+
em: {
74+
fontStyle: 'italic',
75+
},
76+
s: {
77+
textDecorationLine: 'line-through',
78+
},
79+
// Blockquotes
80+
blockquote: {
81+
backgroundColor: theme.colors.background,
82+
borderColor: theme.colors.border,
83+
borderLeftWidth: 4,
84+
marginLeft: theme.display.space2,
85+
paddingHorizontal: theme.display.space2,
86+
borderRadius: theme.display.radius3,
87+
},
88+
// Lists
89+
bullet_list: {},
90+
ordered_list: {},
91+
list_item: {
92+
flexDirection: 'row',
93+
justifyContent: 'flex-start',
94+
},
95+
// @pseudo class, does not have a unique render rule
96+
bullet_list_icon: {
97+
marginLeft: theme.display.space2,
98+
marginRight: theme.display.space2,
99+
},
100+
// @pseudo class, does not have a unique render rule
101+
bullet_list_content: {
102+
flex: 1,
103+
},
104+
// @pseudo class, does not have a unique render rule
105+
ordered_list_icon: {
106+
marginLeft: theme.display.space2,
107+
marginRight: theme.display.space2,
108+
},
109+
// @pseudo class, does not have a unique render rule
110+
ordered_list_content: {
111+
flex: 1,
112+
},
113+
// Code
114+
code_inline: {
115+
borderWidth: 1,
116+
borderColor: theme.colors.border,
117+
lineHeight: theme.font.labelHeight,
118+
paddingVertical: theme.display.space1,
119+
paddingHorizontal: theme.display.space2,
120+
borderRadius: theme.display.radius3,
121+
backgroundColor: theme.colors.card,
122+
color: theme.colors.cardForeground,
123+
...Platform.select({
124+
ios: {
125+
fontFamily: 'Courier',
126+
},
127+
default: {
128+
fontFamily: 'monospace',
129+
},
130+
}),
131+
},
132+
code_block: {
133+
borderWidth: 1,
134+
borderColor: theme.colors.border,
135+
borderRadius: theme.display.radius3,
136+
padding: theme.display.space3,
137+
backgroundColor: theme.colors.card,
138+
color: theme.colors.cardForeground,
139+
...Platform.select({
140+
ios: {
141+
fontFamily: 'Courier',
142+
},
143+
default: {
144+
fontFamily: 'monospace',
145+
},
146+
}),
147+
},
148+
fence: {
149+
borderWidth: 1,
150+
borderColor: theme.colors.border,
151+
borderRadius: theme.display.radius3,
152+
padding: theme.display.space3,
153+
backgroundColor: theme.colors.card,
154+
color: theme.colors.cardForeground,
155+
...Platform.select({
156+
ios: {
157+
fontFamily: 'Courier',
158+
},
159+
default: {
160+
fontFamily: 'monospace',
161+
},
162+
}),
163+
},
164+
// Tables
165+
table: {
166+
borderWidth: 1,
167+
borderColor: theme.colors.border,
168+
borderRadius: theme.display.radius3,
169+
},
170+
thead: {},
171+
tbody: {},
172+
th: {
173+
flex: 1,
174+
padding: theme.display.space2,
175+
},
176+
tr: {
177+
borderBottomWidth: 1,
178+
borderColor: theme.colors.border,
179+
flexDirection: 'row',
180+
},
181+
td: {
182+
flex: 1,
183+
padding: theme.display.space2,
184+
},
185+
// Links
186+
link: {
187+
textDecorationLine: 'underline',
188+
},
189+
blocklink: {
190+
flex: 1,
191+
borderColor: theme.colors.border,
192+
borderBottomWidth: 1,
193+
},
194+
// Images
195+
image: {
196+
flex: 1,
197+
},
198+
// Text Output
199+
text: {},
200+
textgroup: {},
201+
paragraph: {
202+
width: '100%',
203+
flexWrap: 'wrap',
204+
flexDirection: 'row',
205+
alignItems: 'flex-start',
206+
justifyContent: 'flex-start',
207+
marginVertical: theme.display.space3,
208+
fontSize: theme.font.contentSize,
209+
fontWeight: theme.font.contentWeight,
210+
lineHeight: theme.font.contentHeight,
211+
letterSpacing: theme.font.contentSpacing,
212+
},
213+
hardbreak: {
214+
width: '100%',
215+
height: 1,
216+
},
217+
softbreak: {},
218+
// Never used but retained for completeness
219+
pre: {},
220+
inline: {},
221+
span: {},
222+
}}>
223+
{text}
224+
</Render>
225+
</ScrollView>
226+
);
227+
})

client/src/app/base/Menu.tsx

+1-30
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function Menu(props: MenuProps) {
2929
<MenuItem
3030
path="/calendar"
3131
label={t`Calendar`}
32-
icon={<Icon name="ph:calendar"/>}
32+
icon={<Icon name="ph:calendar-dots"/>}
3333
tab={props.tabs}
3434
/>
3535
<MenuItem
@@ -48,35 +48,6 @@ export function Menu(props: MenuProps) {
4848
/>
4949
)}
5050
<View style={styles.fill}/>
51-
{false &&
52-
<>
53-
<MenuItem
54-
path="/media/files"
55-
label={t`Files`}
56-
icon={<Icon name="ph:file-text"/>}
57-
tab={props.tabs}
58-
/>
59-
<MenuItem
60-
path="/media/photos"
61-
label={t`Photos`}
62-
icon={<Icon name="ph:image"/>}
63-
tab={props.tabs}
64-
/>
65-
<MenuItem
66-
path="/media/videos"
67-
label={t`Videos`}
68-
icon={<Icon name="ph:video"/>}
69-
tab={props.tabs}
70-
/>
71-
<MenuItem
72-
path="/media/audio"
73-
label={t`Audio`}
74-
icon={<Icon name="ph:music-notes-simple"/>}
75-
tab={props.tabs}
76-
/>
77-
</>
78-
}
79-
<View style={styles.fill}/>
8051
{hasDevMenu &&
8152
<>
8253
<MenuItem

0 commit comments

Comments
 (0)