Compare commits
235 Commits
jazz-svelt
...
authv2-can
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
498954fd09 | ||
|
|
198f6d3627 | ||
|
|
f701f2a4f4 | ||
|
|
94131ba6d6 | ||
|
|
c0e892313f | ||
|
|
b426342c02 | ||
|
|
bbbd773c3f | ||
|
|
7d5f4e5881 | ||
|
|
29c44538dc | ||
|
|
198f995b21 | ||
|
|
2d639667a3 | ||
|
|
1be017d69d | ||
|
|
03df4fee8e | ||
|
|
c658ed3404 | ||
|
|
99e58e60dc | ||
|
|
a9ad0284e9 | ||
|
|
6e2d791c4b | ||
|
|
f9be857bbb | ||
|
|
1288ac140e | ||
|
|
7f07f7e049 | ||
|
|
b22589bbad | ||
|
|
be144adeee | ||
|
|
513619b04e | ||
|
|
81f6a75aac | ||
|
|
913d03de75 | ||
|
|
2d0172d839 | ||
|
|
27d46641e3 | ||
|
|
1014816d79 | ||
|
|
441194acb7 | ||
|
|
c9bea7200f | ||
|
|
9eaa88bd83 | ||
|
|
6ada48d57a | ||
|
|
8fa978df21 | ||
|
|
df7356fd24 | ||
|
|
153fa4ce44 | ||
|
|
6105bd2c88 | ||
|
|
c06d63eec1 | ||
|
|
4ee7359370 | ||
|
|
7b5c47b377 | ||
|
|
7ad57e88f3 | ||
|
|
c181e55557 | ||
|
|
5574be699b | ||
|
|
b3142cb8ed | ||
|
|
cb08d9d1a3 | ||
|
|
7e0cd721e6 | ||
|
|
4d01cbae03 | ||
|
|
13f6389559 | ||
|
|
f6ea9bcc50 | ||
|
|
f6f2766eac | ||
|
|
f8f63bface | ||
|
|
5ec561fec4 | ||
|
|
277787cbd2 | ||
|
|
dda4336721 | ||
|
|
59ddff40ab | ||
|
|
064d19b48c | ||
|
|
3ea269f4d8 | ||
|
|
c4b8befe27 | ||
|
|
06f667ef2a | ||
|
|
bac3cc7bf8 | ||
|
|
6ad0a9f886 | ||
|
|
9b12932b66 | ||
|
|
82bb0d51d9 | ||
|
|
39dede92e8 | ||
|
|
84f4e6e48d | ||
|
|
e629dea585 | ||
|
|
2faf22ffff | ||
|
|
2273505a13 | ||
|
|
19eb29d831 | ||
|
|
738c4c2bd7 | ||
|
|
64e2273475 | ||
|
|
5a85c89154 | ||
|
|
8898b10e89 | ||
|
|
dc2d4e25f7 | ||
|
|
9275c4f6c0 | ||
|
|
cb75cc62b2 | ||
|
|
b141f6a62f | ||
|
|
4a251a528c | ||
|
|
ac3c2df474 | ||
|
|
681f973d4b | ||
|
|
338be7622f | ||
|
|
1227047b03 | ||
|
|
9afde8d0be | ||
|
|
c2ca1feba0 | ||
|
|
f8b6119996 | ||
|
|
98c265304a | ||
|
|
675e3e8046 | ||
|
|
4acba8c990 | ||
|
|
a93adeb1fe | ||
|
|
a7c90f749e | ||
|
|
cf8773f3de | ||
|
|
3be94ae1e7 | ||
|
|
6a8aa06d18 | ||
|
|
dc17889209 | ||
|
|
4dab70eea3 | ||
|
|
55f9d8e120 | ||
|
|
15b9457ed8 | ||
|
|
898297e95c | ||
|
|
0fc4f24cd5 | ||
|
|
63b5ad9edf | ||
|
|
873c3264ca | ||
|
|
34f89e48aa | ||
|
|
b01cc1fe9d | ||
|
|
3a6e34589f | ||
|
|
68e9c85d8f | ||
|
|
1b124ff5c7 | ||
|
|
a1d512d9d7 | ||
|
|
51bf6b7fdc | ||
|
|
b5826fc0a5 | ||
|
|
becdd2f451 | ||
|
|
3b20bf354f | ||
|
|
ab2645765d | ||
|
|
2dec852ce2 | ||
|
|
8cb09379f4 | ||
|
|
fff7fe934b | ||
|
|
9fb2e61e01 | ||
|
|
24b3b6afc1 | ||
|
|
c2eed7e2c4 | ||
|
|
f97ef696e3 | ||
|
|
ad65cb8ab5 | ||
|
|
8d8131410a | ||
|
|
7491711b72 | ||
|
|
5933aa59c1 | ||
|
|
da96bec465 | ||
|
|
483422c0e9 | ||
|
|
3df93cc147 | ||
|
|
d686edfa6c | ||
|
|
497b0ade1f | ||
|
|
794927cac3 | ||
|
|
4c8d128eee | ||
|
|
86acbcd0d6 | ||
|
|
9111c85445 | ||
|
|
1d87879787 | ||
|
|
7c777f2bdf | ||
|
|
aa8067b8d0 | ||
|
|
bd66cdeb78 | ||
|
|
8d29e50669 | ||
|
|
5a7398d242 | ||
|
|
74b984fbe6 | ||
|
|
f8e00204b4 | ||
|
|
76543df765 | ||
|
|
15d4b2a5f7 | ||
|
|
2e67f91fe0 | ||
|
|
df106ca680 | ||
|
|
c58f93b597 | ||
|
|
3f2a0ead1b | ||
|
|
c9e6d2998e | ||
|
|
0eb21a3471 | ||
|
|
99e88d3497 | ||
|
|
f09ce70d3c | ||
|
|
7d62e2735f | ||
|
|
40634c6ec1 | ||
|
|
5863badbb0 | ||
|
|
8bc758ce95 | ||
|
|
56d26222e7 | ||
|
|
bd34084104 | ||
|
|
f5e6fe927d | ||
|
|
93c49639c2 | ||
|
|
aabe7bef34 | ||
|
|
909165d813 | ||
|
|
6bee742b65 | ||
|
|
23486d01b9 | ||
|
|
b761d5a730 | ||
|
|
9181e74fc8 | ||
|
|
5e83864f41 | ||
|
|
73079ca1b7 | ||
|
|
789cf66de2 | ||
|
|
c36f19a97f | ||
|
|
109338923a | ||
|
|
f4c2501b06 | ||
|
|
9161229474 | ||
|
|
265f2f40bf | ||
|
|
d2935ac2ae | ||
|
|
aaf00b8a20 | ||
|
|
f9c6a49d2a | ||
|
|
2f54a48a3d | ||
|
|
be4dd0a787 | ||
|
|
f3f072e7cf | ||
|
|
a6270bf552 | ||
|
|
de5f2d6d5b | ||
|
|
4aa377dea7 | ||
|
|
efbf3d84ac | ||
|
|
b90393b43e | ||
|
|
31ae73fe0e | ||
|
|
7a5adfc4dc | ||
|
|
850e264912 | ||
|
|
aa81779ad8 | ||
|
|
72c97c0835 | ||
|
|
12809a6733 | ||
|
|
c55aeff98e | ||
|
|
16b76e401c | ||
|
|
d2470efd6f | ||
|
|
1a97b1b77c | ||
|
|
adde5b78f3 | ||
|
|
06fd3a3686 | ||
|
|
d231b6ae2a | ||
|
|
f76274c19a | ||
|
|
e471fc5d23 | ||
|
|
cb1b602255 | ||
|
|
a728dbf632 | ||
|
|
84d06d180a | ||
|
|
342e4d9f5e | ||
|
|
8eb92471ae | ||
|
|
e5b93871f7 | ||
|
|
896aeb571d | ||
|
|
3a9797ce75 | ||
|
|
b2f14c0339 | ||
|
|
2d7b4b6c82 | ||
|
|
68369c16da | ||
|
|
f002110c28 | ||
|
|
466c5f695a | ||
|
|
b6a70228ea | ||
|
|
ac32c432da | ||
|
|
066ac6bf98 | ||
|
|
ccfa7d9943 | ||
|
|
90c76a01a6 | ||
|
|
807b52cccf | ||
|
|
fb7c6c6bbf | ||
|
|
12e619b990 | ||
|
|
aba2f8110c | ||
|
|
862e3fc7ed | ||
|
|
51fc92759a | ||
|
|
c8fac3381d | ||
|
|
9723090f91 | ||
|
|
4783e08c69 | ||
|
|
34959ff0ec | ||
|
|
bec9be84d5 | ||
|
|
277ee9d7e4 | ||
|
|
314518a87f | ||
|
|
c280fa11c3 | ||
|
|
929f5785a8 | ||
|
|
9ae92c19ab | ||
|
|
599bb7355e | ||
|
|
ad76a2f44f | ||
|
|
3a3ad44f13 | ||
|
|
db01bfb0a8 |
5
.changeset/afraid-queens-bathe.md
Normal file
5
.changeset/afraid-queens-bathe.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"cojson": patch
|
||||
---
|
||||
|
||||
Export the coValue loading config to reduce the timeout on tests
|
||||
16
.changeset/blue-kids-remain.md
Normal file
16
.changeset/blue-kids-remain.md
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
"jazz-react-native-auth-clerk": minor
|
||||
"jazz-react-auth-clerk": minor
|
||||
"cojson-transport-ws": minor
|
||||
"jazz-react-native": minor
|
||||
"jazz-auth-clerk": minor
|
||||
"jazz-react-core": minor
|
||||
"jazz-inspector": minor
|
||||
"jazz-browser": minor
|
||||
"jazz-nodejs": minor
|
||||
"jazz-react": minor
|
||||
"jazz-tools": minor
|
||||
"cojson": minor
|
||||
---
|
||||
|
||||
Introducing the new auth system!
|
||||
@@ -11,7 +11,7 @@
|
||||
"cojson-storage-sqlite",
|
||||
"cojson-transport-ws",
|
||||
"jazz-browser",
|
||||
"jazz-browser-auth-clerk",
|
||||
"jazz-auth-clerk",
|
||||
"jazz-browser-media-images",
|
||||
"jazz-nodejs",
|
||||
"jazz-react",
|
||||
|
||||
8
.changeset/silent-turtles-obey.md
Normal file
8
.changeset/silent-turtles-obey.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"jazz-react-core": minor
|
||||
"jazz-svelte": minor
|
||||
"jazz-tools": minor
|
||||
"jazz-vue": minor
|
||||
---
|
||||
|
||||
Return null when a coValue is not found
|
||||
@@ -1,5 +1,133 @@
|
||||
# chat-rn-clerk
|
||||
|
||||
## 1.0.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1be017d]
|
||||
- jazz-tools@0.9.21
|
||||
- jazz-react-native@0.9.21
|
||||
- jazz-react-native-auth-clerk@0.9.21
|
||||
- jazz-react-native-media-images@0.9.21
|
||||
|
||||
## 1.0.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b01cc1f]
|
||||
- jazz-tools@0.9.20
|
||||
- jazz-react-native@0.9.20
|
||||
- jazz-react-native-auth-clerk@0.9.20
|
||||
- jazz-react-native-media-images@0.9.20
|
||||
|
||||
## 1.0.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.9.19
|
||||
- jazz-react-native-auth-clerk@0.9.19
|
||||
- jazz-tools@0.9.19
|
||||
- jazz-react-native-media-images@0.9.19
|
||||
|
||||
## 1.0.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.9.18
|
||||
- jazz-react-native-auth-clerk@0.9.18
|
||||
- jazz-tools@0.9.18
|
||||
- jazz-react-native-media-images@0.9.18
|
||||
|
||||
## 1.0.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c2ca1fe]
|
||||
- Updated dependencies [1227047]
|
||||
- jazz-tools@0.9.17
|
||||
- jazz-react-native@0.9.17
|
||||
- jazz-react-native-auth-clerk@0.9.17
|
||||
- jazz-react-native-media-images@0.9.17
|
||||
|
||||
## 1.0.57
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [24b3b6a]
|
||||
- jazz-react-native-auth-clerk@0.9.16
|
||||
- jazz-tools@0.9.16
|
||||
- jazz-react-native@0.9.16
|
||||
- jazz-react-native-media-images@0.9.16
|
||||
|
||||
## 1.0.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7491711]
|
||||
- jazz-tools@0.9.15
|
||||
- jazz-react-native@0.9.15
|
||||
- jazz-react-native-auth-clerk@0.9.15
|
||||
- jazz-react-native-media-images@0.9.15
|
||||
|
||||
## 1.0.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3df93cc]
|
||||
- jazz-tools@0.9.14
|
||||
- jazz-react-native@0.9.14
|
||||
- jazz-react-native-auth-clerk@0.9.14
|
||||
- jazz-react-native-media-images@0.9.14
|
||||
|
||||
## 1.0.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.9.13
|
||||
- jazz-react-native-auth-clerk@0.9.13
|
||||
- jazz-tools@0.9.13
|
||||
- jazz-react-native-media-images@0.9.13
|
||||
|
||||
## 1.0.53
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.9.12
|
||||
- jazz-react-native-auth-clerk@0.9.12
|
||||
- jazz-tools@0.9.12
|
||||
- jazz-react-native-media-images@0.9.12
|
||||
|
||||
## 1.0.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.9.11
|
||||
- jazz-react-native-auth-clerk@0.9.11
|
||||
- jazz-tools@0.9.11
|
||||
- jazz-react-native-media-images@0.9.11
|
||||
|
||||
## 1.0.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f76274c: Fix image handling in react-native
|
||||
- Updated dependencies [f76274c]
|
||||
- Updated dependencies [5e83864]
|
||||
- jazz-react-native@0.9.10
|
||||
- jazz-tools@0.9.10
|
||||
- jazz-react-native-auth-clerk@0.9.10
|
||||
- jazz-react-native-media-images@0.9.10
|
||||
|
||||
## 1.0.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- jazz-tools@0.9.9
|
||||
- jazz-react-native@0.9.9
|
||||
- jazz-react-native-auth-clerk@0.9.9
|
||||
- jazz-react-native-media-images@0.9.9
|
||||
|
||||
## 1.0.49
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -37,7 +37,13 @@
|
||||
],
|
||||
"expo-secure-store",
|
||||
"expo-font",
|
||||
"expo-router"
|
||||
"expo-router",
|
||||
[
|
||||
"expo-image-picker",
|
||||
{
|
||||
"photosPermission": "The app accesses your photos to let you share them with your friends."
|
||||
}
|
||||
]
|
||||
],
|
||||
"extra": {
|
||||
"eas": {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Redirect, Stack } from "expo-router";
|
||||
import { useIsAuthenticated } from "jazz-react-native";
|
||||
import React from "react";
|
||||
import { useAuth } from "../../src/auth-context";
|
||||
|
||||
export default function HomeLayout() {
|
||||
const { isAuthenticated } = useAuth();
|
||||
const isAuthenticated = useIsAuthenticated();
|
||||
|
||||
if (isAuthenticated) {
|
||||
return <Redirect href={"/chat"} />;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Redirect, Stack } from "expo-router";
|
||||
import { useAuth } from "../../src/auth-context";
|
||||
import { useIsAuthenticated } from "jazz-react-native";
|
||||
|
||||
export default function UnAuthenticatedLayout() {
|
||||
const { isAuthenticated } = useAuth();
|
||||
const isAuthenticated = useIsAuthenticated();
|
||||
|
||||
if (isAuthenticated) {
|
||||
return <Redirect href={"/chat"} />;
|
||||
|
||||
@@ -2,8 +2,11 @@ import { Chat, Message } from "@/src/schema";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import clsx from "clsx";
|
||||
import * as Clipboard from "expo-clipboard";
|
||||
import * as ImagePicker from "expo-image-picker";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useAccount, useCoState } from "jazz-react-native";
|
||||
import { ProgressiveImg } from "jazz-react-native";
|
||||
import { createImage } from "jazz-react-native-media-images";
|
||||
import { Group, ID } from "jazz-tools";
|
||||
import { useEffect, useLayoutEffect, useState } from "react";
|
||||
import React, {
|
||||
@@ -16,6 +19,8 @@ import React, {
|
||||
KeyboardAvoidingView,
|
||||
TextInput,
|
||||
Button,
|
||||
Image,
|
||||
ActivityIndicator,
|
||||
} from "react-native";
|
||||
|
||||
export default function Conversation() {
|
||||
@@ -25,6 +30,7 @@ export default function Conversation() {
|
||||
const [message, setMessage] = useState("");
|
||||
const loadedChat = useCoState(Chat, chat?.id, [{}]);
|
||||
const navigation = useNavigation();
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (chat) return;
|
||||
@@ -81,6 +87,32 @@ export default function Conversation() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleImageUpload = async () => {
|
||||
try {
|
||||
const result = await ImagePicker.launchImageLibraryAsync({
|
||||
mediaTypes: ImagePicker.MediaTypeOptions.Images,
|
||||
base64: true,
|
||||
quality: 0.7,
|
||||
});
|
||||
|
||||
if (!result.canceled && result.assets[0].base64 && chat) {
|
||||
setIsUploading(true);
|
||||
const base64Uri = `data:image/jpeg;base64,${result.assets[0].base64}`;
|
||||
|
||||
const image = await createImage(base64Uri, {
|
||||
owner: chat._owner,
|
||||
maxSize: 2048,
|
||||
});
|
||||
|
||||
chat.push(Message.create({ text: "", image }, { owner: chat._owner }));
|
||||
}
|
||||
} catch (error) {
|
||||
Alert.alert("Error", "Failed to upload image");
|
||||
} finally {
|
||||
setIsUploading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const renderMessageItem = ({ item }: { item: Message }) => {
|
||||
const isMe = item._edits.text.by?.isMe;
|
||||
return (
|
||||
@@ -106,14 +138,27 @@ export default function Conversation() {
|
||||
isMe ? "flex-row" : "flex-row",
|
||||
)}
|
||||
>
|
||||
<Text
|
||||
className={clsx(
|
||||
!isMe ? "text-black" : "text-gray-200",
|
||||
`text-md max-w-[85%]`,
|
||||
)}
|
||||
>
|
||||
{item.text}
|
||||
</Text>
|
||||
{item.image && (
|
||||
<ProgressiveImg image={item.image} maxWidth={1024}>
|
||||
{({ src, res, originalSize }) => (
|
||||
<Image
|
||||
source={{ uri: src }}
|
||||
className="w-48 h-48 rounded-lg mb-2"
|
||||
resizeMode="cover"
|
||||
/>
|
||||
)}
|
||||
</ProgressiveImg>
|
||||
)}
|
||||
{item.text && (
|
||||
<Text
|
||||
className={clsx(
|
||||
!isMe ? "text-black" : "text-gray-200",
|
||||
`text-md max-w-[85%]`,
|
||||
)}
|
||||
>
|
||||
{item.text}
|
||||
</Text>
|
||||
)}
|
||||
<Text
|
||||
className={clsx(
|
||||
"text-[10px] text-right ml-2",
|
||||
@@ -147,6 +192,17 @@ export default function Conversation() {
|
||||
className="p-3 bg-white border-t border-gray-300"
|
||||
>
|
||||
<SafeAreaView className="flex-row items-center gap-2">
|
||||
<TouchableOpacity
|
||||
onPress={handleImageUpload}
|
||||
disabled={isUploading}
|
||||
className="h-10 w-10 items-center justify-center"
|
||||
>
|
||||
{isUploading ? (
|
||||
<ActivityIndicator size="small" color="#0000ff" />
|
||||
) : (
|
||||
<Text className="text-2xl">🖼️</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
<TextInput
|
||||
className="flex-1 rounded-full h-10 px-4 bg-gray-100 border border-gray-300 focus:border-blue-500 focus:bg-white"
|
||||
value={message}
|
||||
|
||||
@@ -20,10 +20,15 @@ export default function ChatScreen() {
|
||||
const navigation = useNavigation();
|
||||
const { user } = useUser();
|
||||
|
||||
function handleLogOut() {
|
||||
logOut();
|
||||
router.navigate("/");
|
||||
}
|
||||
|
||||
useLayoutEffect(() => {
|
||||
navigation.setOptions({
|
||||
headerTitle: "Chat",
|
||||
headerRight: () => <Button onPress={logOut} title="Logout" />,
|
||||
headerRight: () => <Button onPress={handleLogOut} title="Logout" />,
|
||||
});
|
||||
}, [navigation]);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "chat-rn-clerk",
|
||||
"main": "index.js",
|
||||
"version": "1.0.49",
|
||||
"version": "1.0.62",
|
||||
"scripts": {
|
||||
"build": "expo export -p ios",
|
||||
"start": "expo start",
|
||||
@@ -35,6 +35,7 @@
|
||||
"expo-dev-client": "~5.0.5",
|
||||
"expo-file-system": "^18.0.4",
|
||||
"expo-font": "~13.0.1",
|
||||
"expo-image-picker": "~16.0.4",
|
||||
"expo-linking": "~7.0.3",
|
||||
"expo-router": "~4.0.11",
|
||||
"expo-secure-store": "~14.0.0",
|
||||
|
||||
@@ -1,63 +1,20 @@
|
||||
import { useClerk, useUser } from "@clerk/clerk-expo";
|
||||
import { JazzProvider, setupKvStore } from "jazz-react-native";
|
||||
import { useJazzClerkAuth } from "jazz-react-native-auth-clerk";
|
||||
import React, {
|
||||
createContext,
|
||||
PropsWithChildren,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
import { Text, View } from "react-native";
|
||||
const AuthContext = createContext<{
|
||||
isAuthenticated: boolean;
|
||||
isLoading: boolean;
|
||||
}>({
|
||||
isAuthenticated: false,
|
||||
isLoading: true,
|
||||
});
|
||||
|
||||
export function useAuth() {
|
||||
return useContext(AuthContext);
|
||||
}
|
||||
|
||||
const kvStore = setupKvStore();
|
||||
import { useClerk } from "@clerk/clerk-expo";
|
||||
import { JazzProviderWithClerk } from "jazz-react-native-auth-clerk";
|
||||
import React, { PropsWithChildren } from "react";
|
||||
|
||||
export function JazzAndAuth({ children }: PropsWithChildren) {
|
||||
const { isSignedIn, isLoaded: isClerkLoaded } = useUser();
|
||||
const clerk = useClerk();
|
||||
const [auth, state] = useJazzClerkAuth(clerk, kvStore);
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isSignedIn && isClerkLoaded && auth) {
|
||||
setIsAuthenticated(true);
|
||||
} else {
|
||||
setIsAuthenticated(false);
|
||||
}
|
||||
}, [isSignedIn, isClerkLoaded, auth]);
|
||||
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
value={{ isAuthenticated, isLoading: !isClerkLoaded || !auth }}
|
||||
<JazzProviderWithClerk
|
||||
clerk={clerk}
|
||||
storage="sqlite"
|
||||
sync={{
|
||||
peer: "wss://cloud.jazz.tools/?key=chat-rn-clerk-example-jazz@garden.co",
|
||||
when: "signedUp", // This makes the app work in local mode when the user is not authenticated
|
||||
}}
|
||||
>
|
||||
{state?.errors?.length > 0 &&
|
||||
state.errors.map((error) => (
|
||||
<View key={error}>
|
||||
<Text style={{ color: "red" }}>{error}</Text>
|
||||
</View>
|
||||
))}
|
||||
{auth && clerk.user ? (
|
||||
<JazzProvider
|
||||
auth={auth}
|
||||
storage="sqlite"
|
||||
peer="wss://cloud.jazz.tools/?key=chat-rn-clerk-example-jazz@garden.co"
|
||||
>
|
||||
{children}
|
||||
</JazzProvider>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</AuthContext.Provider>
|
||||
{children}
|
||||
</JazzProviderWithClerk>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { CoList, CoMap, co } from "jazz-tools";
|
||||
import { CoList, CoMap, ImageDefinition, co } from "jazz-tools";
|
||||
|
||||
export class Message extends CoMap {
|
||||
text = co.string;
|
||||
image = co.optional.ref(ImageDefinition);
|
||||
}
|
||||
|
||||
export class Chat extends CoList.Of(co.ref(Message)) {}
|
||||
|
||||
@@ -1,5 +1,106 @@
|
||||
# chat-rn
|
||||
|
||||
## 1.0.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1be017d]
|
||||
- jazz-tools@0.9.21
|
||||
- jazz-react-native@0.9.21
|
||||
|
||||
## 1.0.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b01cc1f]
|
||||
- jazz-tools@0.9.20
|
||||
- jazz-react-native@0.9.20
|
||||
|
||||
## 1.0.57
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.9.19
|
||||
- jazz-tools@0.9.19
|
||||
|
||||
## 1.0.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.9.18
|
||||
- jazz-tools@0.9.18
|
||||
|
||||
## 1.0.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c2ca1fe]
|
||||
- Updated dependencies [1227047]
|
||||
- jazz-tools@0.9.17
|
||||
- jazz-react-native@0.9.17
|
||||
|
||||
## 1.0.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [24b3b6a]
|
||||
- jazz-tools@0.9.16
|
||||
- jazz-react-native@0.9.16
|
||||
|
||||
## 1.0.53
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7491711]
|
||||
- jazz-tools@0.9.15
|
||||
- jazz-react-native@0.9.15
|
||||
|
||||
## 1.0.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3df93cc]
|
||||
- jazz-tools@0.9.14
|
||||
- jazz-react-native@0.9.14
|
||||
|
||||
## 1.0.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.9.13
|
||||
- jazz-tools@0.9.13
|
||||
|
||||
## 1.0.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.9.12
|
||||
- jazz-tools@0.9.12
|
||||
|
||||
## 1.0.49
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react-native@0.9.11
|
||||
- jazz-tools@0.9.11
|
||||
|
||||
## 1.0.48
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f76274c]
|
||||
- Updated dependencies [5e83864]
|
||||
- jazz-react-native@0.9.10
|
||||
- jazz-tools@0.9.10
|
||||
|
||||
## 1.0.47
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- jazz-tools@0.9.9
|
||||
- jazz-react-native@0.9.9
|
||||
|
||||
## 1.0.46
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-rn",
|
||||
"version": "1.0.46",
|
||||
"version": "1.0.59",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "expo export -p ios",
|
||||
|
||||
@@ -9,7 +9,7 @@ import * as Linking from "expo-linking";
|
||||
import React, { StrictMode, useEffect, useState } from "react";
|
||||
import HandleInviteScreen from "./invite";
|
||||
|
||||
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react-native";
|
||||
import { JazzProvider } from "jazz-react-native";
|
||||
import ChatScreen from "./chat";
|
||||
|
||||
const Stack = createNativeStackNavigator();
|
||||
@@ -28,7 +28,6 @@ const linking = {
|
||||
};
|
||||
|
||||
function App() {
|
||||
const [auth, state] = useDemoAuth();
|
||||
const [initialRoute, setInitialRoute] = useState<
|
||||
"ChatScreen" | "HandleInviteScreen"
|
||||
>("ChatScreen");
|
||||
@@ -43,16 +42,13 @@ function App() {
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (!auth) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<StrictMode>
|
||||
<JazzProvider
|
||||
auth={auth}
|
||||
storage="sqlite"
|
||||
peer="wss://cloud.jazz.tools/?key=chat-rn-example-jazz@garden.co"
|
||||
sync={{
|
||||
peer: "wss://cloud.jazz.tools/?key=chat-rn-example-jazz@garden.co",
|
||||
}}
|
||||
>
|
||||
<NavigationContainer linking={linking} ref={navigationRef}>
|
||||
<Stack.Navigator initialRouteName={initialRoute}>
|
||||
@@ -69,9 +65,6 @@ function App() {
|
||||
</Stack.Navigator>
|
||||
</NavigationContainer>
|
||||
</JazzProvider>
|
||||
{state.state !== "signedIn" ? (
|
||||
<DemoAuthBasicUI appName="Jazz Chat" state={state} />
|
||||
) : null}
|
||||
</StrictMode>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import clsx from "clsx";
|
||||
import * as Clipboard from "expo-clipboard";
|
||||
import { Group, ID } from "jazz-tools";
|
||||
import { Group, ID, Profile } from "jazz-tools";
|
||||
import { useEffect, useState } from "react";
|
||||
import React, {
|
||||
Button,
|
||||
@@ -22,10 +22,16 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
|
||||
const [chatId, setChatId] = useState<ID<Chat>>();
|
||||
const loadedChat = useCoState(Chat, chatId, [{}]);
|
||||
const [message, setMessage] = useState("");
|
||||
const profile = useCoState(Profile, me._refs.profile?.id, {});
|
||||
|
||||
function handleLogOut() {
|
||||
setChatId(undefined);
|
||||
logOut();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
navigation.setOptions({
|
||||
headerRight: () => <Button onPress={logOut} title="Logout" />,
|
||||
headerRight: () => <Button onPress={handleLogOut} title="Logout" />,
|
||||
headerLeft: () =>
|
||||
loadedChat ? (
|
||||
<Button
|
||||
@@ -131,6 +137,18 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
|
||||
<View className="flex flex-col h-full">
|
||||
{!loadedChat ? (
|
||||
<View className="flex flex-col h-full items-center justify-center">
|
||||
<Text className="text-m font-bold mb-6">Username</Text>
|
||||
<TextInput
|
||||
className="rounded h-12 p-2 mb-12 w-40 border border-gray-200 block"
|
||||
value={profile?.name ?? ""}
|
||||
onChangeText={(value) => {
|
||||
if (profile) {
|
||||
profile.name = value;
|
||||
}
|
||||
}}
|
||||
textAlignVertical="center"
|
||||
onSubmitEditing={sendMessage}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
onPress={createChat}
|
||||
className="bg-blue-500 p-4 rounded-md"
|
||||
|
||||
@@ -1,5 +1,118 @@
|
||||
# chat-vue
|
||||
|
||||
## 0.0.46
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1be017d]
|
||||
- jazz-tools@0.9.21
|
||||
- jazz-browser@0.9.21
|
||||
- jazz-vue@0.9.21
|
||||
|
||||
## 0.0.45
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b01cc1f]
|
||||
- jazz-tools@0.9.20
|
||||
- jazz-browser@0.9.20
|
||||
- jazz-vue@0.9.20
|
||||
|
||||
## 0.0.44
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-browser@0.9.19
|
||||
- jazz-tools@0.9.19
|
||||
- jazz-vue@0.9.19
|
||||
|
||||
## 0.0.43
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-browser@0.9.18
|
||||
- jazz-tools@0.9.18
|
||||
- jazz-vue@0.9.18
|
||||
|
||||
## 0.0.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c2ca1fe]
|
||||
- Updated dependencies [1227047]
|
||||
- jazz-tools@0.9.17
|
||||
- jazz-browser@0.9.17
|
||||
- jazz-vue@0.9.17
|
||||
|
||||
## 0.0.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [24b3b6a]
|
||||
- jazz-tools@0.9.16
|
||||
- jazz-browser@0.9.16
|
||||
- jazz-vue@0.9.16
|
||||
|
||||
## 0.0.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7491711]
|
||||
- jazz-tools@0.9.15
|
||||
- jazz-browser@0.9.15
|
||||
- jazz-vue@0.9.15
|
||||
|
||||
## 0.0.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3df93cc]
|
||||
- jazz-tools@0.9.14
|
||||
- jazz-browser@0.9.14
|
||||
- jazz-vue@0.9.14
|
||||
|
||||
## 0.0.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-browser@0.9.13
|
||||
- jazz-tools@0.9.13
|
||||
- jazz-vue@0.9.13
|
||||
|
||||
## 0.0.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-browser@0.9.12
|
||||
- jazz-tools@0.9.12
|
||||
- jazz-vue@0.9.12
|
||||
|
||||
## 0.0.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-browser@0.9.11
|
||||
- jazz-tools@0.9.11
|
||||
- jazz-vue@0.9.11
|
||||
|
||||
## 0.0.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5e83864]
|
||||
- jazz-tools@0.9.10
|
||||
- jazz-browser@0.9.10
|
||||
- jazz-vue@0.9.10
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- jazz-tools@0.9.9
|
||||
- jazz-browser@0.9.9
|
||||
- jazz-vue@0.9.9
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,29 +1,55 @@
|
||||
# Chat example with Jazz and Vue
|
||||
|
||||
## Installing & running the example locally
|
||||
## Getting started
|
||||
|
||||
(This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
|
||||
You can either
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
Start by downloading the [jazz repository](https://github.com/garden-co/jazz):
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
```bash
|
||||
npx degit gardencmp/jazz jazz
|
||||
npx create-jazz-app@latest --example chat-vue --project-name chat-vue
|
||||
```
|
||||
|
||||
Go to the todo-vue example directory:
|
||||
Go to the new project directory.
|
||||
```bash
|
||||
cd jazz/examples/chat-vue
|
||||
cd chat-vue
|
||||
```
|
||||
|
||||
Install and build dependencies:
|
||||
Run the dev server.
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Start the dev server:
|
||||
Go to the example directory.
|
||||
```bash
|
||||
cd jazz/examples/chat-vue/
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-vue",
|
||||
"version": "0.0.33",
|
||||
"version": "0.0.46",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-vue";
|
||||
import { DemoAuthBasicUI, JazzProvider } from "jazz-vue";
|
||||
import { createApp, defineComponent, h } from "vue";
|
||||
import App from "./App.vue";
|
||||
import "./index.css";
|
||||
@@ -7,26 +7,24 @@ import router from "./router";
|
||||
const RootComponent = defineComponent({
|
||||
name: "RootComponent",
|
||||
setup() {
|
||||
const { authMethod, state } = useDemoAuth();
|
||||
|
||||
return () => [
|
||||
return () =>
|
||||
h(
|
||||
JazzProvider,
|
||||
{
|
||||
auth: authMethod.value,
|
||||
peer: "wss://cloud.jazz.tools/?key=chat-example-jazz@garden.co",
|
||||
sync: {
|
||||
peer: "wss://cloud.jazz.tools/?key=vue-todo-example-jazz@garden.co",
|
||||
},
|
||||
},
|
||||
{
|
||||
default: () => h(App),
|
||||
},
|
||||
),
|
||||
|
||||
state.state !== "signedIn" &&
|
||||
h(DemoAuthBasicUI, {
|
||||
appName: "Jazz Chat",
|
||||
state,
|
||||
}),
|
||||
];
|
||||
h(
|
||||
DemoAuthBasicUI,
|
||||
{
|
||||
appName: "Jazz Vue Chat",
|
||||
},
|
||||
{
|
||||
default: () => h(App),
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,119 @@
|
||||
# jazz-example-chat
|
||||
|
||||
## 0.0.142
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1be017d]
|
||||
- jazz-tools@0.9.21
|
||||
- jazz-browser-media-images@0.9.21
|
||||
- jazz-react@0.9.21
|
||||
|
||||
## 0.0.141
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b01cc1f]
|
||||
- jazz-tools@0.9.20
|
||||
- jazz-browser-media-images@0.9.20
|
||||
- jazz-react@0.9.20
|
||||
|
||||
## 0.0.140
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.19
|
||||
- jazz-tools@0.9.19
|
||||
- jazz-browser-media-images@0.9.19
|
||||
|
||||
## 0.0.139
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.18
|
||||
- jazz-tools@0.9.18
|
||||
- jazz-browser-media-images@0.9.18
|
||||
|
||||
## 0.0.138
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c2ca1fe]
|
||||
- Updated dependencies [1227047]
|
||||
- jazz-tools@0.9.17
|
||||
- jazz-browser-media-images@0.9.17
|
||||
- jazz-react@0.9.17
|
||||
|
||||
## 0.0.137
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [24b3b6a]
|
||||
- jazz-tools@0.9.16
|
||||
- jazz-browser-media-images@0.9.16
|
||||
- jazz-react@0.9.16
|
||||
|
||||
## 0.0.136
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7491711]
|
||||
- jazz-tools@0.9.15
|
||||
- jazz-browser-media-images@0.9.15
|
||||
- jazz-react@0.9.15
|
||||
|
||||
## 0.0.135
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3df93cc]
|
||||
- jazz-tools@0.9.14
|
||||
- jazz-browser-media-images@0.9.14
|
||||
- jazz-react@0.9.14
|
||||
|
||||
## 0.0.134
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.13
|
||||
- jazz-tools@0.9.13
|
||||
- jazz-browser-media-images@0.9.13
|
||||
|
||||
## 0.0.133
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.12
|
||||
- jazz-tools@0.9.12
|
||||
- jazz-browser-media-images@0.9.12
|
||||
|
||||
## 0.0.132
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.11
|
||||
- jazz-tools@0.9.11
|
||||
- jazz-browser-media-images@0.9.11
|
||||
|
||||
## 0.0.131
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f76274c: Fix image handling in react-native
|
||||
- Updated dependencies [5e83864]
|
||||
- jazz-react@0.9.10
|
||||
- jazz-tools@0.9.10
|
||||
- jazz-browser-media-images@0.9.10
|
||||
|
||||
## 0.0.130
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- jazz-tools@0.9.9
|
||||
- jazz-browser-media-images@0.9.9
|
||||
- jazz-react@0.9.9
|
||||
|
||||
## 0.0.129
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -2,30 +2,56 @@
|
||||
|
||||
Live version: [https://chat.jazz.tools](https://chat.jazz.tools)
|
||||
|
||||
## Installing & running the example locally
|
||||
## Getting started
|
||||
|
||||
(This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
|
||||
You can either
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
Start by downloading the [jazz repository](https://github.com/garden-co/jazz):
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
```bash
|
||||
npx degit gardencmp/jazz jazz
|
||||
npx create-jazz-app@latest --example chat --project-name chat
|
||||
```
|
||||
|
||||
Go to the chat example directory:
|
||||
Go to the new project directory.
|
||||
```bash
|
||||
cd jazz/examples/chat
|
||||
cd chat
|
||||
```
|
||||
|
||||
Install and build dependencies:
|
||||
Run the dev server.
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Start the dev server:
|
||||
Go to the example directory.
|
||||
```bash
|
||||
cd jazz/examples/chat/
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-chat",
|
||||
"private": true,
|
||||
"version": "0.0.129",
|
||||
"version": "0.0.142",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { inIframe, onChatLoad } from "@/util.ts";
|
||||
import { getRandomUsername, inIframe, onChatLoad } from "@/util.ts";
|
||||
import { useIframeHashRouter } from "hash-slash";
|
||||
import { useAccount } from "jazz-react";
|
||||
import { JazzProvider, useAccount } from "jazz-react";
|
||||
import { Group, ID } from "jazz-tools";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { ChatScreen } from "./chatScreen.tsx";
|
||||
import { JazzAndAuth } from "./jazz.tsx";
|
||||
import { Chat } from "./schema.ts";
|
||||
import { ThemeProvider } from "./themeProvider.tsx";
|
||||
import { AppContainer, TopBar } from "./ui.tsx";
|
||||
@@ -28,7 +27,15 @@ export function App() {
|
||||
return (
|
||||
<AppContainer>
|
||||
<TopBar>
|
||||
<p>{me?.profile?.name}</p>
|
||||
<input
|
||||
type="text"
|
||||
value={me?.profile?.name ?? ""}
|
||||
onChange={(e) => {
|
||||
if (!me?.profile) return;
|
||||
me.profile.name = e.target.value;
|
||||
}}
|
||||
placeholder="Set username"
|
||||
/>
|
||||
{!inIframe && <button onClick={logOut}>Log out</button>}
|
||||
</TopBar>
|
||||
{router.route({
|
||||
@@ -39,12 +46,20 @@ export function App() {
|
||||
);
|
||||
}
|
||||
|
||||
const url = new URL(window.location.href);
|
||||
const defaultProfileName = url.searchParams.get("user") ?? getRandomUsername();
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<ThemeProvider>
|
||||
<StrictMode>
|
||||
<JazzAndAuth>
|
||||
<JazzProvider
|
||||
sync={{
|
||||
peer: "wss://cloud.jazz.tools/?key=chat-example-jazz@garden.co",
|
||||
}}
|
||||
defaultProfileName={defaultProfileName}
|
||||
>
|
||||
<App />
|
||||
</JazzAndAuth>
|
||||
</JazzProvider>
|
||||
</StrictMode>
|
||||
</ThemeProvider>,
|
||||
);
|
||||
|
||||
@@ -35,7 +35,7 @@ export function ChatScreen(props: { chatID: ID<Chat> }) {
|
||||
return;
|
||||
}
|
||||
|
||||
createImage(file).then((image) => {
|
||||
createImage(file, { owner: chat._owner }).then((image) => {
|
||||
chat.push(Message.create({ text: file.name, image: image }, chat._owner));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
|
||||
|
||||
export function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
const [auth, state] = useDemoAuth();
|
||||
|
||||
return (
|
||||
<>
|
||||
<JazzProvider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=chat-example-jazz@garden.co"
|
||||
>
|
||||
{children}
|
||||
</JazzProvider>
|
||||
{state.state !== "signedIn" && (
|
||||
<DemoAuthBasicUI appName="Jazz Chat" state={state} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -15,3 +15,20 @@ export function onChatLoad(chat: Chat) {
|
||||
}
|
||||
|
||||
export const inIframe = window.self !== window.top;
|
||||
|
||||
const animals = [
|
||||
"elephant",
|
||||
"penguin",
|
||||
"giraffe",
|
||||
"octopus",
|
||||
"kangaroo",
|
||||
"dolphin",
|
||||
"cheetah",
|
||||
"koala",
|
||||
"platypus",
|
||||
"pangolin",
|
||||
];
|
||||
|
||||
export function getRandomUsername() {
|
||||
return `Anonymous ${animals[Math.floor(Math.random() * animals.length)]}`;
|
||||
}
|
||||
|
||||
@@ -1,48 +1,35 @@
|
||||
import { test } from "@playwright/test";
|
||||
import { ChatPage } from "./pages/ChatPage";
|
||||
import { LoginPage } from "./pages/LoginPage";
|
||||
|
||||
test("chat between two users", async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
test("chat between two users", async ({ page: marioPage, browser }) => {
|
||||
const context = await browser.newContext();
|
||||
const luigiPage = await context.newPage();
|
||||
|
||||
const mario = "S. Mario";
|
||||
const luigi = "Luigi";
|
||||
await marioPage.goto("/");
|
||||
|
||||
await loginPage.goto();
|
||||
await loginPage.fillUsername(mario);
|
||||
await loginPage.signup();
|
||||
const marioChat = new ChatPage(marioPage);
|
||||
const luigiChat = new ChatPage(luigiPage);
|
||||
|
||||
const chatPage = new ChatPage(page);
|
||||
await marioChat.setUsername("Mario");
|
||||
|
||||
const message1ByMario = "Hello Luigi, are you ready to save the princess?";
|
||||
|
||||
await chatPage.sendMessage(message1ByMario);
|
||||
await chatPage.expectMessageRow(message1ByMario);
|
||||
await marioChat.sendMessage(message1ByMario);
|
||||
await marioChat.expectMessageRow(message1ByMario);
|
||||
|
||||
const roomURL = page.url();
|
||||
const roomURL = marioPage.url();
|
||||
await luigiPage.goto(roomURL);
|
||||
|
||||
await chatPage.logout();
|
||||
await luigiChat.setUsername("Luigi");
|
||||
|
||||
await loginPage.expectLoaded();
|
||||
|
||||
await loginPage.fillUsername(luigi);
|
||||
await loginPage.signup();
|
||||
|
||||
await page.goto(roomURL);
|
||||
|
||||
await chatPage.expectMessageRow(message1ByMario);
|
||||
await luigiChat.expectMessageRow(message1ByMario);
|
||||
|
||||
const message2ByLuigi =
|
||||
"No, I'm not ready yet. I'm still trying to find the key to the castle.";
|
||||
|
||||
await chatPage.sendMessage(message2ByLuigi);
|
||||
await chatPage.expectMessageRow(message2ByLuigi);
|
||||
await luigiChat.sendMessage(message2ByLuigi);
|
||||
await luigiChat.expectMessageRow(message2ByLuigi);
|
||||
|
||||
await chatPage.logout();
|
||||
await loginPage.loginAs(mario);
|
||||
|
||||
await page.goto(roomURL);
|
||||
|
||||
await chatPage.expectMessageRow(message1ByMario);
|
||||
await chatPage.expectMessageRow(message2ByLuigi);
|
||||
await marioChat.expectMessageRow(message1ByMario);
|
||||
await luigiChat.expectMessageRow(message2ByLuigi);
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ export class ChatPage {
|
||||
readonly page: Page;
|
||||
readonly messageInput: Locator;
|
||||
readonly logoutButton: Locator;
|
||||
|
||||
readonly usernameInput: Locator;
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.messageInput = page.getByRole("textbox", {
|
||||
@@ -13,6 +13,11 @@ export class ChatPage {
|
||||
this.logoutButton = page.getByRole("button", {
|
||||
name: "Log out",
|
||||
});
|
||||
this.usernameInput = page.getByPlaceholder("Set username");
|
||||
}
|
||||
|
||||
async setUsername(username: string) {
|
||||
await this.usernameInput.fill(username);
|
||||
}
|
||||
|
||||
async sendMessage(message: string) {
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import { Locator, Page, expect } from "@playwright/test";
|
||||
|
||||
export class LoginPage {
|
||||
readonly page: Page;
|
||||
readonly usernameInput: Locator;
|
||||
readonly signupButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.usernameInput = page.getByRole("textbox");
|
||||
this.signupButton = page.getByRole("button", {
|
||||
name: "Sign up",
|
||||
});
|
||||
}
|
||||
|
||||
async goto() {
|
||||
this.page.goto("/");
|
||||
}
|
||||
|
||||
async fillUsername(value: string) {
|
||||
await this.usernameInput.clear();
|
||||
await this.usernameInput.fill(value);
|
||||
}
|
||||
|
||||
async loginAs(value: string) {
|
||||
await this.page
|
||||
.getByRole("button", {
|
||||
name: value,
|
||||
})
|
||||
.click();
|
||||
}
|
||||
|
||||
async signup() {
|
||||
await this.signupButton.click();
|
||||
}
|
||||
|
||||
async expectLoaded() {
|
||||
await expect(this.signupButton).toBeVisible();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,118 @@
|
||||
# minimal-auth-clerk
|
||||
|
||||
## 0.0.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1be017d]
|
||||
- jazz-tools@0.9.21
|
||||
- jazz-react@0.9.21
|
||||
- jazz-react-auth-clerk@0.9.21
|
||||
|
||||
## 0.0.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b01cc1f]
|
||||
- jazz-tools@0.9.20
|
||||
- jazz-react@0.9.20
|
||||
- jazz-react-auth-clerk@0.9.20
|
||||
|
||||
## 0.0.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.19
|
||||
- jazz-react-auth-clerk@0.9.19
|
||||
- jazz-tools@0.9.19
|
||||
|
||||
## 0.0.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.18
|
||||
- jazz-react-auth-clerk@0.9.18
|
||||
- jazz-tools@0.9.18
|
||||
|
||||
## 0.0.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c2ca1fe]
|
||||
- Updated dependencies [1227047]
|
||||
- jazz-tools@0.9.17
|
||||
- jazz-react@0.9.17
|
||||
- jazz-react-auth-clerk@0.9.17
|
||||
|
||||
## 0.0.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [24b3b6a]
|
||||
- jazz-react-auth-clerk@0.9.16
|
||||
- jazz-tools@0.9.16
|
||||
- jazz-react@0.9.16
|
||||
|
||||
## 0.0.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7491711]
|
||||
- jazz-tools@0.9.15
|
||||
- jazz-react@0.9.15
|
||||
- jazz-react-auth-clerk@0.9.15
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3df93cc]
|
||||
- jazz-tools@0.9.14
|
||||
- jazz-react@0.9.14
|
||||
- jazz-react-auth-clerk@0.9.14
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.13
|
||||
- jazz-react-auth-clerk@0.9.13
|
||||
- jazz-tools@0.9.13
|
||||
|
||||
## 0.0.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.12
|
||||
- jazz-react-auth-clerk@0.9.12
|
||||
- jazz-tools@0.9.12
|
||||
|
||||
## 0.0.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.11
|
||||
- jazz-react-auth-clerk@0.9.11
|
||||
- jazz-tools@0.9.11
|
||||
|
||||
## 0.0.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5e83864]
|
||||
- jazz-react@0.9.10
|
||||
- jazz-tools@0.9.10
|
||||
- jazz-react-auth-clerk@0.9.10
|
||||
|
||||
## 0.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- jazz-tools@0.9.9
|
||||
- jazz-react@0.9.9
|
||||
- jazz-react-auth-clerk@0.9.9
|
||||
|
||||
## 0.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -4,30 +4,56 @@ This is an example of how to use clerk authentication with Jazz.
|
||||
|
||||
Live version: https://clerk-demo.jazz.tools
|
||||
|
||||
## Installing & running the example locally
|
||||
## Getting started
|
||||
|
||||
(This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
|
||||
You can either
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
Start by downloading the [jazz repository](https://github.com/garden-co/jazz):
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
```bash
|
||||
npx degit gardencmp/jazz jazz
|
||||
npx create-jazz-app@latest --example clerk --project-name clerk
|
||||
```
|
||||
|
||||
Go to the clerk example directory:
|
||||
Go to the new project directory.
|
||||
```bash
|
||||
cd jazz/examples/clerk
|
||||
cd clerk
|
||||
```
|
||||
|
||||
Install and build dependencies:
|
||||
Run the dev server.
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Start the dev server:
|
||||
Go to the example directory.
|
||||
```bash
|
||||
cd jazz/examples/clerk/
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "clerk",
|
||||
"private": true,
|
||||
"version": "0.0.28",
|
||||
"version": "0.0.41",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -13,7 +13,7 @@
|
||||
"dependencies": {
|
||||
"@clerk/clerk-react": "^5.4.1",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-react-auth-clerk": "workspace:0.9.8",
|
||||
"jazz-react-auth-clerk": "workspace:0.9.21",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
import { useAccount } from "jazz-react";
|
||||
import { SignInButton } from "@clerk/clerk-react";
|
||||
import { useAccount, useIsAuthenticated } from "jazz-react";
|
||||
|
||||
function App() {
|
||||
const { me, logOut } = useAccount();
|
||||
|
||||
const isAuthenticated = useIsAuthenticated();
|
||||
|
||||
if (isAuthenticated) {
|
||||
return (
|
||||
<div className="container">
|
||||
<h1>You're logged in</h1>
|
||||
<p>Welcome back, {me?.profile?.name}</p>
|
||||
<button onClick={() => logOut()}>Logout</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<h1>You're logged in</h1>
|
||||
<p>Welcome back, {me?.profile?.name}</p>
|
||||
<button onClick={() => logOut()}>Logout</button>
|
||||
<h1>You're not logged in</h1>
|
||||
<SignInButton />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ button {
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 200px;
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1rem;
|
||||
display: flex;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { ClerkProvider, SignInButton, useClerk } from "@clerk/clerk-react";
|
||||
import { useJazzClerkAuth } from "jazz-react-auth-clerk";
|
||||
import { ClerkProvider, useClerk } from "@clerk/clerk-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import App from "./App.tsx";
|
||||
import "./index.css";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { JazzProviderWithClerk } from "jazz-react-auth-clerk";
|
||||
|
||||
// Import your publishable key
|
||||
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;
|
||||
@@ -13,35 +12,28 @@ if (!PUBLISHABLE_KEY) {
|
||||
throw new Error("Add your Clerk publishable key to the .env.local file");
|
||||
}
|
||||
|
||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
function JazzProvider({ children }: { children: React.ReactNode }) {
|
||||
const clerk = useClerk();
|
||||
const [auth, state] = useJazzClerkAuth(clerk);
|
||||
|
||||
return (
|
||||
<main className="container">
|
||||
{state?.errors?.map((error) => (
|
||||
<div key={error}>{error}</div>
|
||||
))}
|
||||
{clerk.user && auth ? (
|
||||
<JazzProvider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=minimal-auth-clerk-example@garden.co"
|
||||
>
|
||||
{children}
|
||||
</JazzProvider>
|
||||
) : (
|
||||
<SignInButton />
|
||||
)}
|
||||
</main>
|
||||
<JazzProviderWithClerk
|
||||
clerk={clerk}
|
||||
sync={{
|
||||
peer: "wss://cloud.jazz.tools/?key=minimal-auth-clerk-example@garden.co",
|
||||
when: "signedUp", // This makes the app work in local mode when the user is not authenticated
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</JazzProviderWithClerk>
|
||||
);
|
||||
}
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
<ClerkProvider publishableKey={PUBLISHABLE_KEY} afterSignOutUrl="/">
|
||||
<JazzAndAuth>
|
||||
<JazzProvider>
|
||||
<App />
|
||||
</JazzAndAuth>
|
||||
</JazzProvider>
|
||||
</ClerkProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
@@ -1,5 +1,105 @@
|
||||
# file-share-svelte
|
||||
|
||||
## 0.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1be017d]
|
||||
- jazz-tools@0.9.21
|
||||
- jazz-svelte@0.9.21
|
||||
|
||||
## 0.0.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b01cc1f]
|
||||
- jazz-tools@0.9.20
|
||||
- jazz-svelte@0.9.20
|
||||
|
||||
## 0.0.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.19
|
||||
- jazz-tools@0.9.19
|
||||
|
||||
## 0.0.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.18
|
||||
- jazz-tools@0.9.18
|
||||
|
||||
## 0.0.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c2ca1fe]
|
||||
- Updated dependencies [1227047]
|
||||
- jazz-tools@0.9.17
|
||||
- jazz-svelte@0.9.17
|
||||
|
||||
## 0.0.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [24b3b6a]
|
||||
- jazz-tools@0.9.16
|
||||
- jazz-svelte@0.9.16
|
||||
|
||||
## 0.0.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7491711]
|
||||
- jazz-tools@0.9.15
|
||||
- jazz-svelte@0.9.15
|
||||
|
||||
## 0.0.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3df93cc]
|
||||
- jazz-tools@0.9.14
|
||||
- jazz-svelte@0.9.14
|
||||
|
||||
## 0.0.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.13
|
||||
- jazz-tools@0.9.13
|
||||
|
||||
## 0.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.12
|
||||
- jazz-tools@0.9.12
|
||||
|
||||
## 0.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.11
|
||||
- jazz-tools@0.9.11
|
||||
|
||||
## 0.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5e83864]
|
||||
- jazz-tools@0.9.10
|
||||
- jazz-svelte@0.9.10
|
||||
|
||||
## 0.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- jazz-tools@0.9.9
|
||||
- jazz-svelte@0.9.9
|
||||
|
||||
## 0.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "file-share-svelte",
|
||||
"version": "0.0.13",
|
||||
"version": "0.0.26",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -17,6 +17,6 @@ export function formatFileSize(bytes: number): string {
|
||||
* @param createdAt The creation date
|
||||
* @returns A unique file ID string
|
||||
*/
|
||||
export function generateTempFileId(fileName: string, createdAt: Date): string {
|
||||
return `file-${fileName}-${createdAt.getTime()}`;
|
||||
export function generateTempFileId(fileName: string | undefined, createdAt: Date | undefined): string {
|
||||
return `file-${fileName ?? 'unknown'}-${createdAt?.getTime() ?? 0}`;
|
||||
}
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
import { FileShareAccount } from '$lib/schema';
|
||||
|
||||
let { children } = $props();
|
||||
const auth = usePasskeyAuth({
|
||||
appName: 'File Share'
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -25,21 +22,16 @@
|
||||
|
||||
<Toaster richColors />
|
||||
|
||||
{#if auth.state.state === 'ready'}
|
||||
<div class="fixed inset-0 flex items-center justify-center bg-gray-50/80">
|
||||
<div class="rounded-lg bg-white p-8 shadow-lg">
|
||||
<PasskeyAuthBasicUI state={auth.state} />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if auth.current}
|
||||
<JazzProvider
|
||||
AccountSchema={FileShareAccount}
|
||||
auth={auth.current}
|
||||
peer="wss://cloud.jazz.tools/?key=file-share-svelte@garden.co"
|
||||
>
|
||||
<JazzProvider
|
||||
AccountSchema={FileShareAccount}
|
||||
sync={{
|
||||
peer: "wss://cloud.jazz.tools/?key=minimal-svelte-auth-passkey@garden.co",
|
||||
when: "signedUp",
|
||||
}}
|
||||
>
|
||||
<PasskeyAuthBasicUI appName="File Share">
|
||||
<div class="min-h-screen bg-gray-100">
|
||||
{@render children()}
|
||||
</div>
|
||||
</JazzProvider>
|
||||
{/if}
|
||||
</PasskeyAuthBasicUI>
|
||||
</JazzProvider>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
const input = event.target as HTMLInputElement;
|
||||
const files = input.files;
|
||||
|
||||
if (!files || !files.length || !me?.root?.sharedFiles || !me.root.publicGroup) return;
|
||||
if (!files || !files.length || !me.root?.sharedFiles || !me.root.publicGroup) return;
|
||||
|
||||
const file = files[0];
|
||||
const fileName = file.name;
|
||||
@@ -129,12 +129,14 @@
|
||||
{#if sharedFiles.current}
|
||||
{#if !(sharedFiles.current.length === 0 && uploadingFiles.size === 0)}
|
||||
{#each [...sharedFiles.current, ...uploadingFiles.values()] as file (generateTempFileId(file?.name, file?.createdAt))}
|
||||
<FileItem
|
||||
{file}
|
||||
loading={uploadingFiles.has(generateTempFileId(file?.name, file?.createdAt))}
|
||||
onShare={shareFile}
|
||||
onDelete={deleteFile}
|
||||
/>
|
||||
{#if file}
|
||||
<FileItem
|
||||
{file}
|
||||
loading={uploadingFiles.has(generateTempFileId(file?.name, file?.createdAt))}
|
||||
onShare={shareFile}
|
||||
onDelete={deleteFile}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
{:else}
|
||||
<p class="text-center text-gray-500">No files yet</p>
|
||||
|
||||
@@ -1,5 +1,118 @@
|
||||
# form
|
||||
|
||||
## 0.0.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1be017d]
|
||||
- jazz-tools@0.9.21
|
||||
- jazz-browser-media-images@0.9.21
|
||||
- jazz-react@0.9.21
|
||||
|
||||
## 0.0.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b01cc1f]
|
||||
- jazz-tools@0.9.20
|
||||
- jazz-browser-media-images@0.9.20
|
||||
- jazz-react@0.9.20
|
||||
|
||||
## 0.0.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.19
|
||||
- jazz-tools@0.9.19
|
||||
- jazz-browser-media-images@0.9.19
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.18
|
||||
- jazz-tools@0.9.18
|
||||
- jazz-browser-media-images@0.9.18
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c2ca1fe]
|
||||
- Updated dependencies [1227047]
|
||||
- jazz-tools@0.9.17
|
||||
- jazz-browser-media-images@0.9.17
|
||||
- jazz-react@0.9.17
|
||||
|
||||
## 0.0.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [24b3b6a]
|
||||
- jazz-tools@0.9.16
|
||||
- jazz-browser-media-images@0.9.16
|
||||
- jazz-react@0.9.16
|
||||
|
||||
## 0.0.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7491711]
|
||||
- jazz-tools@0.9.15
|
||||
- jazz-browser-media-images@0.9.15
|
||||
- jazz-react@0.9.15
|
||||
|
||||
## 0.0.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3df93cc]
|
||||
- jazz-tools@0.9.14
|
||||
- jazz-browser-media-images@0.9.14
|
||||
- jazz-react@0.9.14
|
||||
|
||||
## 0.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.13
|
||||
- jazz-tools@0.9.13
|
||||
- jazz-browser-media-images@0.9.13
|
||||
|
||||
## 0.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.12
|
||||
- jazz-tools@0.9.12
|
||||
- jazz-browser-media-images@0.9.12
|
||||
|
||||
## 0.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.11
|
||||
- jazz-tools@0.9.11
|
||||
- jazz-browser-media-images@0.9.11
|
||||
|
||||
## 0.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5e83864]
|
||||
- jazz-react@0.9.10
|
||||
- jazz-tools@0.9.10
|
||||
- jazz-browser-media-images@0.9.10
|
||||
|
||||
## 0.0.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- jazz-tools@0.9.9
|
||||
- jazz-browser-media-images@0.9.9
|
||||
- jazz-react@0.9.9
|
||||
|
||||
## 0.0.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -17,30 +17,56 @@ converting it into a `BubbleTeaOrder`.
|
||||
|
||||
[See the full guide here.](https://jazz.tools/docs/react/design-patterns/form)
|
||||
|
||||
## Installing & running the example locally
|
||||
## Getting started
|
||||
|
||||
(This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
|
||||
You can either
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
Start by downloading the [jazz repository](https://github.com/garden-co/jazz):
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
```bash
|
||||
npx degit gardencmp/jazz jazz
|
||||
npx create-jazz-app@latest --example form --project-name form
|
||||
```
|
||||
|
||||
Go to the form example directory:
|
||||
Go to the new project directory.
|
||||
```bash
|
||||
cd jazz/examples/form
|
||||
cd form
|
||||
```
|
||||
|
||||
Install and build dependencies:
|
||||
Run the dev server.
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Start the dev server:
|
||||
Go to the example directory.
|
||||
```bash
|
||||
cd jazz/examples/form/
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "form",
|
||||
"private": true,
|
||||
"version": "0.0.24",
|
||||
"version": "0.0.37",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,30 +1,10 @@
|
||||
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import App from "./App.tsx";
|
||||
import "./index.css";
|
||||
import { JazzAccount } from "./schema.ts";
|
||||
|
||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
const [auth, authState] = useDemoAuth();
|
||||
|
||||
return (
|
||||
<>
|
||||
<JazzProvider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=form-example@garden.co"
|
||||
AccountSchema={JazzAccount}
|
||||
>
|
||||
{children}
|
||||
</JazzProvider>
|
||||
|
||||
{authState.state !== "signedIn" && (
|
||||
<DemoAuthBasicUI appName="Form" state={authState} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
declare module "jazz-react" {
|
||||
interface Register {
|
||||
Account: JazzAccount;
|
||||
@@ -33,8 +13,13 @@ declare module "jazz-react" {
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
<JazzAndAuth>
|
||||
<JazzProvider
|
||||
sync={{
|
||||
peer: "wss://cloud.jazz.tools/?key=form-example@garden.co",
|
||||
}}
|
||||
AccountSchema={JazzAccount}
|
||||
>
|
||||
<App />
|
||||
</JazzAndAuth>
|
||||
</JazzProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { LoginPage } from "./pages/LoginPage";
|
||||
|
||||
test("create and edit an order", async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
|
||||
await loginPage.goto();
|
||||
await loginPage.fillUsername("Alice");
|
||||
await loginPage.signup();
|
||||
|
||||
await page.goto("/");
|
||||
// start an order
|
||||
await page.getByRole("link", { name: "Add new order" }).click();
|
||||
await page.getByLabel("Base tea").selectOption("Oolong");
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import { Locator, Page, expect } from "@playwright/test";
|
||||
|
||||
export class LoginPage {
|
||||
readonly page: Page;
|
||||
readonly usernameInput: Locator;
|
||||
readonly signupButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.usernameInput = page.getByRole("textbox");
|
||||
this.signupButton = page.getByRole("button", {
|
||||
name: "Sign up",
|
||||
});
|
||||
}
|
||||
|
||||
async goto() {
|
||||
this.page.goto("/");
|
||||
}
|
||||
|
||||
async fillUsername(value: string) {
|
||||
await this.usernameInput.clear();
|
||||
await this.usernameInput.fill(value);
|
||||
}
|
||||
|
||||
async loginAs(value: string) {
|
||||
await this.page
|
||||
.getByRole("button", {
|
||||
name: value,
|
||||
})
|
||||
.click();
|
||||
}
|
||||
|
||||
async signup() {
|
||||
await this.signupButton.click();
|
||||
}
|
||||
|
||||
async expectLoaded() {
|
||||
await expect(this.signupButton).toBeVisible();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,118 @@
|
||||
# image-upload
|
||||
|
||||
## 0.0.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1be017d]
|
||||
- jazz-tools@0.9.21
|
||||
- jazz-browser-media-images@0.9.21
|
||||
- jazz-react@0.9.21
|
||||
|
||||
## 0.0.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b01cc1f]
|
||||
- jazz-tools@0.9.20
|
||||
- jazz-browser-media-images@0.9.20
|
||||
- jazz-react@0.9.20
|
||||
|
||||
## 0.0.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.19
|
||||
- jazz-tools@0.9.19
|
||||
- jazz-browser-media-images@0.9.19
|
||||
|
||||
## 0.0.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.18
|
||||
- jazz-tools@0.9.18
|
||||
- jazz-browser-media-images@0.9.18
|
||||
|
||||
## 0.0.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c2ca1fe]
|
||||
- Updated dependencies [1227047]
|
||||
- jazz-tools@0.9.17
|
||||
- jazz-browser-media-images@0.9.17
|
||||
- jazz-react@0.9.17
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [24b3b6a]
|
||||
- jazz-tools@0.9.16
|
||||
- jazz-browser-media-images@0.9.16
|
||||
- jazz-react@0.9.16
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7491711]
|
||||
- jazz-tools@0.9.15
|
||||
- jazz-browser-media-images@0.9.15
|
||||
- jazz-react@0.9.15
|
||||
|
||||
## 0.0.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3df93cc]
|
||||
- jazz-tools@0.9.14
|
||||
- jazz-browser-media-images@0.9.14
|
||||
- jazz-react@0.9.14
|
||||
|
||||
## 0.0.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.13
|
||||
- jazz-tools@0.9.13
|
||||
- jazz-browser-media-images@0.9.13
|
||||
|
||||
## 0.0.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.12
|
||||
- jazz-tools@0.9.12
|
||||
- jazz-browser-media-images@0.9.12
|
||||
|
||||
## 0.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.11
|
||||
- jazz-tools@0.9.11
|
||||
- jazz-browser-media-images@0.9.11
|
||||
|
||||
## 0.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5e83864]
|
||||
- jazz-react@0.9.10
|
||||
- jazz-tools@0.9.10
|
||||
- jazz-browser-media-images@0.9.10
|
||||
|
||||
## 0.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- jazz-tools@0.9.9
|
||||
- jazz-browser-media-images@0.9.9
|
||||
- jazz-react@0.9.9
|
||||
|
||||
## 0.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -4,30 +4,56 @@ This is an example of how to upload and render images with Jazz.
|
||||
|
||||
Live version: https://image-upload-demo.jazz.tools
|
||||
|
||||
## Installing & running the example locally
|
||||
## Getting started
|
||||
|
||||
(This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
|
||||
You can either
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
Start by downloading the [jazz repository](https://github.com/garden-co/jazz):
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
```bash
|
||||
npx degit gardencmp/jazz jazz
|
||||
npx create-jazz-app@latest --example image-upload --project-name image-upload
|
||||
```
|
||||
|
||||
Go to the image-upload example directory:
|
||||
Go to the new project directory.
|
||||
```bash
|
||||
cd jazz/examples/image-upload
|
||||
cd image-upload
|
||||
```
|
||||
|
||||
Install and build dependencies:
|
||||
Run the dev server.
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Start the dev server:
|
||||
Go to the example directory.
|
||||
```bash
|
||||
cd jazz/examples/image-upload/
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "image-upload",
|
||||
"private": true,
|
||||
"version": "0.0.26",
|
||||
"version": "0.0.39",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,30 +1,10 @@
|
||||
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import App from "./App.tsx";
|
||||
import "./index.css";
|
||||
import { JazzAccount } from "./schema.ts";
|
||||
|
||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
const [auth, authState] = useDemoAuth();
|
||||
|
||||
return (
|
||||
<>
|
||||
<JazzProvider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=image-upload-example@garden.co"
|
||||
AccountSchema={JazzAccount}
|
||||
>
|
||||
{children}
|
||||
</JazzProvider>
|
||||
|
||||
{authState.state !== "signedIn" && (
|
||||
<DemoAuthBasicUI appName="Image upload" state={authState} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
declare module "jazz-react" {
|
||||
interface Register {
|
||||
Account: JazzAccount;
|
||||
@@ -33,8 +13,13 @@ declare module "jazz-react" {
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
<JazzAndAuth>
|
||||
<JazzProvider
|
||||
sync={{
|
||||
peer: "wss://cloud.jazz.tools/?key=image-upload-example@garden.co",
|
||||
}}
|
||||
AccountSchema={JazzAccount}
|
||||
>
|
||||
<App />
|
||||
</JazzAndAuth>
|
||||
</JazzProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
@@ -1,5 +1,62 @@
|
||||
# jazz-example-inspector
|
||||
|
||||
## 0.0.100
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6ad0a9f]
|
||||
- cojson@0.9.19
|
||||
- cojson-transport-ws@0.9.19
|
||||
|
||||
## 0.0.99
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8898b10]
|
||||
- cojson@0.9.18
|
||||
- cojson-transport-ws@0.9.18
|
||||
|
||||
## 0.0.98
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8d29e50]
|
||||
- cojson-transport-ws@0.9.13
|
||||
- cojson@0.9.13
|
||||
|
||||
## 0.0.97
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [15d4b2a]
|
||||
- cojson-transport-ws@0.9.12
|
||||
- cojson@0.9.12
|
||||
|
||||
## 0.0.96
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [efbf3d8]
|
||||
- Updated dependencies [5863bad]
|
||||
- cojson@0.9.11
|
||||
- cojson-transport-ws@0.9.11
|
||||
|
||||
## 0.0.95
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4aa377d]
|
||||
- cojson@0.9.10
|
||||
- cojson-transport-ws@0.9.10
|
||||
|
||||
## 0.0.94
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- cojson@0.9.9
|
||||
- cojson-transport-ws@0.9.9
|
||||
|
||||
## 0.0.93
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-inspector",
|
||||
"name": "jazz-inspector-app",
|
||||
"private": true,
|
||||
"version": "0.0.93",
|
||||
"version": "0.0.100",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -16,8 +16,8 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"cojson": "workspace:0.9.0",
|
||||
"cojson-transport-ws": "workspace:0.9.0",
|
||||
"cojson": "workspace:0.9.19",
|
||||
"cojson-transport-ws": "workspace:0.9.19",
|
||||
"hash-slash": "workspace:0.2.1",
|
||||
"lucide-react": "^0.274.0",
|
||||
"qrcode": "^1.5.3",
|
||||
|
||||
@@ -1,5 +1,123 @@
|
||||
# jazz-example-musicplayer
|
||||
|
||||
## 0.0.63
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1be017d]
|
||||
- jazz-tools@0.9.21
|
||||
- jazz-inspector@0.9.22
|
||||
- jazz-react@0.9.21
|
||||
|
||||
## 0.0.62
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b01cc1f]
|
||||
- jazz-tools@0.9.20
|
||||
- jazz-inspector@0.9.21
|
||||
- jazz-react@0.9.20
|
||||
|
||||
## 0.0.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-inspector@0.9.20
|
||||
- jazz-react@0.9.19
|
||||
- jazz-tools@0.9.19
|
||||
|
||||
## 0.0.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2faf22f]
|
||||
- jazz-inspector@0.9.19
|
||||
|
||||
## 0.0.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-inspector@0.9.18
|
||||
- jazz-react@0.9.18
|
||||
- jazz-tools@0.9.18
|
||||
|
||||
## 0.0.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c2ca1fe]
|
||||
- Updated dependencies [1227047]
|
||||
- jazz-tools@0.9.17
|
||||
- jazz-inspector@0.9.17
|
||||
- jazz-react@0.9.17
|
||||
|
||||
## 0.0.57
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [24b3b6a]
|
||||
- jazz-tools@0.9.16
|
||||
- jazz-inspector@0.9.16
|
||||
- jazz-react@0.9.16
|
||||
|
||||
## 0.0.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7491711]
|
||||
- jazz-tools@0.9.15
|
||||
- jazz-inspector@0.9.15
|
||||
- jazz-react@0.9.15
|
||||
|
||||
## 0.0.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3df93cc]
|
||||
- jazz-tools@0.9.14
|
||||
- jazz-inspector@0.9.14
|
||||
- jazz-react@0.9.14
|
||||
|
||||
## 0.0.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-inspector@0.9.13
|
||||
- jazz-react@0.9.13
|
||||
- jazz-tools@0.9.13
|
||||
|
||||
## 0.0.53
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-inspector@0.9.12
|
||||
- jazz-react@0.9.12
|
||||
- jazz-tools@0.9.12
|
||||
|
||||
## 0.0.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-inspector@0.9.11
|
||||
- jazz-react@0.9.11
|
||||
- jazz-tools@0.9.11
|
||||
|
||||
## 0.0.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5e83864]
|
||||
- jazz-react@0.9.10
|
||||
- jazz-tools@0.9.10
|
||||
|
||||
## 0.0.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- jazz-tools@0.9.9
|
||||
- jazz-react@0.9.9
|
||||
|
||||
## 0.0.49
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -2,30 +2,56 @@
|
||||
|
||||
Live version: https://music-demo.jazz.tools
|
||||
|
||||
## Installing & running the example locally
|
||||
## Getting started
|
||||
|
||||
(This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
|
||||
You can either
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
Start by downloading the [jazz repository](https://github.com/garden-co/jazz):
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
```bash
|
||||
npx degit gardencmp/jazz jazz
|
||||
npx create-jazz-app@latest --example music-player --project-name music-player
|
||||
```
|
||||
|
||||
Go to the music-player example directory:
|
||||
Go to the new project directory.
|
||||
```bash
|
||||
cd jazz/examples/music-player
|
||||
cd music-player
|
||||
```
|
||||
|
||||
Install and build dependencies:
|
||||
Run the dev server.
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Start the dev server:
|
||||
Go to the example directory.
|
||||
```bash
|
||||
cd jazz/examples/music-player/
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-music-player",
|
||||
"private": true,
|
||||
"version": "0.0.49",
|
||||
"version": "0.0.63",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -13,13 +13,17 @@
|
||||
"test:ui": "playwright test --ui"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-dialog": "^1.1.4",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"@radix-ui/react-label": "^2.1.1",
|
||||
"@radix-ui/react-slot": "^1.1.1",
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"@radix-ui/react-tooltip": "^1.1.6",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-react": "workspace:0.9.8",
|
||||
"jazz-tools": "workspace:0.9.8",
|
||||
"jazz-react": "workspace:0.9.21",
|
||||
"jazz-tools": "workspace:0.9.21",
|
||||
"jazz-inspector": "workspace:*",
|
||||
"lucide-react": "^0.274.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
||||
@@ -86,7 +86,7 @@ export class MusicaAccount extends Account {
|
||||
* You can use it to set up the account root and any other initial CoValues you need.
|
||||
*/
|
||||
migrate() {
|
||||
if (!this._refs.root) {
|
||||
if (this.root === undefined) {
|
||||
const ownership = { owner: this };
|
||||
|
||||
const tracks = ListOfTracks.create([], ownership);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Toaster } from "@/components/ui/toaster";
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
/* eslint-disable react-refresh/only-export-components */
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
@@ -10,7 +11,7 @@ import { PlayerControls } from "./components/PlayerControls";
|
||||
import "./index.css";
|
||||
|
||||
import { MusicaAccount } from "@/1_schema";
|
||||
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { useUploadExampleData } from "./lib/useUploadExampleData";
|
||||
|
||||
/**
|
||||
@@ -53,29 +54,11 @@ function Main() {
|
||||
);
|
||||
}
|
||||
|
||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
const [auth, state] = useDemoAuth();
|
||||
|
||||
const peer =
|
||||
(new URL(window.location.href).searchParams.get(
|
||||
"peer",
|
||||
) as `ws://${string}`) ??
|
||||
"wss://cloud.jazz.tools/?key=music-player-example-jazz@garden.co";
|
||||
|
||||
return (
|
||||
<>
|
||||
<JazzProvider
|
||||
storage="indexedDB"
|
||||
auth={auth}
|
||||
peer={peer}
|
||||
AccountSchema={MusicaAccount}
|
||||
>
|
||||
{children}
|
||||
</JazzProvider>
|
||||
<DemoAuthBasicUI appName="Jazz Music Player" state={state} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
const peer =
|
||||
(new URL(window.location.href).searchParams.get(
|
||||
"peer",
|
||||
) as `ws://${string}`) ??
|
||||
"wss://cloud.jazz.tools/?key=music-player-example-jazz@garden.co";
|
||||
|
||||
declare module "jazz-react" {
|
||||
interface Register {
|
||||
@@ -85,8 +68,17 @@ declare module "jazz-react" {
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<React.StrictMode>
|
||||
<JazzAndAuth>
|
||||
<JazzProvider
|
||||
sync={{
|
||||
peer,
|
||||
when: "signedUp", // This makes the app work in local mode when the user is anonymous
|
||||
}}
|
||||
storage="indexedDB"
|
||||
AccountSchema={MusicaAccount}
|
||||
defaultProfileName="Anonymous unicorn"
|
||||
>
|
||||
<Main />
|
||||
</JazzAndAuth>
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { createInviteLink, useAccount, useCoState } from "jazz-react";
|
||||
import {
|
||||
createInviteLink,
|
||||
useAccount,
|
||||
useCoState,
|
||||
useIsAuthenticated,
|
||||
} from "jazz-react";
|
||||
import { ID } from "jazz-tools";
|
||||
import { useNavigate, useParams } from "react-router";
|
||||
import { Playlist } from "./1_schema";
|
||||
import { createNewPlaylist, uploadMusicTracks } from "./4_actions";
|
||||
import { MediaPlayer } from "./5_useMediaPlayer";
|
||||
import { AuthButton } from "./components/AuthButton";
|
||||
import { FileUploadButton } from "./components/FileUploadButton";
|
||||
import { LogoutButton } from "./components/LogoutButton";
|
||||
import { MusicTrackRow } from "./components/MusicTrackRow";
|
||||
import { PlaylistTitleInput } from "./components/PlaylistTitleInput";
|
||||
import { SidePanel } from "./components/SidePanel";
|
||||
@@ -66,6 +71,8 @@ export function HomePage({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
|
||||
});
|
||||
};
|
||||
|
||||
const isAuthenticated = useIsAuthenticated();
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-screen text-gray-800 bg-blue-50">
|
||||
<div className="flex flex-1 overflow-hidden">
|
||||
@@ -86,12 +93,12 @@ export function HomePage({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
|
||||
<Button onClick={handleCreatePlaylist}>New playlist</Button>
|
||||
</>
|
||||
)}
|
||||
{!isRootPlaylist && (
|
||||
{!isRootPlaylist && isAuthenticated && (
|
||||
<Button onClick={handlePlaylistShareClick}>
|
||||
Share playlist
|
||||
</Button>
|
||||
)}
|
||||
<LogoutButton />
|
||||
<AuthButton />
|
||||
</div>
|
||||
</div>
|
||||
<ul className="flex flex-col">
|
||||
|
||||
40
examples/music-player/src/components/AuthButton.tsx
Normal file
40
examples/music-player/src/components/AuthButton.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useAccount, useIsAuthenticated } from "jazz-react";
|
||||
import { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { AuthModal } from "./AuthModal";
|
||||
|
||||
export function AuthButton() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const { logOut } = useAccount();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const isAuthenticated = useIsAuthenticated();
|
||||
|
||||
function handleSignOut() {
|
||||
logOut();
|
||||
navigate("/");
|
||||
}
|
||||
|
||||
if (isAuthenticated) {
|
||||
return (
|
||||
<Button variant="outline" onClick={handleSignOut}>
|
||||
Sign out
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
onClick={() => setOpen(true)}
|
||||
className="bg-white text-black hover:bg-gray-100"
|
||||
>
|
||||
Sign up
|
||||
</Button>
|
||||
<AuthModal open={open} onOpenChange={setOpen} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
97
examples/music-player/src/components/AuthModal.tsx
Normal file
97
examples/music-player/src/components/AuthModal.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { usePasskeyAuth } from "jazz-react";
|
||||
import { useState } from "react";
|
||||
|
||||
interface AuthModalProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
}
|
||||
|
||||
export function AuthModal({ open, onOpenChange }: AuthModalProps) {
|
||||
const [username, setUsername] = useState("");
|
||||
const [isSignUp, setIsSignUp] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const auth = usePasskeyAuth({
|
||||
appName: "Jazz Music Player",
|
||||
});
|
||||
|
||||
const handleViewChange = () => {
|
||||
setIsSignUp(!isSignUp);
|
||||
setError(null);
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
try {
|
||||
if (isSignUp) {
|
||||
await auth.signUp(username);
|
||||
} else {
|
||||
await auth.logIn();
|
||||
}
|
||||
onOpenChange(false);
|
||||
} catch (error) {
|
||||
setError(error instanceof Error ? error.message : "Unknown error");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="sm:max-w-[425px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-2xl font-bold">
|
||||
{isSignUp ? "Create account" : "Welcome back"}
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
{isSignUp
|
||||
? "Sign up to enable network sync and share your playlists with others"
|
||||
: "Changes done before logging in will be lost"}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
{isSignUp && (
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="username">Username</Label>
|
||||
<Input
|
||||
id="username"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
placeholder="Enter your username"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{error && <div className="text-sm text-red-500">{error}</div>}
|
||||
<div className="space-y-4">
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full bg-blue-600 hover:bg-blue-700"
|
||||
>
|
||||
{isSignUp ? "Sign up with passkey" : "Login with passkey"}
|
||||
</Button>
|
||||
<div className="text-center text-sm">
|
||||
{isSignUp ? "Already have an account?" : "Don't have an account?"}{" "}
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleViewChange}
|
||||
className="text-blue-600 hover:underline"
|
||||
>
|
||||
{isSignUp ? "Login" : "Sign up"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
37
examples/music-player/src/components/LocalOnlyTag.tsx
Normal file
37
examples/music-player/src/components/LocalOnlyTag.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { useIsAuthenticated } from "jazz-react";
|
||||
import { Info } from "lucide-react";
|
||||
|
||||
export function LocalOnlyTag() {
|
||||
const isAuthenticated = useIsAuthenticated();
|
||||
|
||||
if (isAuthenticated) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div className="inline-flex items-center gap-1.5 cursor-help">
|
||||
<Badge variant="default" className="h-5 text-xs font-normal">
|
||||
Local only
|
||||
</Badge>
|
||||
<Info className="h-3.5 w-3.5 text-muted-foreground" />
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="max-w-[250px]">
|
||||
<p>
|
||||
Sign up to enable network sync and share your playlists with others
|
||||
</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useAccount } from "jazz-react";
|
||||
import { useNavigate, useParams } from "react-router";
|
||||
import { LocalOnlyTag } from "./LocalOnlyTag";
|
||||
|
||||
export function SidePanel() {
|
||||
const { playlistId } = useParams();
|
||||
@@ -25,7 +26,7 @@ export function SidePanel() {
|
||||
|
||||
return (
|
||||
<aside className="w-64 p-6 bg-white overflow-y-auto">
|
||||
<div className="flex items-center mb-6">
|
||||
<div className="flex items-center mb-1">
|
||||
<svg
|
||||
className="w-8 h-8 mr-2"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -46,6 +47,9 @@ export function SidePanel() {
|
||||
</svg>
|
||||
<span className="text-xl font-bold text-blue-600">Music Player</span>
|
||||
</div>
|
||||
<div className="mb-6">
|
||||
<LocalOnlyTag />
|
||||
</div>
|
||||
<nav>
|
||||
<h2 className="mb-2 text-sm font-semibold text-gray-600">Playlists</h2>
|
||||
<ul className="space-y-1">
|
||||
|
||||
36
examples/music-player/src/components/ui/badge.tsx
Normal file
36
examples/music-player/src/components/ui/badge.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import { type VariantProps, cva } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const badgeVariants = cva(
|
||||
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
|
||||
secondary:
|
||||
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
destructive:
|
||||
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
||||
outline: "text-foreground",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
export interface BadgeProps
|
||||
extends React.HTMLAttributes<HTMLDivElement>,
|
||||
VariantProps<typeof badgeVariants> {}
|
||||
|
||||
function Badge({ className, variant, ...props }: BadgeProps) {
|
||||
return (
|
||||
<div className={cn(badgeVariants({ variant }), className)} {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
export { Badge, badgeVariants };
|
||||
120
examples/music-player/src/components/ui/dialog.tsx
Normal file
120
examples/music-player/src/components/ui/dialog.tsx
Normal file
@@ -0,0 +1,120 @@
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||
import { X } from "lucide-react";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Dialog = DialogPrimitive.Root;
|
||||
|
||||
const DialogTrigger = DialogPrimitive.Trigger;
|
||||
|
||||
const DialogPortal = DialogPrimitive.Portal;
|
||||
|
||||
const DialogClose = DialogPrimitive.Close;
|
||||
|
||||
const DialogOverlay = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Overlay>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Overlay
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
||||
|
||||
const DialogContent = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<DialogPortal>
|
||||
<DialogOverlay />
|
||||
<DialogPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||
<X className="h-4 w-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
</DialogPrimitive.Content>
|
||||
</DialogPortal>
|
||||
));
|
||||
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
||||
|
||||
const DialogHeader = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col space-y-1.5 text-center sm:text-left",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
DialogHeader.displayName = "DialogHeader";
|
||||
|
||||
const DialogFooter = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
DialogFooter.displayName = "DialogFooter";
|
||||
|
||||
const DialogTitle = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Title>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Title
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"text-lg font-semibold leading-none tracking-tight",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
||||
|
||||
const DialogDescription = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Description>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Description
|
||||
ref={ref}
|
||||
className={cn("text-sm text-muted-foreground", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
||||
|
||||
export {
|
||||
Dialog,
|
||||
DialogPortal,
|
||||
DialogOverlay,
|
||||
DialogClose,
|
||||
DialogTrigger,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogFooter,
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
};
|
||||
22
examples/music-player/src/components/ui/input.tsx
Normal file
22
examples/music-player/src/components/ui/input.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
|
||||
({ className, type, ...props }, ref) => {
|
||||
return (
|
||||
<input
|
||||
type={type}
|
||||
className={cn(
|
||||
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
Input.displayName = "Input";
|
||||
|
||||
export { Input };
|
||||
24
examples/music-player/src/components/ui/label.tsx
Normal file
24
examples/music-player/src/components/ui/label.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import * as LabelPrimitive from "@radix-ui/react-label";
|
||||
import { type VariantProps, cva } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const labelVariants = cva(
|
||||
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
);
|
||||
|
||||
const Label = React.forwardRef<
|
||||
React.ElementRef<typeof LabelPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
|
||||
VariantProps<typeof labelVariants>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<LabelPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(labelVariants(), className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
Label.displayName = LabelPrimitive.Root.displayName;
|
||||
|
||||
export { Label };
|
||||
30
examples/music-player/src/components/ui/tooltip.tsx
Normal file
30
examples/music-player/src/components/ui/tooltip.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
"use client";
|
||||
|
||||
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const TooltipProvider = TooltipPrimitive.Provider;
|
||||
|
||||
const Tooltip = TooltipPrimitive.Root;
|
||||
|
||||
const TooltipTrigger = TooltipPrimitive.Trigger;
|
||||
|
||||
const TooltipContent = React.forwardRef<
|
||||
React.ElementRef<typeof TooltipPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
|
||||
>(({ className, sideOffset = 4, ...props }, ref) => (
|
||||
<TooltipPrimitive.Content
|
||||
ref={ref}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
||||
|
||||
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
||||
@@ -1,11 +1,14 @@
|
||||
import { MusicaAccount } from "@/1_schema";
|
||||
import { useAccount } from "jazz-react";
|
||||
import { useEffect } from "react";
|
||||
import { uploadMusicTracks } from "../4_actions";
|
||||
|
||||
export function useUploadExampleData() {
|
||||
const { me } = useAccount();
|
||||
|
||||
useEffect(() => {
|
||||
uploadOnboardingData();
|
||||
}, []);
|
||||
}, [me.id]);
|
||||
}
|
||||
|
||||
async function uploadOnboardingData() {
|
||||
|
||||
@@ -1,44 +1,84 @@
|
||||
import { test } from "@playwright/test";
|
||||
import { BrowserContext, test } from "@playwright/test";
|
||||
import { HomePage } from "./pages/HomePage";
|
||||
import { LoginPage } from "./pages/LoginPage";
|
||||
|
||||
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
test("create a new playlist and share", async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
async function mockAuthenticator(context: BrowserContext) {
|
||||
await context.addInitScript(() => {
|
||||
Object.defineProperty(window.navigator, "credentials", {
|
||||
value: {
|
||||
...window.navigator.credentials,
|
||||
create: async () => ({
|
||||
type: "public-key",
|
||||
id: new Uint8Array([1, 2, 3, 4]),
|
||||
rawId: new Uint8Array([1, 2, 3, 4]),
|
||||
response: {
|
||||
clientDataJSON: new Uint8Array([1]),
|
||||
attestationObject: new Uint8Array([2]),
|
||||
},
|
||||
}),
|
||||
get: async () => ({
|
||||
type: "public-key",
|
||||
id: new Uint8Array([1, 2, 3, 4]),
|
||||
rawId: new Uint8Array([1, 2, 3, 4]),
|
||||
response: {
|
||||
authenticatorData: new Uint8Array([1]),
|
||||
clientDataJSON: new Uint8Array([2]),
|
||||
signature: new Uint8Array([3]),
|
||||
},
|
||||
}),
|
||||
},
|
||||
configurable: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
await loginPage.goto();
|
||||
await loginPage.fillUsername("S. Mario");
|
||||
await loginPage.signup();
|
||||
// Configure the authenticator
|
||||
test.beforeEach(async ({ context }) => {
|
||||
// Enable virtual authenticator environment
|
||||
await mockAuthenticator(context);
|
||||
});
|
||||
|
||||
const homePage = new HomePage(page);
|
||||
test("create a new playlist and share", async ({
|
||||
page: marioPage,
|
||||
browser,
|
||||
}) => {
|
||||
await marioPage.goto("/");
|
||||
|
||||
const marioHome = new HomePage(marioPage);
|
||||
|
||||
// The example song should be loaded
|
||||
await homePage.expectMusicTrack("Example song");
|
||||
await homePage.editTrackTitle("Example song", "Super Mario World");
|
||||
await marioHome.expectMusicTrack("Example song");
|
||||
await marioHome.editTrackTitle("Example song", "Super Mario World");
|
||||
|
||||
await homePage.createPlaylist();
|
||||
await homePage.editPlaylistTitle("Save the princess");
|
||||
await marioHome.createPlaylist();
|
||||
await marioHome.editPlaylistTitle("Save the princess");
|
||||
|
||||
await homePage.navigateToPlaylist("All tracks");
|
||||
await homePage.addTrackToPlaylist("Super Mario World", "Save the princess");
|
||||
await marioHome.navigateToPlaylist("All tracks");
|
||||
await marioHome.addTrackToPlaylist("Super Mario World", "Save the princess");
|
||||
|
||||
await homePage.navigateToPlaylist("Save the princess");
|
||||
await homePage.expectMusicTrack("Super Mario World");
|
||||
await marioHome.navigateToPlaylist("Save the princess");
|
||||
await marioHome.expectMusicTrack("Super Mario World");
|
||||
|
||||
const url = await homePage.getShareLink();
|
||||
await marioHome.signUp("Mario");
|
||||
|
||||
const url = await marioHome.getShareLink();
|
||||
|
||||
await sleep(4000); // Wait for the sync to complete
|
||||
|
||||
await homePage.logout();
|
||||
const luigiContext = await browser.newContext();
|
||||
await mockAuthenticator(luigiContext);
|
||||
|
||||
await loginPage.goto();
|
||||
await loginPage.fillUsername("Luigi");
|
||||
await loginPage.signup();
|
||||
const luigiPage = await luigiContext.newPage();
|
||||
await luigiPage.goto("/");
|
||||
|
||||
await page.goto(url);
|
||||
const luigiHome = new HomePage(luigiPage);
|
||||
|
||||
await homePage.expectMusicTrack("Super Mario World");
|
||||
await homePage.playMusicTrack("Super Mario World");
|
||||
await homePage.expectActiveTrackPlaying();
|
||||
await luigiHome.signUp("Luigi");
|
||||
|
||||
await luigiPage.goto(url);
|
||||
|
||||
await luigiHome.expectMusicTrack("Super Mario World");
|
||||
await luigiHome.playMusicTrack("Super Mario World");
|
||||
await luigiHome.expectActiveTrackPlaying();
|
||||
});
|
||||
|
||||
@@ -95,6 +95,17 @@ export class HomePage {
|
||||
.click();
|
||||
}
|
||||
|
||||
async signUp(name: string) {
|
||||
await this.page.getByRole("button", { name: "Sign up" }).click();
|
||||
await this.page.getByRole("textbox", { name: "Username" }).fill(name);
|
||||
await this.page
|
||||
.getByRole("button", { name: "Sign up with passkey" })
|
||||
.click();
|
||||
await expect(
|
||||
this.page.getByRole("button", { name: "Sign out" }),
|
||||
).toBeVisible();
|
||||
}
|
||||
|
||||
async logout() {
|
||||
await this.logoutButton.click();
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import { Locator, Page, expect } from "@playwright/test";
|
||||
|
||||
export class LoginPage {
|
||||
readonly page: Page;
|
||||
readonly usernameInput: Locator;
|
||||
readonly signupButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.usernameInput = page.getByRole("textbox");
|
||||
this.signupButton = page.getByRole("button", {
|
||||
name: "Sign up",
|
||||
});
|
||||
}
|
||||
|
||||
async goto() {
|
||||
this.page.goto("/");
|
||||
}
|
||||
|
||||
async fillUsername(value: string) {
|
||||
await this.usernameInput.clear();
|
||||
await this.usernameInput.fill(value);
|
||||
}
|
||||
|
||||
async loginAs(value: string) {
|
||||
await this.page
|
||||
.getByRole("button", {
|
||||
name: value,
|
||||
})
|
||||
.click();
|
||||
}
|
||||
|
||||
async signup() {
|
||||
await this.signupButton.click();
|
||||
}
|
||||
|
||||
async expectLoaded() {
|
||||
await expect(this.signupButton).toBeVisible();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,118 @@
|
||||
# jazz-example-onboarding
|
||||
|
||||
## 0.0.43
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1be017d]
|
||||
- jazz-tools@0.9.21
|
||||
- jazz-browser-media-images@0.9.21
|
||||
- jazz-react@0.9.21
|
||||
|
||||
## 0.0.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b01cc1f]
|
||||
- jazz-tools@0.9.20
|
||||
- jazz-browser-media-images@0.9.20
|
||||
- jazz-react@0.9.20
|
||||
|
||||
## 0.0.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.19
|
||||
- jazz-tools@0.9.19
|
||||
- jazz-browser-media-images@0.9.19
|
||||
|
||||
## 0.0.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.18
|
||||
- jazz-tools@0.9.18
|
||||
- jazz-browser-media-images@0.9.18
|
||||
|
||||
## 0.0.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c2ca1fe]
|
||||
- Updated dependencies [1227047]
|
||||
- jazz-tools@0.9.17
|
||||
- jazz-browser-media-images@0.9.17
|
||||
- jazz-react@0.9.17
|
||||
|
||||
## 0.0.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [24b3b6a]
|
||||
- jazz-tools@0.9.16
|
||||
- jazz-browser-media-images@0.9.16
|
||||
- jazz-react@0.9.16
|
||||
|
||||
## 0.0.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7491711]
|
||||
- jazz-tools@0.9.15
|
||||
- jazz-browser-media-images@0.9.15
|
||||
- jazz-react@0.9.15
|
||||
|
||||
## 0.0.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3df93cc]
|
||||
- jazz-tools@0.9.14
|
||||
- jazz-browser-media-images@0.9.14
|
||||
- jazz-react@0.9.14
|
||||
|
||||
## 0.0.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.13
|
||||
- jazz-tools@0.9.13
|
||||
- jazz-browser-media-images@0.9.13
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.12
|
||||
- jazz-tools@0.9.12
|
||||
- jazz-browser-media-images@0.9.12
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.11
|
||||
- jazz-tools@0.9.11
|
||||
- jazz-browser-media-images@0.9.11
|
||||
|
||||
## 0.0.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5e83864]
|
||||
- jazz-react@0.9.10
|
||||
- jazz-tools@0.9.10
|
||||
- jazz-browser-media-images@0.9.10
|
||||
|
||||
## 0.0.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- jazz-tools@0.9.9
|
||||
- jazz-browser-media-images@0.9.9
|
||||
- jazz-react@0.9.9
|
||||
|
||||
## 0.0.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,29 +1,54 @@
|
||||
# Onboarding example with Jazz and React
|
||||
|
||||
## Installing & running the example locally
|
||||
## Getting started
|
||||
|
||||
(This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
|
||||
You can either
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
Start by downloading the [jazz repository](https://github.com/garden-co/jazz):
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
```bash
|
||||
npx degit gardencmp/jazz jazz
|
||||
npx create-jazz-app@latest --example onboarding --project-name onboarding
|
||||
```
|
||||
|
||||
Go to the onboarding example directory:
|
||||
Go to the new project directory.
|
||||
```bash
|
||||
cd jazz/examples/onboarding
|
||||
cd onboarding
|
||||
```
|
||||
|
||||
Install and build dependencies:
|
||||
Run the dev server.
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Start the dev server:
|
||||
Go to the example directory.
|
||||
```bash
|
||||
cd jazz/examples/onboarding/
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jazz-example-onboarding",
|
||||
"private": true,
|
||||
"version": "0.0.30",
|
||||
"version": "0.0.43",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import App from "@/App.tsx";
|
||||
import "@/index.css";
|
||||
import { HRAccount } from "@/schema.ts";
|
||||
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
|
||||
@@ -11,20 +11,6 @@ const peer =
|
||||
) as `ws://${string}`) ??
|
||||
"wss://cloud.jazz.tools/?key=onboarding-example-jazz@garden.co";
|
||||
|
||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
const [auth, authState] = useDemoAuth();
|
||||
return (
|
||||
<>
|
||||
<JazzProvider AccountSchema={HRAccount} auth={auth} peer={peer}>
|
||||
{children}
|
||||
</JazzProvider>
|
||||
{authState.state !== "signedIn" && (
|
||||
<DemoAuthBasicUI appName="Jazz Onboarding" state={authState} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
declare module "jazz-react" {
|
||||
interface Register {
|
||||
Account: HRAccount;
|
||||
@@ -33,8 +19,13 @@ declare module "jazz-react" {
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<React.StrictMode>
|
||||
<JazzAndAuth>
|
||||
<JazzProvider
|
||||
AccountSchema={HRAccount}
|
||||
sync={{
|
||||
peer,
|
||||
}}
|
||||
>
|
||||
<App />
|
||||
</JazzAndAuth>
|
||||
</JazzProvider>
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
||||
@@ -16,25 +16,6 @@ async function scrollToBottom(page: Page) {
|
||||
});
|
||||
}
|
||||
|
||||
const login = async ({
|
||||
page,
|
||||
userName,
|
||||
loginAs = false,
|
||||
}: {
|
||||
page: Page;
|
||||
userName: string;
|
||||
loginAs?: boolean;
|
||||
}) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
await loginPage.goto("/");
|
||||
if (loginAs) {
|
||||
await loginPage.loginAs(userName);
|
||||
} else {
|
||||
await loginPage.fillUsername(userName);
|
||||
await loginPage.signup();
|
||||
}
|
||||
};
|
||||
|
||||
test.describe("Admin onboarding flow", () => {
|
||||
let browser: Browser;
|
||||
let adminContext: BrowserContext;
|
||||
@@ -54,7 +35,7 @@ test.describe("Admin onboarding flow", () => {
|
||||
|
||||
test("Create and delete flow", async () => {
|
||||
const adminPage = await adminContext.newPage();
|
||||
await login({ page: adminPage, userName: "HR specialist" });
|
||||
await adminPage.goto("/");
|
||||
const adminHomePage = new HomePage(adminPage);
|
||||
await adminHomePage.createEmployee("Paul");
|
||||
await adminHomePage.createEmployee("Sean");
|
||||
@@ -70,10 +51,8 @@ test.describe("Admin onboarding flow", () => {
|
||||
const adminPage = await adminContext.newPage();
|
||||
const writerPage = await writerContext.newPage();
|
||||
|
||||
const adminUser = "HR specialist";
|
||||
const writerUser = "Invitee";
|
||||
await login({ page: adminPage, userName: adminUser });
|
||||
await login({ page: writerPage, userName: writerUser });
|
||||
await adminPage.goto("/");
|
||||
await writerPage.goto("/");
|
||||
|
||||
const adminHomePage = new HomePage(adminPage);
|
||||
await adminHomePage.createEmployee("Paul");
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// vite.config.ts
|
||||
import path from "path";
|
||||
import react from "file:///Users/brad/dev/jazz/node_modules/@vitejs/plugin-react-swc/index.mjs";
|
||||
import topLevelAwait from "file:///Users/brad/dev/jazz/node_modules/vite-plugin-top-level-await/exports/import.mjs";
|
||||
import { defineConfig } from "file:///Users/brad/dev/jazz/node_modules/vite/dist/node/index.js";
|
||||
var __vite_injected_original_dirname =
|
||||
"/Users/brad/dev/jazz/examples/onboarding";
|
||||
var vite_config_default = defineConfig({
|
||||
plugins: [react(), topLevelAwait()],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__vite_injected_original_dirname, "./src"),
|
||||
},
|
||||
},
|
||||
build: {
|
||||
minify: false,
|
||||
},
|
||||
});
|
||||
export { vite_config_default as default };
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvVXNlcnMvYnJhZC9kZXYvamF6ei9leGFtcGxlcy9vbmJvYXJkaW5nXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCIvVXNlcnMvYnJhZC9kZXYvamF6ei9leGFtcGxlcy9vbmJvYXJkaW5nL3ZpdGUuY29uZmlnLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9Vc2Vycy9icmFkL2Rldi9qYXp6L2V4YW1wbGVzL29uYm9hcmRpbmcvdml0ZS5jb25maWcudHNcIjtpbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHJlYWN0IGZyb20gXCJAdml0ZWpzL3BsdWdpbi1yZWFjdC1zd2NcIjtcbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gXCJ2aXRlXCI7XG5pbXBvcnQgdG9wTGV2ZWxBd2FpdCBmcm9tIFwidml0ZS1wbHVnaW4tdG9wLWxldmVsLWF3YWl0XCI7XG5cbi8vIGh0dHBzOi8vdml0ZWpzLmRldi9jb25maWcvXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xuICBwbHVnaW5zOiBbcmVhY3QoKSwgdG9wTGV2ZWxBd2FpdCgpXSxcbiAgcmVzb2x2ZToge1xuICAgIGFsaWFzOiB7XG4gICAgICBcIkBcIjogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgXCIuL3NyY1wiKSxcbiAgICB9LFxuICB9LFxuICBidWlsZDoge1xuICAgIG1pbmlmeTogZmFsc2UsXG4gIH0sXG59KTtcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBMFMsT0FBTyxVQUFVO0FBQzNULE9BQU8sV0FBVztBQUNsQixTQUFTLG9CQUFvQjtBQUM3QixPQUFPLG1CQUFtQjtBQUgxQixJQUFNLG1DQUFtQztBQU16QyxJQUFPLHNCQUFRLGFBQWE7QUFBQSxFQUMxQixTQUFTLENBQUMsTUFBTSxHQUFHLGNBQWMsQ0FBQztBQUFBLEVBQ2xDLFNBQVM7QUFBQSxJQUNQLE9BQU87QUFBQSxNQUNMLEtBQUssS0FBSyxRQUFRLGtDQUFXLE9BQU87QUFBQSxJQUN0QztBQUFBLEVBQ0Y7QUFBQSxFQUNBLE9BQU87QUFBQSxJQUNMLFFBQVE7QUFBQSxFQUNWO0FBQ0YsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
|
||||
@@ -1,5 +1,105 @@
|
||||
# organization
|
||||
|
||||
## 0.0.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1be017d]
|
||||
- jazz-tools@0.9.21
|
||||
- jazz-react@0.9.21
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b01cc1f]
|
||||
- jazz-tools@0.9.20
|
||||
- jazz-react@0.9.20
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.19
|
||||
- jazz-tools@0.9.19
|
||||
|
||||
## 0.0.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.18
|
||||
- jazz-tools@0.9.18
|
||||
|
||||
## 0.0.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c2ca1fe]
|
||||
- Updated dependencies [1227047]
|
||||
- jazz-tools@0.9.17
|
||||
- jazz-react@0.9.17
|
||||
|
||||
## 0.0.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [24b3b6a]
|
||||
- jazz-tools@0.9.16
|
||||
- jazz-react@0.9.16
|
||||
|
||||
## 0.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7491711]
|
||||
- jazz-tools@0.9.15
|
||||
- jazz-react@0.9.15
|
||||
|
||||
## 0.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3df93cc]
|
||||
- jazz-tools@0.9.14
|
||||
- jazz-react@0.9.14
|
||||
|
||||
## 0.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.13
|
||||
- jazz-tools@0.9.13
|
||||
|
||||
## 0.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.12
|
||||
- jazz-tools@0.9.12
|
||||
|
||||
## 0.0.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.11
|
||||
- jazz-tools@0.9.11
|
||||
|
||||
## 0.0.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5e83864]
|
||||
- jazz-react@0.9.10
|
||||
- jazz-tools@0.9.10
|
||||
|
||||
## 0.0.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- jazz-tools@0.9.9
|
||||
- jazz-react@0.9.9
|
||||
|
||||
## 0.0.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -5,30 +5,56 @@ Different apps have different names for this concept, such as "teams" or "worksp
|
||||
|
||||
Refer to the [documentation](https://jazz.tools/docs/react/design-patterns/organization) for more information.
|
||||
|
||||
## Installing & running the example locally
|
||||
## Getting started
|
||||
|
||||
(This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
|
||||
You can either
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
Start by downloading the [jazz repository](https://github.com/garden-co/jazz):
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
```bash
|
||||
npx degit gardencmp/jazz jazz
|
||||
npx create-jazz-app@latest --example organization --project-name organization
|
||||
```
|
||||
|
||||
Go to the organization example directory:
|
||||
Go to the new project directory.
|
||||
```bash
|
||||
cd jazz/examples/organization
|
||||
cd organization
|
||||
```
|
||||
|
||||
Install and build dependencies:
|
||||
Run the dev server.
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Start the dev server:
|
||||
Go to the example directory.
|
||||
```bash
|
||||
cd jazz/examples/organization/
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "organization",
|
||||
"private": true,
|
||||
"version": "0.0.22",
|
||||
"version": "0.0.35",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import "./index.css";
|
||||
@@ -27,26 +27,6 @@ function Router() {
|
||||
return <RouterProvider router={router}></RouterProvider>;
|
||||
}
|
||||
|
||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
const [auth, authState] = useDemoAuth();
|
||||
|
||||
return (
|
||||
<>
|
||||
<JazzProvider
|
||||
AccountSchema={JazzAccount}
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=organization-example@garden.co"
|
||||
>
|
||||
{children}
|
||||
</JazzProvider>
|
||||
|
||||
{authState.state !== "signedIn" && (
|
||||
<DemoAuthBasicUI appName="Organization" state={authState} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
declare module "jazz-react" {
|
||||
interface Register {
|
||||
Account: JazzAccount;
|
||||
@@ -55,8 +35,13 @@ declare module "jazz-react" {
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
<JazzAndAuth>
|
||||
<JazzProvider
|
||||
AccountSchema={JazzAccount}
|
||||
sync={{
|
||||
peer: "wss://cloud.jazz.tools/?key=organization-example@garden.co",
|
||||
}}
|
||||
>
|
||||
<Router />
|
||||
</JazzAndAuth>
|
||||
</JazzProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
@@ -1,5 +1,83 @@
|
||||
# passkey-svelte
|
||||
|
||||
## 0.0.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.21
|
||||
|
||||
## 0.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.20
|
||||
|
||||
## 0.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.19
|
||||
|
||||
## 0.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.18
|
||||
|
||||
## 0.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.17
|
||||
|
||||
## 0.0.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.16
|
||||
|
||||
## 0.0.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.15
|
||||
|
||||
## 0.0.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.14
|
||||
|
||||
## 0.0.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.13
|
||||
|
||||
## 0.0.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.12
|
||||
|
||||
## 0.0.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.11
|
||||
|
||||
## 0.0.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.10
|
||||
|
||||
## 0.0.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.9.9
|
||||
|
||||
## 0.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -10,34 +10,55 @@ This example showcases how to:
|
||||
- Manage authentication state
|
||||
- Implement secure login/logout flows
|
||||
|
||||
## Getting Started
|
||||
## Getting started
|
||||
|
||||
1. Clone the repository:
|
||||
You can either
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
```sh
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
```bash
|
||||
npx create-jazz-app@latest --example passkey-svelte --project-name passkey-svelte
|
||||
```
|
||||
|
||||
Go to the new project directory.
|
||||
```bash
|
||||
cd passkey-svelte
|
||||
```
|
||||
|
||||
Run the dev server.
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
2. Navigate to the example directory:
|
||||
|
||||
```sh
|
||||
cd examples/passkey-svelte
|
||||
Install and build dependencies.
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
3. Install dependencies:
|
||||
|
||||
```sh
|
||||
pnpm install
|
||||
Go to the example directory.
|
||||
```bash
|
||||
cd jazz/examples/passkey-svelte/
|
||||
```
|
||||
|
||||
4. Start the development server:
|
||||
|
||||
```sh
|
||||
Start the dev server.
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
5. Open your browser and visit [http://localhost:5173](http://localhost:5173)
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
|
||||
## Learn More
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "passkey-svelte",
|
||||
"version": "0.0.17",
|
||||
"version": "0.0.30",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,27 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { JazzProvider, PasskeyAuthBasicUI, usePasskeyAuth } from 'jazz-svelte';
|
||||
import { JazzProvider, PasskeyAuthBasicUI } from 'jazz-svelte';
|
||||
|
||||
let { children } = $props();
|
||||
|
||||
let auth = usePasskeyAuth({ appName: 'minimal-svelte-auth-passkey' });
|
||||
|
||||
$inspect(auth.state);
|
||||
</script>
|
||||
|
||||
<div
|
||||
style="width: 100vw; height: 100vh; display: flex; align-items: center; justify-content: center;"
|
||||
<JazzProvider
|
||||
sync={{
|
||||
peer: "wss://cloud.jazz.tools/?key=minimal-svelte-auth-passkey@garden.co",
|
||||
when: "signedUp",
|
||||
}}
|
||||
>
|
||||
<PasskeyAuthBasicUI state={auth.state} />
|
||||
|
||||
{#if auth.current}
|
||||
<JazzProvider
|
||||
auth={auth.current}
|
||||
peer="wss://cloud.jazz.tools/?key=minimal-svelte-auth-passkey@garden.co"
|
||||
>
|
||||
{@render children?.()}
|
||||
</JazzProvider>
|
||||
{/if}
|
||||
</div>
|
||||
<PasskeyAuthBasicUI appName="minimal-svelte-auth-passkey">
|
||||
{@render children?.()}
|
||||
</PasskeyAuthBasicUI>
|
||||
</JazzProvider>
|
||||
|
||||
<style>
|
||||
:global(html, body) {
|
||||
|
||||
@@ -1,5 +1,105 @@
|
||||
# minimal-auth-passkey
|
||||
|
||||
## 0.0.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1be017d]
|
||||
- jazz-tools@0.9.21
|
||||
- jazz-react@0.9.21
|
||||
|
||||
## 0.0.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b01cc1f]
|
||||
- jazz-tools@0.9.20
|
||||
- jazz-react@0.9.20
|
||||
|
||||
## 0.0.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.19
|
||||
- jazz-tools@0.9.19
|
||||
|
||||
## 0.0.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.18
|
||||
- jazz-tools@0.9.18
|
||||
|
||||
## 0.0.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c2ca1fe]
|
||||
- Updated dependencies [1227047]
|
||||
- jazz-tools@0.9.17
|
||||
- jazz-react@0.9.17
|
||||
|
||||
## 0.0.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [24b3b6a]
|
||||
- jazz-tools@0.9.16
|
||||
- jazz-react@0.9.16
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7491711]
|
||||
- jazz-tools@0.9.15
|
||||
- jazz-react@0.9.15
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3df93cc]
|
||||
- jazz-tools@0.9.14
|
||||
- jazz-react@0.9.14
|
||||
|
||||
## 0.0.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.13
|
||||
- jazz-tools@0.9.13
|
||||
|
||||
## 0.0.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.12
|
||||
- jazz-tools@0.9.12
|
||||
|
||||
## 0.0.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-react@0.9.11
|
||||
- jazz-tools@0.9.11
|
||||
|
||||
## 0.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5e83864]
|
||||
- jazz-react@0.9.10
|
||||
- jazz-tools@0.9.10
|
||||
|
||||
## 0.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8eb9247]
|
||||
- jazz-tools@0.9.9
|
||||
- jazz-react@0.9.9
|
||||
|
||||
## 0.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -4,30 +4,55 @@ This is an example of how to use passkey authentication with Jazz.
|
||||
|
||||
Live version: https://passkey-demo.jazz.tools
|
||||
|
||||
## Installing & running the example locally
|
||||
## Getting started
|
||||
|
||||
(This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
|
||||
You can either
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
Start by downloading the [jazz repository](https://github.com/garden-co/jazz):
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
```bash
|
||||
npx degit gardencmp/jazz jazz
|
||||
npx create-jazz-app@latest --example passkey --project-name passkey
|
||||
```
|
||||
|
||||
Go to the passkey example directory:
|
||||
Go to the new project directory.
|
||||
```bash
|
||||
cd jazz/examples/passkey
|
||||
cd passkey
|
||||
```
|
||||
|
||||
Install and build dependencies:
|
||||
Run the dev server.
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Start the dev server:
|
||||
Go to the example directory.
|
||||
```bash
|
||||
cd jazz/examples/passkey/
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "passkey",
|
||||
"private": true,
|
||||
"version": "0.0.27",
|
||||
"version": "0.0.40",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,24 +1,21 @@
|
||||
import { JazzProvider, PasskeyAuthBasicUI, usePasskeyAuth } from "jazz-react";
|
||||
import { JazzProvider, PasskeyAuthBasicUI } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import App from "./App.tsx";
|
||||
import "./index.css";
|
||||
|
||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
const [auth, state] = usePasskeyAuth({
|
||||
appName: "Jazz Minimal Auth Passkey Example",
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<JazzProvider
|
||||
auth={auth}
|
||||
peer="wss://cloud.jazz.tools/?key=minimal-auth-passkey-example@garden.co"
|
||||
>
|
||||
<JazzProvider
|
||||
sync={{
|
||||
peer: "wss://cloud.jazz.tools/?key=minimal-auth-passkey-example@garden.co",
|
||||
when: "signedUp",
|
||||
}}
|
||||
>
|
||||
<PasskeyAuthBasicUI appName="Jazz Minimal Auth Passkey Example">
|
||||
{children}
|
||||
</JazzProvider>
|
||||
<PasskeyAuthBasicUI state={state} />
|
||||
</>
|
||||
</PasskeyAuthBasicUI>
|
||||
</JazzProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
24
examples/passphrase/.gitignore
vendored
Normal file
24
examples/passphrase/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
56
examples/passphrase/README.md
Normal file
56
examples/passphrase/README.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Passphrase authentication example with Jazz and React
|
||||
|
||||
This is an example of how to use passphrase authentication with Jazz.
|
||||
|
||||
## Getting started
|
||||
|
||||
You can either
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
```bash
|
||||
npx create-jazz-app@latest --example passphrase --project-name passphrase
|
||||
```
|
||||
|
||||
Go to the new project directory.
|
||||
```bash
|
||||
cd passphrase
|
||||
```
|
||||
|
||||
Run the dev server.
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Go to the example directory.
|
||||
```bash
|
||||
cd jazz/examples/passphrase/
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
13
examples/passphrase/index.html
Normal file
13
examples/passphrase/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Jazz | Minimal Auth Passphrase Example</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
28
examples/passphrase/package.json
Normal file
28
examples/passphrase/package.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "passphrase",
|
||||
"private": true,
|
||||
"version": "0.0.39",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc -b && vite build",
|
||||
"preview": "vite preview",
|
||||
"format-and-lint": "biome check .",
|
||||
"format-and-lint:fix": "biome check . --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "~5.6.2",
|
||||
"vite": "^5.4.10"
|
||||
}
|
||||
}
|
||||
14
examples/passphrase/src/App.tsx
Normal file
14
examples/passphrase/src/App.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import { useAccount } from "jazz-react";
|
||||
|
||||
function App() {
|
||||
const { logOut } = useAccount();
|
||||
|
||||
return (
|
||||
<main>
|
||||
<h1>You're logged in</h1>
|
||||
<button onClick={() => logOut()}>Logout</button>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
68
examples/passphrase/src/index.css
Normal file
68
examples/passphrase/src/index.css
Normal file
@@ -0,0 +1,68 @@
|
||||
:root {
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
#root {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 0;
|
||||
padding: 0.6em 1.2em;
|
||||
font-weight: 500;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 1rem;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
32
examples/passphrase/src/main.tsx
Normal file
32
examples/passphrase/src/main.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import { JazzProvider, PassphraseAuthBasicUI } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import App from "./App.tsx";
|
||||
import "./index.css";
|
||||
import { wordlist } from "./wordlist.ts";
|
||||
|
||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<JazzProvider
|
||||
sync={{
|
||||
peer: "wss://cloud.jazz.tools/?key=minimal-auth-passphrase-example@garden.co",
|
||||
when: "signedUp",
|
||||
}}
|
||||
>
|
||||
<PassphraseAuthBasicUI
|
||||
appName="Jazz Minimal Auth Passphrase Example"
|
||||
wordlist={wordlist}
|
||||
>
|
||||
{children}
|
||||
</PassphraseAuthBasicUI>
|
||||
</JazzProvider>
|
||||
);
|
||||
}
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
<JazzAndAuth>
|
||||
<App />
|
||||
</JazzAndAuth>
|
||||
</StrictMode>,
|
||||
);
|
||||
1
examples/passphrase/src/vite-env.d.ts
vendored
Normal file
1
examples/passphrase/src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
2050
examples/passphrase/src/wordlist.ts
Normal file
2050
examples/passphrase/src/wordlist.ts
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user