Skip to content

Commit 2ae5242

Browse files
author
Wojtach
committed
feat: added view for collection document change listener
1 parent 2a88bcd commit 2ae5242

File tree

3 files changed

+133
-1
lines changed

3 files changed

+133
-1
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import React, { useContext, useState } from 'react';
2+
import { Collection, MutableDocument } from 'cbl-reactnative';
3+
import { useStyleScheme } from '@/components/Themed/Themed';
4+
import { SafeAreaView, View } 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+
import { StyledTextInput } from '@/components/StyledTextInput/StyledTextInput';
11+
import HeaderView from '@/components/HeaderView/HeaderView';
12+
13+
export default function CollectionStatusScreen() {
14+
const { databases } = useContext(DatabaseContext)!;
15+
const [databaseName, setDatabaseName] = useState<string>('');
16+
const [scopeName, setScopeName] = useState<string>('');
17+
const [collectionName, setCollectionName] = useState<string>('');
18+
const [documentID, setDocumentID] = useState<string>('-1');
19+
20+
const [isListenerAdded, setIsListenerAdded] = useState(false);
21+
const [token, setToken] = useState<string>('');
22+
const [collection, setCollection] = useState<Collection | null>(null);
23+
24+
const styles = useStyleScheme();
25+
const navigation = useNavigation();
26+
useNavigationBarTitleOption(
27+
'Collection Document Change Listener',
28+
navigation
29+
);
30+
const [informationMessages, setInformationMessages] = useState<string[]>([]);
31+
32+
async function update(): Promise<void> {
33+
try {
34+
const database = databases[databaseName];
35+
if (database) {
36+
const collection = await database.collection(collectionName, scopeName);
37+
if (collection != null) {
38+
setCollection(collection);
39+
if (!isListenerAdded || token === '') {
40+
setInformationMessages((prev) => [
41+
...prev,
42+
`::Information: Collection <${collection.name}> Starting Document Change listener...`,
43+
]);
44+
const token = await collection.addDocumentChangeListener(
45+
documentID,
46+
(change) => {
47+
const dateString = new Date().toISOString();
48+
const newMessage = `${dateString}::Change:: Document with id: <${change.documentId}> changed in database: <${change.database.getName()}>, collection: <${change.collection.name}>`;
49+
setInformationMessages((prev) => [...prev, newMessage]);
50+
}
51+
);
52+
53+
const saveDocuments = async () => {
54+
const doc1 = new MutableDocument();
55+
doc1.setId(documentID);
56+
doc1.setString('name', 'Alice');
57+
58+
await collection.save(doc1);
59+
};
60+
await saveDocuments();
61+
62+
const fetchedDoc = await collection.document(documentID);
63+
const mutableDoc = MutableDocument.fromDocument(fetchedDoc);
64+
mutableDoc.setString('key', 'value2');
65+
await collection.save(mutableDoc);
66+
67+
setIsListenerAdded(true);
68+
setToken(token);
69+
}
70+
} else {
71+
setInformationMessages((prev) => [
72+
...prev,
73+
`::ERROR: ${scopeName}.${collectionName} not found`,
74+
]);
75+
}
76+
} else {
77+
setInformationMessages((prev) => [
78+
...prev,
79+
`::ERROR: Database ${databaseName} not found`,
80+
]);
81+
}
82+
} catch (error) {
83+
// @ts-ignore
84+
setInformationMessages((prev) => [...prev, `::ERROR: ${error.message}`]);
85+
}
86+
}
87+
88+
async function stop(): Promise<void> {
89+
const database = databases[databaseName];
90+
if (database != null && isListenerAdded && collection) {
91+
await collection.removeChangeListener(token);
92+
setIsListenerAdded(false);
93+
setInformationMessages([
94+
`::Information: Removed Listening for changes od document: ${documentID} on collection: ${collection.name}`,
95+
]);
96+
}
97+
setToken('');
98+
setDatabaseName('');
99+
setCollectionName('');
100+
setScopeName('');
101+
}
102+
103+
return (
104+
<SafeAreaView style={styles.container}>
105+
<DatabaseScopeCollectionActionForm
106+
databaseName={databaseName}
107+
setDatabaseName={setDatabaseName}
108+
scopeName={scopeName}
109+
setScopeName={setScopeName}
110+
collectionName={collectionName}
111+
setCollectionName={setCollectionName}
112+
handleUpdatePressed={update}
113+
handleStopPressed={stop}
114+
/>
115+
<HeaderView name="Document ID" iconName="file-document" />
116+
<View style={styles.component}>
117+
<StyledTextInput
118+
autoCapitalize="none"
119+
placeholder="Document ID"
120+
onChangeText={(newText) => setDocumentID(newText)}
121+
defaultValue={documentID}
122+
/>
123+
</View>
124+
<ResultListView useScrollView={true} messages={informationMessages} />
125+
</SafeAreaView>
126+
);
127+
}

expo-example/hooks/useCollectionNavigationSections.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ export function useCollectionNavigationSections() {
5151
title: 'Collection Change Listener',
5252
path: '/collection/changeListener',
5353
},
54+
{
55+
id: 15,
56+
title: 'Collection Document Change Listener',
57+
path: '/collection/documentChangeListener',
58+
},
5459
],
5560
},
5661
{

0 commit comments

Comments
 (0)