Skip to content

Commit

Permalink
Misc
Browse files Browse the repository at this point in the history
  • Loading branch information
TheUltDev committed Jul 14, 2024
1 parent f143bd4 commit 4697f24
Show file tree
Hide file tree
Showing 20 changed files with 656 additions and 430 deletions.
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@lingui/react": "^4.11.2",
"@marceloterreiro/flash-calendar": "^1.0.0",
"@react-native-community/checkbox": "^0.5.17",
"@react-native-community/geolocation": "^3.3.0",
"@react-native-community/netinfo": "^11.3.2",
"@react-native-community/slider": "^4.5.2",
"@react-native-picker/picker": "^2.7.7",
Expand Down
2 changes: 1 addition & 1 deletion client/src/app/base/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export function Menu(props: MenuProps) {
const stylesheet = createStyleSheet(theme => ({
bg: {
flex: 1,
backgroundColor: theme.colors.secondary,
backgroundColor: theme.colors.background,
},
root: {
flex: 1,
Expand Down
2 changes: 1 addition & 1 deletion client/src/app/base/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function MenuItem(props: MenuItemProps) {
const itemActive = props.path === decodeURIComponent(pathname);
const isDarkMode = scheme === 'dark';
const backgroundColor = isDarkMode
? 'rgba(255, 255, 255, 0.15)'
? 'rgba(255, 255, 255, 0.09)'
: 'rgba(0, 0, 0, 0.07)';

return (
Expand Down
2 changes: 1 addition & 1 deletion client/src/app/base/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ const stylesheet = createStyleSheet(theme => ({
alignSelf: 'center',
gap: theme.display.space5,
padding: theme.display.space5,
backgroundColor: theme.colors.background,
minWidth: {
initial: '100%',
md: 900,
Expand All @@ -67,6 +66,7 @@ const stylesheet = createStyleSheet(theme => ({
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'flex-start',
marginTop: theme.display.space5,
marginBottom: theme.display.space3,
},
title: {
Expand Down
24 changes: 20 additions & 4 deletions client/src/app/data/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ export * from './schema';

export const createDatabase = () => _.createEvolu($.Database, {
indexes: $.indexes,
...(__DEV__ && {syncUrl: 'http://localhost:4000'}),
syncUrl: __DEV__
? 'http://localhost:4000'
: 'https://evolu.world',
initialData: (evolu) => {
// Initial profile for new account
evolu.create('profile', {
Expand Down Expand Up @@ -36,15 +38,15 @@ export function Database(props: React.PropsWithChildren) {
)
}

export const profile = evolu.createQuery((db) => db
export const profile = evolu.createQuery(db => db
.selectFrom('profile')
.select(['id', 'name', 'groqKey', 'groqModel'])
.where('isDeleted', 'is not', _.cast(true))
.orderBy('createdAt')
.limit(1)
);

export const label = evolu.createQuery((db) => db
export const label = evolu.createQuery(db => db
.selectFrom('label')
.select(['id', 'name', 'data'])
.where('isDeleted', 'is not', _.cast(true))
Expand All @@ -54,7 +56,21 @@ export const label = evolu.createQuery((db) => db
.orderBy('createdAt')
);

export const note = evolu.createQuery((db) => db
export const prompts = evolu.createQuery(db => db
.selectFrom('aiPrompt')
.select(['id'])
.where('isDeleted', 'is not', _.cast(true))
.orderBy('createdAt')
);

export const prompt = evolu.createQuery(db => db
.selectFrom('aiPrompt')
.select(['id', 'model', 'prompt', 'response', 'isMultiline', 'createdAt'])
.where('isDeleted', 'is not', _.cast(true))
.limit(1)
);

export const note = evolu.createQuery(db => db
.selectFrom('todo')
.select(['id', 'title', 'isCompleted', 'labelId'])
.where('isDeleted', 'is not', _.cast(true))
Expand Down
3 changes: 0 additions & 3 deletions client/src/app/data/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export const NonEmptyString50 = _.String.pipe(
export type LabelData = typeof LabelData.Type;
export const LabelData = S.Struct({icon: S.String, color: S.String});


/**
* Ids
*/
Expand Down Expand Up @@ -68,7 +67,6 @@ export const LabelTable = _.table({
data: S.NullOr(LabelData),
});


/**
* Databases
*/
Expand All @@ -81,7 +79,6 @@ export const Database = _.database({
todo: TodoTable,
});


/**
* Indexes
*
Expand Down
77 changes: 72 additions & 5 deletions client/src/events/routes/ScreenCalendar.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,101 @@
import {View} from 'react-native';
import {Trans} from '@lingui/macro';
import {Icon} from 'react-exo/icon';
import {View, Text} from 'react-native';
import {useStyles, createStyleSheet} from 'react-native-unistyles';
import {useDateRange, toDateId, Calendar} from 'react-exo/calendar';
import {useCalendarTheme} from 'events/hooks/useCalendarTheme';
import {useLocale} from 'settings/hooks/useLocale';
import {Alert} from 'design';

const today = toDateId(new Date());

export default function ScreenCalendar() {
const {styles} = useStyles(stylesheet);
const calendarTheme = useCalendarTheme();
const [locale] = useLocale();
const range = useDateRange();
const theme = useCalendarTheme();

const hasEvent = false;
const demoEventStartDate = new Date('2024-07-28T12:00:00');
const demoEventEndDate = new Date('2024-07-28T14:00:00');
const demoEventTitle = 'Birthday – Shiner, TX';
const demoEventDesc = demoEventStartDate.toLocaleDateString(locale, {
weekday: 'short',
month: 'long',
day: 'numeric',
}) + ' • ' + demoEventStartDate.toLocaleTimeString(locale, {
hour: 'numeric',
minute: '2-digit',
}) + ' - ' + demoEventEndDate.toLocaleTimeString(locale, {
hour: 'numeric',
minute: '2-digit',
});

return (
<View style={styles.root}>
<Calendar.List
theme={theme}
theme={calendarTheme}
calendarFormatLocale={locale}
calendarInitialMonthId={today}
calendarActiveDateRanges={range.calendarActiveDateRanges}
onCalendarDayPress={range.onCalendarDayPress}
/>
<View style={styles.panel}>
{hasEvent
? <Alert
mode="Default"
header={demoEventTitle}
body={demoEventDesc}
hasIcon
icon={
<Icon name="ph:cake"/>
}
/>
: <View style={styles.empty}>
<Text style={styles.emptyText}>
<Trans>No events scheduled.</Trans>
</Text>
</View>
}
</View>
</View>
);
}

const stylesheet = createStyleSheet(theme => ({
root: {
flex: 1,
maxWidth: 800,
paddingHorizontal: theme.display.space5,
flexDirection: {
initial: 'column',
xs: 'row',
},
},
panel: {
flex: 1,
gap: theme.display.space3,
flexWrap: 'wrap',
padding: theme.display.space5,
borderColor: theme.colors.secondary,
borderLeftWidth: {
initial: 0,
xs: 1,
},
borderTopWidth: {
initial: 1,
xs: 0,
},
},
empty: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
emptyText: {
fontFamily: theme.font.family,
fontSize: theme.font.contentSize,
fontWeight: theme.font.contentWeight,
lineHeight: theme.font.contentHeight,
letterSpacing: theme.font.contentSpacing,
color: theme.colors.mutedForeground,
},
}));
18 changes: 9 additions & 9 deletions client/src/home/base/AiPrompt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import {useRef, useState} from 'react';
import {useStyles, createStyleSheet} from 'react-native-unistyles';
import {Text, View, TextInput, Pressable} from 'react-native';
import {Link} from 'react-exo/navigation';
import {Icon} from 'react-exo/icon';
import {Markdown} from 'app/base/Markdown';
import {PageLoading} from 'app/base/PageLoading';
import {formatDate} from 'home/utils/time';
import {useAI} from 'home/hooks/useAI';
import {Icon} from 'react-exo/icon';
import {profile} from 'app/data';

const DEFAULT_MODEL = 'llama3-8b-8192';
Expand All @@ -22,7 +22,7 @@ export function AiPrompt() {
const apiKey = row?.groqKey || '';
const model = row?.groqModel || DEFAULT_MODEL;
const input = useRef<TextInput>(null);
const ai = useAI(apiKey, model, input);
const ai = useAI(input, model, apiKey);

return (
<>
Expand All @@ -31,15 +31,15 @@ export function AiPrompt() {
<View style={styles.wrapper}>
<TextInput
style={styles.input}
value={ai.response?.[0]}
multiline={ai.response?.[3]}
numberOfLines={ai.response?.[3] ? 8 : undefined}
value={ai.response?.prompt ?? ''}
multiline={ai.response?.isMultiline ? true : false}
numberOfLines={ai.response?.isMultiline ? 8 : undefined}
onKeyPress={(e) => ai.navigate(e)}
autoFocus
readOnly
/>
<Text style={styles.timestamp}>
{`${formatDate(new Date(ai.response?.[2]))} (${ai.response?.[4] ?? DEFAULT_MODEL})`}
{`${formatDate(new Date(ai.response?.createdAt ?? ''))} (${ai.response?.model ?? DEFAULT_MODEL})`}
</Text>
</View>
}
Expand All @@ -50,7 +50,7 @@ export function AiPrompt() {
style={styles.input}
placeholder={apiKey ? t(i18n)`Ask anything...` : t(i18n)`Please set your Groq API Key`}
placeholderTextColor={theme.colors.mutedForeground}
onSubmitEditing={(e) => e.nativeEvent.text && ai.prompt(e.nativeEvent.text, multiline)}
onSubmitEditing={(e) => e.nativeEvent.text && ai.promptText(e.nativeEvent.text, multiline)}
onKeyPress={(e) => ai.navigate(e, multiline ? () => setMultiline(false) : undefined)}
blurOnSubmit={false}
multiline={multiline}
Expand Down Expand Up @@ -89,7 +89,7 @@ export function AiPrompt() {
onPress={() => {
// @ts-ignore
const text = input.current?.value;
if (text) ai.prompt(text, true);
if (text) ai.promptText(text, true);
}}>
<Icon
name="ph:paper-plane-right"
Expand All @@ -103,7 +103,7 @@ export function AiPrompt() {
</View>
<View style={styles.response}>
{ai.dirty && ai.response && !ai.loading &&
<Markdown text={ai.response[1]}/>
<Markdown text={ai.response?.response ?? ''}/>
}
{ai.loading &&
<PageLoading indicator={{size: 'small'}}/>
Expand Down
52 changes: 23 additions & 29 deletions client/src/home/hooks/useAI.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,49 @@
import {t} from '@lingui/macro';
import {generateText} from 'ai';
import {createOpenAI} from '@ai-sdk/openai';
import {useState, useMemo, useCallback} from 'react';
import {useDispatch, useSelector} from 'react-redux';
import {useQuery, useEvolu, cast} from '@evolu/react-native';
import {useLingui} from '@lingui/react';
import {prompts, prompt} from 'app/data';
import {toast} from 'react-exo/toast';

import home from 'home/store';

const baseURL = 'https://api.groq.com/openai/v1';

import type {State} from 'app/store';
import type {TextInput, NativeSyntheticEvent, TextInputKeyPressEventData} from 'react-native';

export function useAI(
apiKey: string,
model: string,
input: React.RefObject<TextInput>,
model: string,
apiKey: string,
) {
const [index, setIndex] = useState<number | null>(null);
const [dirty, setDirty] = useState(false);
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
const provider = useMemo(() => createOpenAI({baseURL, apiKey}), [apiKey]);
const response = useSelector((state: State) => home.selectors.getPrompt(state, index ?? 1));
const history = useSelector(home.selectors.getPromptCount);
const apiModel = useMemo(() => provider(model), [model, provider]);
//const response = useSelector((state: State) => home.selectors.getPrompt(state, index ?? 1));
const {create} = useEvolu();
const {rows} = useQuery(prompts);
const {row} = useQuery(prompt);
const {i18n} = useLingui();

const prompt = useCallback(async (prompt: string, multiLine?: boolean) => {
const promptText = useCallback(async (prompt: string, multi: boolean = false) => {
setLoading(true);
if (prompt.length > 0) {
try {
const {text} = await generateText({
model: provider(model),
prompt,
});
dispatch(home.actions.addPrompt([
prompt,
text,
Date.now(),
multiLine ?? false,
model,
]));
const {text} = await generateText({model: apiModel, prompt});
create('prompts', {prompt, text, model, isMultiLine: cast(multi)});
setDirty(true);
} catch (e) {
toast({
title: 'Groq Failure',
message: (e as Error).message,
preset: 'error',
title: t(i18n)`Groq Failure`,
message: (e as Error).message,
});
}
}
setLoading(false);
}, [model]);
}, [apiModel]);

const navigate = useCallback((
e: NativeSyntheticEvent<TextInputKeyPressEventData>,
Expand All @@ -66,7 +60,7 @@ export function useAI(
e.preventDefault();
} else if (key === 'ArrowUp') {
if (clearMulti) return;
if (i >= history) return;
if (i >= rows.length) return;
setDirty(true);
setIndex(i + 1);
e.preventDefault();
Expand All @@ -78,14 +72,14 @@ export function useAI(
input.current?.clear();
input.current?.focus();
}
}, [index, history]);
}, [index, rows]);

return {
response,
loading,
prompt,
promptText,
dirty,
navigate,
archive: response && index !== null,
response: row,
archive: row && index !== null,
};
}
Loading

0 comments on commit 4697f24

Please sign in to comment.