Skip to content

Commit ac18546

Browse files
author
Wojtach
committed
feat: added collection change listener view
1 parent dd6d1c7 commit ac18546

File tree

4 files changed

+123
-0
lines changed

4 files changed

+123
-0
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import React, { useContext, useState } from 'react';
2+
import { Collection, MutableDocument } from 'cbl-reactnative';
3+
import { useStyleScheme } from '@/components/Themed/Themed';
4+
import { SafeAreaView } from 'react-native';
5+
import ResultListView from '@/components/ResultsListView/ResultsListView';
6+
import DatabaseScopeCollectionActionForm from '@/components/DatabaseScopeCollectionActionForm/DatabaseScopeCollectionActionForm';
7+
import useNavigationBarTitleOption from '@/hooks/useNativgationBarTitle';
8+
import { useNavigation } from '@react-navigation/native';
9+
import DatabaseContext from '@/providers/DatabaseContext';
10+
11+
export default function CollectionStatusScreen() {
12+
const { databases } = useContext(DatabaseContext)!;
13+
const [databaseName, setDatabaseName] = useState<string>('');
14+
const [scopeName, setScopeName] = useState<string>('');
15+
const [collectionName, setCollectionName] = useState<string>('');
16+
17+
const [isListenerAdded, setIsListenerAdded] = useState(false);
18+
const [token, setToken] = useState<string>('');
19+
const [collection, setCollection] = useState<Collection | null>(null);
20+
21+
const styles = useStyleScheme();
22+
const navigation = useNavigation();
23+
useNavigationBarTitleOption('Collection Change Listener', navigation);
24+
const [informationMessages, setInformationMessages] = useState<string[]>([]);
25+
26+
async function update(): Promise<void> {
27+
try {
28+
const database = databases[databaseName];
29+
if (database) {
30+
const collection = await database.collection(collectionName, scopeName);
31+
if (collection != null) {
32+
setCollection(collection);
33+
if (!isListenerAdded || token === '') {
34+
setInformationMessages((prev) => [
35+
...prev,
36+
`::Information: Collection <${collection.name}> Starting Change listener...`,
37+
]);
38+
const token = await collection.addChangeListener((change) => {
39+
for (const doc of change.documentIDs) {
40+
const dateString = new Date().toISOString();
41+
const newMessage = `${dateString}::Change:: Collection <${collection.name}> changed: ${doc}`;
42+
setInformationMessages((prev) => [...prev, newMessage]);
43+
}
44+
});
45+
46+
const saveDocuments = async () => {
47+
const doc1 = new MutableDocument();
48+
const doc2 = new MutableDocument();
49+
doc1.setId('doc1');
50+
doc1.setString('name', 'Alice');
51+
doc2.setId('doc2');
52+
doc2.setString('name', 'tdbGamer');
53+
await collection.save(doc1);
54+
await collection.save(doc2);
55+
};
56+
await saveDocuments();
57+
setIsListenerAdded(true);
58+
setToken(token);
59+
}
60+
} else {
61+
setInformationMessages((prev) => [
62+
...prev,
63+
`::ERROR: ${scopeName}.${collectionName} not found`,
64+
]);
65+
}
66+
} else {
67+
setInformationMessages((prev) => [
68+
...prev,
69+
`::ERROR: Database ${databaseName} not found`,
70+
]);
71+
}
72+
} catch (error) {
73+
// @ts-ignore
74+
setInformationMessages((prev) => [...prev, `::ERROR: ${error.message}`]);
75+
}
76+
}
77+
78+
async function stop(): Promise<void> {
79+
const database = databases[databaseName];
80+
if (database != null && isListenerAdded && collection) {
81+
await collection.removeChangeListener(token);
82+
setIsListenerAdded(false);
83+
setInformationMessages([
84+
`::Information: Removed Listening for changes on collection: ${collection.name}`,
85+
]);
86+
}
87+
setToken('');
88+
setDatabaseName('');
89+
setCollectionName('');
90+
setScopeName('');
91+
}
92+
93+
return (
94+
<SafeAreaView style={styles.container}>
95+
<DatabaseScopeCollectionActionForm
96+
databaseName={databaseName}
97+
setDatabaseName={setDatabaseName}
98+
scopeName={scopeName}
99+
setScopeName={setScopeName}
100+
collectionName={collectionName}
101+
setCollectionName={setCollectionName}
102+
handleUpdatePressed={update}
103+
handleStopPressed={stop}
104+
/>
105+
<ResultListView useScrollView={true} messages={informationMessages} />
106+
</SafeAreaView>
107+
);
108+
}

expo-example/components/DatabaseScopeCollectionActionForm/DatabaseScopeCollectionActionForm.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,22 @@ export default function DatabaseScopeCollectionActionForm({
1111
collectionName,
1212
setCollectionName,
1313
handleUpdatePressed,
14+
handleStopPressed,
1415
style,
1516
}: DatabaseScopeCollectionActionFormProps) {
1617
const icons = [
1718
{
1819
iconName: 'play',
1920
onPress: handleUpdatePressed,
2021
},
22+
...(handleStopPressed
23+
? [
24+
{
25+
iconName: 'stop',
26+
onPress: handleStopPressed,
27+
},
28+
]
29+
: []),
2130
];
2231
return (
2332
<>

expo-example/components/DatabaseScopeCollectionActionForm/databaseScopeCollectionActionFormProps.type.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ export type DatabaseScopeCollectionActionFormProps = {
66
collectionName: string;
77
setCollectionName: (arg: string) => void;
88
handleUpdatePressed: () => void;
9+
handleStopPressed?: () => void;
910
style?: object;
1011
};

expo-example/hooks/useCollectionNavigationSections.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ export function useCollectionNavigationSections() {
4646
title: 'List Collections',
4747
path: '/collection/list',
4848
},
49+
{
50+
id: 14,
51+
title: 'Collection Change Listener',
52+
path: '/collection/changeListener',
53+
},
4954
],
5055
},
5156
{

0 commit comments

Comments
 (0)