Skip to content

Commit d62f367

Browse files
DominicGBauerDominicGBauer
andauthored
feat(react): add useQuery and useStatus hooks (#142)
Co-authored-by: DominicGBauer <dominic@nomanini.com>
1 parent cbd0ce1 commit d62f367

File tree

33 files changed

+453
-139
lines changed

33 files changed

+453
-139
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"react-native-supabase-group-chat": minor
3+
"react-native-supabase-todolist": minor
4+
"yjs-react-supabase-text-collab": minor
5+
"django-react-native-todolist": minor
6+
"react-supabase-todolist": minor
7+
"example-nextjs": minor
8+
"@powersync/react": minor
9+
---
10+
11+
Deprecate usePowerSyncStatus, usePowerSyncQuery and usePowerSyncWatchedQuery in favor of useQuery and useStatus

demos/django-react-native-todolist/library/widgets/HeaderWidget.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Alert, Text } from 'react-native';
33
import { Icon } from 'react-native-elements';
44
import { useNavigation } from 'expo-router';
55
import { useSystem } from '../stores/system';
6-
import { usePowerSyncStatus } from '@powersync/react';
6+
import { useStatus } from '@powersync/react';
77
import { Header } from 'react-native-elements';
88
import { observer } from 'mobx-react-lite';
99
import { DrawerActions } from '@react-navigation/native';
@@ -13,7 +13,7 @@ export const HeaderWidget: React.FC<{
1313
}> = observer((props) => {
1414
const { title } = props;
1515
const { powersync } = useSystem();
16-
const status = usePowerSyncStatus();
16+
const status = useStatus();
1717
const navigation = useNavigation();
1818

1919
return (

demos/example-nextjs/src/app/page.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@
22

33
import React, { useEffect } from 'react';
44
import { CircularProgress, Grid, ListItem, styled } from '@mui/material';
5-
import { useRouter } from 'next/navigation';
6-
import { usePowerSync, usePowerSyncWatchedQuery } from '@powersync/react';
5+
import { usePowerSync, useQuery } from '@powersync/react';
76

87
export default function EntryPage() {
9-
const router = useRouter();
108
const db = usePowerSync();
11-
const customers = usePowerSyncWatchedQuery('SELECT id, name FROM customers');
9+
const { data: customers, isLoading } = useQuery('SELECT id, name FROM customers');
1210

1311
useEffect(() => {
1412
// Insert some test data
@@ -18,6 +16,10 @@ export default function EntryPage() {
1816
return () => {};
1917
}, []);
2018

19+
if (isLoading) {
20+
return <CircularProgress />;
21+
}
22+
2123
return (
2224
<S.MainGrid container>
2325
<S.CenteredGrid item xs={12} md={6} lg={5}>

demos/react-native-supabase-group-chat/src/app/(app)/(chats)/c/[profile]/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { faker } from '@faker-js/faker';
2-
import { usePowerSync, usePowerSyncWatchedQuery } from '@powersync/react-native';
2+
import { usePowerSync, useQuery } from '@powersync/react-native';
33
import { FlashList } from '@shopify/flash-list';
44
import { Stack, useLocalSearchParams } from 'expo-router';
55
import { useEffect, useState } from 'react';
@@ -13,12 +13,12 @@ export default function ChatsChatIndex() {
1313
const { profile: profileId } = useLocalSearchParams<{ profile: string }>();
1414
const { user } = useAuth();
1515
const powerSync = usePowerSync();
16-
const profiles = usePowerSyncWatchedQuery('SELECT id, name, handle, demo FROM profiles WHERE id = ?', [profileId]);
16+
const { data: profiles } = useQuery('SELECT id, name, handle, demo FROM profiles WHERE id = ?', [profileId]);
1717
const profile = profiles.length ? profiles[0] : undefined;
1818
const [draftId, setDraftId] = useState<string>();
1919
const [listMessages, setListMessages] = useState<any[]>([]);
2020

21-
const messages = usePowerSyncWatchedQuery(
21+
const { data: messages } = useQuery(
2222
'SELECT sender_id, content, created_at FROM messages WHERE (((sender_id = ?1 AND recipient_id = ?2) OR (sender_id = ?2 AND recipient_id = ?1)) AND NOT (sender_id = ?1 AND sent_at IS NULL)) ORDER BY created_at ASC',
2323
[user?.id, profile?.id]
2424
);

demos/react-native-supabase-group-chat/src/app/(app)/(chats)/g/[group]/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { usePowerSync, usePowerSyncWatchedQuery } from '@powersync/react-native';
1+
import { usePowerSync, useQuery } from '@powersync/react-native';
22
import { FlashList } from '@shopify/flash-list';
33
import { Stack, useLocalSearchParams } from 'expo-router';
44
import { useState } from 'react';
@@ -12,10 +12,10 @@ export default function ChatsChatIndex() {
1212
const { group: groupId } = useLocalSearchParams<{ group: string }>();
1313
const { user } = useAuth();
1414
const powerSync = usePowerSync();
15-
const groups = usePowerSyncWatchedQuery('SELECT id, name FROM groups WHERE id = ?', [groupId]);
15+
const { data: groups } = useQuery('SELECT id, name FROM groups WHERE id = ?', [groupId]);
1616
const group = groups.length ? groups[0] : undefined;
1717

18-
const messages = usePowerSyncWatchedQuery(
18+
const { data: messages } = useQuery(
1919
'SELECT sender_id, content, created_at FROM messages WHERE group_id = ? ORDER BY created_at ASC',
2020
[group?.id]
2121
);

demos/react-native-supabase-group-chat/src/app/(app)/(chats)/g/[group]/settings.tsx

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { usePowerSync, usePowerSyncWatchedQuery } from '@powersync/react-native';
1+
import { usePowerSync, useQuery } from '@powersync/react-native';
22
import { Save, Trash, XCircle } from '@tamagui/lucide-icons';
33
import { useLocalSearchParams, useRouter } from 'expo-router';
44
import { useEffect, useState } from 'react';
@@ -16,8 +16,8 @@ export default function GroupSettings() {
1616
const [selectedContacts, setSelectedContacts] = useState<Set<string>>(new Set());
1717
const powerSync = usePowerSync();
1818

19-
const groups = usePowerSyncWatchedQuery('SELECT name FROM groups WHERE id = ?', [groupId]);
20-
const groupMembers = usePowerSyncWatchedQuery('SELECT profile_id FROM memberships WHERE group_id = ?', [groupId]);
19+
const { data: groups } = useQuery('SELECT name FROM groups WHERE id = ?', [groupId]);
20+
const { data: groupMembers } = useQuery('SELECT profile_id FROM memberships WHERE group_id = ?', [groupId]);
2121

2222
useEffect(() => {
2323
if (groups.length > 0) {
@@ -74,16 +74,13 @@ export default function GroupSettings() {
7474

7575
await powerSync.writeTransaction(async (tx) => {
7676
try {
77-
await tx.executeAsync('UPDATE groups SET name= ? WHERE id = ?', [name, groupId]);
77+
await tx.execute('UPDATE groups SET name= ? WHERE id = ?', [name, groupId]);
7878
for (const profileId of removedContacts) {
79-
const result = await tx.executeAsync('DELETE FROM memberships WHERE group_id = ? AND profile_id = ?', [
80-
groupId,
81-
profileId
82-
]);
79+
await tx.execute('DELETE FROM memberships WHERE group_id = ? AND profile_id = ?', [groupId, profileId]);
8380
}
8481
for (const profileId of addedContacts) {
8582
const membershipId = uuid();
86-
const result = await tx.executeAsync(
83+
await tx.execute(
8784
'INSERT INTO memberships (id, group_id, profile_id, created_at) VALUES (?, ?, ?, datetime())',
8885
[membershipId, groupId, profileId]
8986
);
@@ -99,9 +96,9 @@ export default function GroupSettings() {
9996
async function deleteTransaction() {
10097
await powerSync.writeTransaction(async (tx) => {
10198
try {
102-
await tx.executeAsync('DELETE FROM memberships WHERE group_id = ?', [groupId]);
103-
await tx.executeAsync('DELETE FROM messages WHERE group_id = ?', [groupId]);
104-
await tx.executeAsync('DELETE FROM groups WHERE id = ?', [groupId]);
99+
await tx.execute('DELETE FROM memberships WHERE group_id = ?', [groupId]);
100+
await tx.execute('DELETE FROM messages WHERE group_id = ?', [groupId]);
101+
await tx.execute('DELETE FROM groups WHERE id = ?', [groupId]);
105102

106103
router.back();
107104
} catch (error) {
@@ -148,8 +145,7 @@ export default function GroupSettings() {
148145
backgroundColor="$red10"
149146
color="white"
150147
onPress={handleDelete}
151-
margin="$3"
152-
>
148+
margin="$3">
153149
Delete group
154150
</Button>
155151
</YStack>

demos/react-native-supabase-group-chat/src/app/(app)/(chats)/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { usePowerSync, usePowerSyncWatchedQuery } from '@powersync/react-native';
1+
import { usePowerSync, useQuery } from '@powersync/react-native';
22
import { MessageSquare, Plus } from '@tamagui/lucide-icons';
33
import { Link, useNavigation } from 'expo-router';
44
import { useEffect, useState } from 'react';
@@ -24,7 +24,7 @@ export default function ChatsIndex() {
2424
return unsubscribe;
2525
}, [navigation]);
2626

27-
const chats = usePowerSyncWatchedQuery(
27+
const { data: chats } = useQuery(
2828
`SELECT profiles.id as partner_id, profiles.name as name, profiles.handle as handle, 'contact' as type, m.created_at as last_message_at FROM chats LEFT JOIN profiles on chats.id = profiles.id LEFT JOIN (SELECT * FROM messages WHERE (sender_id, recipient_id, created_at) IN (SELECT sender_id, recipient_id, MAX(created_at) FROM messages GROUP BY group_id)) as m ON m.recipient_id = chats.id OR m.sender_id = chats.id WHERE (name LIKE '%' || ?1 || '%' OR handle LIKE '%' || ?1 || '%') GROUP BY profiles.id UNION
2929
SELECT groups.id as partner_id, groups.name as name, '' as handle, 'group' as type, m.created_at as last_message_at FROM groups LEFT JOIN (SELECT * FROM messages WHERE (group_id, created_at) IN (SELECT group_id, MAX(created_at) FROM messages GROUP BY group_id)) as m ON m.group_id = groups.id WHERE (name LIKE '%' || ?1 || '%') GROUP BY groups.id ORDER BY last_message_at DESC`,
3030
[search]

demos/react-native-supabase-group-chat/src/app/(app)/contacts/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { faker } from '@faker-js/faker';
2-
import { usePowerSync, usePowerSyncWatchedQuery } from '@powersync/react-native';
2+
import { usePowerSync, useQuery } from '@powersync/react-native';
33
import { Search, Shuffle } from '@tamagui/lucide-icons';
44
import { useState } from 'react';
55
import { Button, Input, XStack, YStack } from 'tamagui';
@@ -17,7 +17,7 @@ export default function ContactsIndex() {
1717
const [search, setSearch] = useState<string>('');
1818
const [profiles, setProfiles] = useState<any[]>([]);
1919

20-
const contacts = usePowerSyncWatchedQuery(
20+
const { data: contacts } = useQuery(
2121
"SELECT contacts.id, profiles.id as profile_id, profiles.name, profiles.handle, 'contact' as type FROM contacts LEFT JOIN profiles ON contacts.profile_id = profiles.id WHERE (profiles.name LIKE '%' || ?1 || '%' OR profiles.handle LIKE '%' || ?1 || '%') ORDER BY name ASC",
2222
[search]
2323
);

demos/react-native-supabase-group-chat/src/app/(app)/settings/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { usePowerSync, usePowerSyncWatchedQuery } from '@powersync/react-native';
1+
import { usePowerSync, useQuery } from '@powersync/react-native';
22
import { useEffect, useState } from 'react';
33
import { Button, Input, Label, Switch, Text, XStack, YStack } from 'tamagui';
44

@@ -10,7 +10,7 @@ export default function SettingsIndex() {
1010
const [name, setName] = useState('');
1111
const [handle, setHandle] = useState('');
1212

13-
const profiles = usePowerSyncWatchedQuery('SELECT * FROM profiles WHERE id = ?', [user?.id]);
13+
const { data: profiles } = useQuery('SELECT * FROM profiles WHERE id = ?', [user?.id]);
1414

1515
useEffect(() => {
1616
if (profiles.length > 0) {

demos/react-native-supabase-group-chat/src/components/groups/MemberSelector.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { usePowerSyncWatchedQuery } from '@powersync/react-native';
1+
import { useQuery } from '@powersync/react-native';
22
import { CheckCircle2, Circle } from '@tamagui/lucide-icons';
33
import { useState } from 'react';
44
import { Input, ListItem, XStack, YStack } from 'tamagui';
@@ -15,7 +15,7 @@ export function MemberSelector({
1515
}) {
1616
const [search, setSearch] = useState<string>('');
1717

18-
const contacts = usePowerSyncWatchedQuery(
18+
const { data: contacts } = useQuery(
1919
"SELECT contacts.id, profiles.id as profile_id, profiles.name, profiles.handle, 'contact' as type FROM contacts LEFT JOIN profiles ON contacts.profile_id = profiles.id WHERE (profiles.name LIKE '%' || ?1 || '%' OR profiles.handle LIKE '%' || ?1 || '%') ORDER BY name ASC",
2020
[search]
2121
);

0 commit comments

Comments
 (0)