Compare commits

..

3 Commits

Author SHA1 Message Date
Anselm Eickhoff
1baf60d660 Tighter slogan supported by kicker 2025-01-08 17:33:05 +00:00
Anselm
cad1b0ea43 Add connection between CoValues and local-first state 2025-01-08 16:02:42 +00:00
Anselm
473da86cca hermo improvements and start adding git comparison to narrative 2025-01-08 11:37:19 +00:00
383 changed files with 3597 additions and 13844 deletions

View File

@@ -0,0 +1,7 @@
---
"jazz-react-native": patch
---
Fix username key hashing in DemoAuth
Improve error handling when loading an existing account fails
Fix the double context creation in Reacc development mode

View File

@@ -0,0 +1,5 @@
---
"cojson": patch
---
Add the assign method to RawCoMap to create bulk transactions and optimize RawCoMap init

View File

@@ -13,7 +13,7 @@ jobs:
continue-on-error: true continue-on-error: true
strategy: strategy:
matrix: matrix:
project: ["tests/e2e", "examples/chat", "examples/file-share-svelte", "examples/form", "examples/music-player", "examples/pets", "examples/onboarding", "starters/react-demo-auth-tailwind"] project: ["tests/e2e", "examples/chat", "examples/file-share-svelte", "examples/form", "examples/music-player", "examples/pets", "examples/onboarding"]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

View File

@@ -1,98 +1,5 @@
# chat-rn-clerk # chat-rn-clerk
## 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
- Updated dependencies [d1d773b]
- jazz-tools@0.9.8
- jazz-react-native@0.9.8
- jazz-react-native-auth-clerk@0.9.8
- jazz-react-native-media-images@0.9.8
## 1.0.48
### Patch Changes
- Updated dependencies [8a390d2]
- jazz-react-native@0.9.6
- jazz-react-native-auth-clerk@0.9.6
## 1.0.47
### Patch Changes
- Updated dependencies [c871912]
- jazz-react-native@0.9.5
- jazz-react-native-auth-clerk@0.9.5
## 1.0.46
### Patch Changes
- jazz-react-native@0.9.4
- jazz-react-native-auth-clerk@0.9.4
## 1.0.45
### Patch Changes
- Updated dependencies [7cd691f]
- jazz-react-native@0.9.3
- jazz-react-native-auth-clerk@0.9.3
## 1.0.44
### Patch Changes
- Updated dependencies [80fd3e9]
- jazz-react-native@0.9.2
- jazz-react-native-auth-clerk@0.9.2
## 1.0.43
### Patch Changes
- Updated dependencies [1b71969]
- jazz-tools@0.9.1
- jazz-react-native@0.9.1
- jazz-react-native-auth-clerk@0.9.1
- jazz-react-native-media-images@0.9.1
## 1.0.42
### Patch Changes
- Updated dependencies [1da4d55]
- Updated dependencies [8eda792]
- Updated dependencies [1e5e3a1]
- jazz-react-native@0.9.0
- jazz-tools@0.9.0
- jazz-react-native-auth-clerk@0.9.0
- jazz-react-native-media-images@0.9.0
## 1.0.41 ## 1.0.41
### Patch Changes ### Patch Changes

View File

@@ -37,13 +37,7 @@
], ],
"expo-secure-store", "expo-secure-store",
"expo-font", "expo-font",
"expo-router", "expo-router"
[
"expo-image-picker",
{
"photosPermission": "The app accesses your photos to let you share them with your friends."
}
]
], ],
"extra": { "extra": {
"eas": { "eas": {

View File

@@ -1,12 +1,9 @@
import { useAccount, useCoState } from "@/src/jazz";
import { Chat, Message } from "@/src/schema"; import { Chat, Message } from "@/src/schema";
import { useNavigation } from "@react-navigation/native"; import { useFocusEffect, useNavigation } from "@react-navigation/native";
import clsx from "clsx"; import clsx from "clsx";
import * as Clipboard from "expo-clipboard"; import * as Clipboard from "expo-clipboard";
import * as ImagePicker from "expo-image-picker";
import { useLocalSearchParams } from "expo-router"; 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 { Group, ID } from "jazz-tools";
import { useEffect, useLayoutEffect, useState } from "react"; import { useEffect, useLayoutEffect, useState } from "react";
import React, { import React, {
@@ -19,8 +16,6 @@ import React, {
KeyboardAvoidingView, KeyboardAvoidingView,
TextInput, TextInput,
Button, Button,
Image,
ActivityIndicator,
} from "react-native"; } from "react-native";
export default function Conversation() { export default function Conversation() {
@@ -30,7 +25,6 @@ export default function Conversation() {
const [message, setMessage] = useState(""); const [message, setMessage] = useState("");
const loadedChat = useCoState(Chat, chat?.id, [{}]); const loadedChat = useCoState(Chat, chat?.id, [{}]);
const navigation = useNavigation(); const navigation = useNavigation();
const [isUploading, setIsUploading] = useState(false);
useEffect(() => { useEffect(() => {
if (chat) return; if (chat) return;
@@ -87,32 +81,6 @@ 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 renderMessageItem = ({ item }: { item: Message }) => {
const isMe = item._edits.text.by?.isMe; const isMe = item._edits.text.by?.isMe;
return ( return (
@@ -138,27 +106,14 @@ export default function Conversation() {
isMe ? "flex-row" : "flex-row", isMe ? "flex-row" : "flex-row",
)} )}
> >
{item.image && ( <Text
<ProgressiveImg image={item.image} maxWidth={1024}> className={clsx(
{({ src, res, originalSize }) => ( !isMe ? "text-black" : "text-gray-200",
<Image `text-md max-w-[85%]`,
source={{ uri: src }} )}
className="w-48 h-48 rounded-lg mb-2" >
resizeMode="cover" {item.text}
/> </Text>
)}
</ProgressiveImg>
)}
{item.text && (
<Text
className={clsx(
!isMe ? "text-black" : "text-gray-200",
`text-md max-w-[85%]`,
)}
>
{item.text}
</Text>
)}
<Text <Text
className={clsx( className={clsx(
"text-[10px] text-right ml-2", "text-[10px] text-right ml-2",
@@ -192,17 +147,6 @@ export default function Conversation() {
className="p-3 bg-white border-t border-gray-300" className="p-3 bg-white border-t border-gray-300"
> >
<SafeAreaView className="flex-row items-center gap-2"> <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 <TextInput
className="flex-1 rounded-full h-10 px-4 bg-gray-100 border border-gray-300 focus:border-blue-500 focus:bg-white" 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} value={message}

View File

@@ -11,7 +11,7 @@ import React, {
} from "react-native"; } from "react-native";
import { useUser } from "@clerk/clerk-expo"; import { useUser } from "@clerk/clerk-expo";
import { useAccount } from "jazz-react-native"; import { useAccount } from "../../src/jazz";
import { Chat } from "../../src/schema"; import { Chat } from "../../src/schema";
export default function ChatScreen() { export default function ChatScreen() {

View File

@@ -1,7 +1,7 @@
{ {
"name": "chat-rn-clerk", "name": "chat-rn-clerk",
"main": "index.js", "main": "index.js",
"version": "1.0.51", "version": "1.0.41",
"scripts": { "scripts": {
"build": "expo export -p ios", "build": "expo export -p ios",
"start": "expo start", "start": "expo start",
@@ -20,7 +20,6 @@
"@bam.tech/react-native-image-resizer": "^3.0.11", "@bam.tech/react-native-image-resizer": "^3.0.11",
"@clerk/clerk-expo": "^2.2.21", "@clerk/clerk-expo": "^2.2.21",
"@expo/vector-icons": "^14.0.2", "@expo/vector-icons": "^14.0.2",
"@op-engineering/op-sqlite": "^11.2.12",
"@react-native-community/netinfo": "^11.4.1", "@react-native-community/netinfo": "^11.4.1",
"@react-navigation/native": "^7.0.13", "@react-navigation/native": "^7.0.13",
"@react-navigation/native-stack": "^7.1.14", "@react-navigation/native-stack": "^7.1.14",
@@ -35,7 +34,6 @@
"expo-dev-client": "~5.0.5", "expo-dev-client": "~5.0.5",
"expo-file-system": "^18.0.4", "expo-file-system": "^18.0.4",
"expo-font": "~13.0.1", "expo-font": "~13.0.1",
"expo-image-picker": "~16.0.4",
"expo-linking": "~7.0.3", "expo-linking": "~7.0.3",
"expo-router": "~4.0.11", "expo-router": "~4.0.11",
"expo-secure-store": "~14.0.0", "expo-secure-store": "~14.0.0",

View File

@@ -1,5 +1,4 @@
import { useClerk, useUser } from "@clerk/clerk-expo"; import { useClerk, useUser } from "@clerk/clerk-expo";
import { JazzProvider, setupKvStore } from "jazz-react-native";
import { useJazzClerkAuth } from "jazz-react-native-auth-clerk"; import { useJazzClerkAuth } from "jazz-react-native-auth-clerk";
import React, { import React, {
createContext, createContext,
@@ -9,6 +8,8 @@ import React, {
useState, useState,
} from "react"; } from "react";
import { Text, View } from "react-native"; import { Text, View } from "react-native";
import { Jazz, kvStore } from "./jazz";
const AuthContext = createContext<{ const AuthContext = createContext<{
isAuthenticated: boolean; isAuthenticated: boolean;
isLoading: boolean; isLoading: boolean;
@@ -21,8 +22,6 @@ export function useAuth() {
return useContext(AuthContext); return useContext(AuthContext);
} }
const kvStore = setupKvStore();
export function JazzAndAuth({ children }: PropsWithChildren) { export function JazzAndAuth({ children }: PropsWithChildren) {
const { isSignedIn, isLoaded: isClerkLoaded } = useUser(); const { isSignedIn, isLoaded: isClerkLoaded } = useUser();
const clerk = useClerk(); const clerk = useClerk();
@@ -48,13 +47,13 @@ export function JazzAndAuth({ children }: PropsWithChildren) {
</View> </View>
))} ))}
{auth && clerk.user ? ( {auth && clerk.user ? (
<JazzProvider <Jazz.Provider
auth={auth} auth={auth}
storage="sqlite"
peer="wss://cloud.jazz.tools/?key=chat-rn-clerk-example-jazz@garden.co" peer="wss://cloud.jazz.tools/?key=chat-rn-clerk-example-jazz@garden.co"
storage={undefined}
> >
{children} {children}
</JazzProvider> </Jazz.Provider>
) : ( ) : (
children children
)} )}

View File

@@ -0,0 +1,4 @@
import { createJazzRNApp } from "jazz-react-native";
export const Jazz = createJazzRNApp();
export const { useAccount, useCoState, useAcceptInvite, kvStore } = Jazz;

View File

@@ -1,8 +1,7 @@
import { CoList, CoMap, ImageDefinition, co } from "jazz-tools"; import { CoList, CoMap, co } from "jazz-tools";
export class Message extends CoMap { export class Message extends CoMap {
text = co.string; text = co.string;
image = co.optional.ref(ImageDefinition);
} }
export class Chat extends CoList.Of(co.ref(Message)) {} export class Chat extends CoList.Of(co.ref(Message)) {}

View File

@@ -1,82 +1,5 @@
# chat-rn # chat-rn
## 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
- Updated dependencies [d1d773b]
- jazz-tools@0.9.8
- jazz-react-native@0.9.8
## 1.0.45
### Patch Changes
- Updated dependencies [8a390d2]
- jazz-react-native@0.9.6
## 1.0.44
### Patch Changes
- Updated dependencies [c871912]
- jazz-react-native@0.9.5
## 1.0.43
### Patch Changes
- jazz-react-native@0.9.4
## 1.0.42
### Patch Changes
- Updated dependencies [7cd691f]
- jazz-react-native@0.9.3
## 1.0.41
### Patch Changes
- Updated dependencies [80fd3e9]
- jazz-react-native@0.9.2
## 1.0.40
### Patch Changes
- Updated dependencies [1b71969]
- jazz-tools@0.9.1
- jazz-react-native@0.9.1
## 1.0.39
### Patch Changes
- Updated dependencies [1da4d55]
- Updated dependencies [8eda792]
- Updated dependencies [1e5e3a1]
- jazz-react-native@0.9.0
- jazz-tools@0.9.0
## 1.0.38 ## 1.0.38
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "chat-rn", "name": "chat-rn",
"version": "1.0.48", "version": "1.0.38",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"build": "expo export -p ios", "build": "expo export -p ios",
@@ -13,7 +13,6 @@
}, },
"dependencies": { "dependencies": {
"@azure/core-asynciterator-polyfill": "^1.0.2", "@azure/core-asynciterator-polyfill": "^1.0.2",
"@op-engineering/op-sqlite": "^11.2.12",
"@react-native-community/netinfo": "^11.4.1", "@react-native-community/netinfo": "^11.4.1",
"@react-navigation/native": "^7.0.13", "@react-navigation/native": "^7.0.13",
"@react-navigation/native-stack": "^7.1.14", "@react-navigation/native-stack": "^7.1.14",

View File

@@ -9,8 +9,9 @@ import * as Linking from "expo-linking";
import React, { StrictMode, useEffect, useState } from "react"; import React, { StrictMode, useEffect, useState } from "react";
import HandleInviteScreen from "./invite"; import HandleInviteScreen from "./invite";
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react-native"; import { DemoAuthBasicUI, useDemoAuth } from "jazz-react-native";
import ChatScreen from "./chat"; import ChatScreen from "./chat";
import { Jazz } from "./jazz";
const Stack = createNativeStackNavigator(); const Stack = createNativeStackNavigator();
@@ -33,6 +34,7 @@ function App() {
"ChatScreen" | "HandleInviteScreen" "ChatScreen" | "HandleInviteScreen"
>("ChatScreen"); >("ChatScreen");
const navigationRef = useNavigationContainerRef(); const navigationRef = useNavigationContainerRef();
useEffect(() => { useEffect(() => {
Linking.getInitialURL().then((url) => { Linking.getInitialURL().then((url) => {
if (url) { if (url) {
@@ -49,10 +51,10 @@ function App() {
return ( return (
<StrictMode> <StrictMode>
<JazzProvider <Jazz.Provider
auth={auth} auth={auth}
storage="sqlite"
peer="wss://cloud.jazz.tools/?key=chat-rn-example-jazz@garden.co" peer="wss://cloud.jazz.tools/?key=chat-rn-example-jazz@garden.co"
storage={undefined}
> >
<NavigationContainer linking={linking} ref={navigationRef}> <NavigationContainer linking={linking} ref={navigationRef}>
<Stack.Navigator initialRouteName={initialRoute}> <Stack.Navigator initialRouteName={initialRoute}>
@@ -68,7 +70,7 @@ function App() {
/> />
</Stack.Navigator> </Stack.Navigator>
</NavigationContainer> </NavigationContainer>
</JazzProvider> </Jazz.Provider>
{state.state !== "signedIn" ? ( {state.state !== "signedIn" ? (
<DemoAuthBasicUI appName="Jazz Chat" state={state} /> <DemoAuthBasicUI appName="Jazz Chat" state={state} />
) : null} ) : null}

View File

@@ -14,7 +14,7 @@ import React, {
Alert, Alert,
} from "react-native"; } from "react-native";
import { useAccount, useCoState } from "jazz-react-native"; import { useAccount, useCoState } from "./jazz";
import { Chat, Message } from "./schema"; import { Chat, Message } from "./schema";
export default function ChatScreen({ navigation }: { navigation: any }) { export default function ChatScreen({ navigation }: { navigation: any }) {

View File

@@ -1,7 +1,13 @@
import { useAcceptInvite } from "jazz-react-native";
import React, { Text } from "react-native"; import React, { Text } from "react-native";
import { useAcceptInvite } from "./jazz";
import { Chat } from "./schema"; import { Chat } from "./schema";
type ChatScreenParams = {
valueHint?: string;
valueID?: string;
inviteSecret?: string;
};
export default function HandleInviteScreen({ export default function HandleInviteScreen({
navigation, navigation,
}: { }: {

View File

@@ -0,0 +1,4 @@
import { createJazzRNApp } from "jazz-react-native";
export const Jazz = createJazzRNApp();
export const { useAccount, useCoState, useAcceptInvite } = Jazz;

View File

@@ -1,52 +1,5 @@
# chat-vue # chat-vue
## 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
- Updated dependencies [d1d773b]
- jazz-tools@0.9.8
- jazz-browser@0.9.8
- jazz-vue@0.9.8
## 0.0.32
### Patch Changes
- Updated dependencies [1b71969]
- Updated dependencies [5d98189]
- jazz-browser@0.9.1
- jazz-tools@0.9.1
- jazz-vue@0.9.1
## 0.0.31
### Patch Changes
- Updated dependencies [9dd8d95]
- Updated dependencies [8eda792]
- jazz-vue@0.9.0
- jazz-tools@0.9.0
- jazz-browser@0.9.0
## 0.0.30 ## 0.0.30
### Patch Changes ### Patch Changes

View File

@@ -1,59 +1,29 @@
# Chat example with Jazz and Vue # Chat example with Jazz and Vue
## Getting started ## Installing & running the example locally
You can either (This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
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 ```bash
npm create jazz-app@latest --example chat-vue --project-name chat-vue npx degit gardencmp/jazz jazz
```
or
```bash
npx create-jazz-app@latest --example chat-vue --project-name chat-vue
``` ```
Go to the new project directory. Go to the todo-vue example directory:
```bash ```bash
cd chat-vue cd jazz/examples/chat-vue
``` ```
Run the dev server. Install and build dependencies:
```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 ```bash
pnpm i && npx turbo build pnpm i && npx turbo build
``` ```
Go to the example directory. Start the dev server:
```bash
cd jazz/examples/chat-vue/
```
Start the dev server.
```bash ```bash
pnpm dev pnpm dev
``` ```
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
## Questions / problems / feedback ## 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. 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.

View File

@@ -1,6 +1,6 @@
{ {
"name": "chat-vue", "name": "chat-vue",
"version": "0.0.35", "version": "0.0.30",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {

View File

@@ -9,9 +9,9 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useAccount } from "jazz-vue";
import AppContainer from "./components/AppContainer.vue"; import AppContainer from "./components/AppContainer.vue";
import TopBar from "./components/TopBar.vue"; import TopBar from "./components/TopBar.vue";
import { useAccount } from "./main";
const { me, logOut } = useAccount(); const { me, logOut } = useAccount();
</script> </script>

View File

@@ -1,9 +1,13 @@
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-vue"; import { DemoAuthBasicUI, createJazzVueApp, useDemoAuth } from "jazz-vue";
import { createApp, defineComponent, h } from "vue"; import { createApp, defineComponent, h } from "vue";
import App from "./App.vue"; import App from "./App.vue";
import "./index.css"; import "./index.css";
import router from "./router"; import router from "./router";
const Jazz = createJazzVueApp();
export const { useAccount, useCoState } = Jazz;
const { JazzProvider } = Jazz;
const RootComponent = defineComponent({ const RootComponent = defineComponent({
name: "RootComponent", name: "RootComponent",
setup() { setup() {

View File

@@ -26,12 +26,12 @@
<script lang="ts"> <script lang="ts">
import type { ID } from "jazz-tools"; import type { ID } from "jazz-tools";
import { useCoState } from "jazz-vue";
import { type PropType, computed, defineComponent, ref } from "vue"; import { type PropType, computed, defineComponent, ref } from "vue";
import ChatBody from "../components/ChatBody.vue"; import ChatBody from "../components/ChatBody.vue";
import ChatBubble from "../components/ChatBubble.vue"; import ChatBubble from "../components/ChatBubble.vue";
import ChatInput from "../components/ChatInput.vue"; import ChatInput from "../components/ChatInput.vue";
import EmptyChatMessage from "../components/EmptyChatMessage.vue"; import EmptyChatMessage from "../components/EmptyChatMessage.vue";
import { useCoState } from "../main";
import { Chat, Message } from "../schema"; import { Chat, Message } from "../schema";
export default defineComponent({ export default defineComponent({

View File

@@ -4,8 +4,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { Group } from "jazz-tools"; import { Group } from "jazz-tools";
import { useAccount } from "jazz-vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useAccount } from "../main";
import { Chat } from "../schema"; import { Chat } from "../schema";
const router = useRouter(); const router = useRouter();

View File

@@ -1,58 +1,5 @@
# jazz-example-chat # jazz-example-chat
## 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
- Updated dependencies [d1d773b]
- jazz-tools@0.9.8
- jazz-react@0.9.8
- jazz-browser-media-images@0.9.8
## 0.0.128
### Patch Changes
- jazz-react@0.9.4
## 0.0.127
### Patch Changes
- Updated dependencies [1b71969]
- jazz-react@0.9.1
- jazz-tools@0.9.1
- jazz-browser-media-images@0.9.1
## 0.0.126
### Patch Changes
- Updated dependencies [956a4d1]
- Updated dependencies [8eda792]
- jazz-react@0.9.0
- jazz-tools@0.9.0
- jazz-browser-media-images@0.9.0
## 0.0.125 ## 0.0.125
### Patch Changes ### Patch Changes

View File

@@ -2,60 +2,30 @@
Live version: [https://chat.jazz.tools](https://chat.jazz.tools) Live version: [https://chat.jazz.tools](https://chat.jazz.tools)
## Getting started ## Installing & running the example locally
You can either (This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
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 ```bash
npm create jazz-app@latest --example chat --project-name chat npx degit gardencmp/jazz jazz
```
or
```bash
npx create-jazz-app@latest --example chat --project-name chat
``` ```
Go to the new project directory. Go to the chat example directory:
```bash ```bash
cd chat cd jazz/examples/chat
``` ```
Run the dev server. Install and build dependencies:
```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 ```bash
pnpm i && npx turbo build pnpm i && npx turbo build
``` ```
Go to the example directory. Start the dev server:
```bash
cd jazz/examples/chat/
```
Start the dev server.
```bash ```bash
pnpm dev pnpm dev
``` ```
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
## Questions / problems / feedback ## 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. 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.
@@ -64,4 +34,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work. By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx). You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/main.tsx](./src/main.tsx).

View File

@@ -1,7 +1,7 @@
{ {
"name": "jazz-example-chat", "name": "jazz-example-chat",
"private": true, "private": true,
"version": "0.0.131", "version": "0.0.125",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -1,13 +1,9 @@
import { inIframe, onChatLoad } from "@/util.ts"; import { inIframe, onChatLoad } from "@/util.ts";
import { useIframeHashRouter } from "hash-slash"; import { useIframeHashRouter } from "hash-slash";
import { useAccount } from "jazz-react";
import { Group, ID } from "jazz-tools"; import { Group, ID } from "jazz-tools";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { ChatScreen } from "./chatScreen.tsx"; import { ChatScreen } from "./chatScreen.tsx";
import { JazzAndAuth } from "./jazz.tsx"; import { useAccount } from "./main.tsx";
import { Chat } from "./schema.ts"; import { Chat } from "./schema.ts";
import { ThemeProvider } from "./themeProvider.tsx";
import { AppContainer, TopBar } from "./ui.tsx"; import { AppContainer, TopBar } from "./ui.tsx";
export function App() { export function App() {
@@ -16,9 +12,9 @@ export function App() {
const createChat = () => { const createChat = () => {
if (!me) return; if (!me) return;
const group = Group.create(); const group = Group.create({ owner: me });
group.addMember("everyone", "writer"); group.addMember("everyone", "writer");
const chat = Chat.create([], group); const chat = Chat.create([], { owner: group });
router.navigate("/#/chat/" + chat.id); router.navigate("/#/chat/" + chat.id);
// for https://jazz.tools marketing site demo only // for https://jazz.tools marketing site demo only
@@ -38,13 +34,3 @@ export function App() {
</AppContainer> </AppContainer>
); );
} }
createRoot(document.getElementById("root")!).render(
<ThemeProvider>
<StrictMode>
<JazzAndAuth>
<App />
</JazzAndAuth>
</StrictMode>
</ThemeProvider>,
);

View File

@@ -1,7 +1,7 @@
import { createImage } from "jazz-browser-media-images"; import { createImage } from "jazz-browser-media-images";
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { useState } from "react"; import { useState } from "react";
import { useAccount, useCoState } from "./main.tsx";
import { Chat, Message } from "./schema.ts"; import { Chat, Message } from "./schema.ts";
import { import {
BubbleBody, BubbleBody,
@@ -18,6 +18,7 @@ import {
export function ChatScreen(props: { chatID: ID<Chat> }) { export function ChatScreen(props: { chatID: ID<Chat> }) {
const chat = useCoState(Chat, props.chatID, [{}]); const chat = useCoState(Chat, props.chatID, [{}]);
const { me } = useAccount();
const [showNLastMessages, setShowNLastMessages] = useState(30); const [showNLastMessages, setShowNLastMessages] = useState(30);
if (!chat) if (!chat)
@@ -26,6 +27,8 @@ export function ChatScreen(props: { chatID: ID<Chat> }) {
); );
const sendImage = (event: React.ChangeEvent<HTMLInputElement>) => { const sendImage = (event: React.ChangeEvent<HTMLInputElement>) => {
if (!me?.profile) return;
const file = event.currentTarget.files?.[0]; const file = event.currentTarget.files?.[0];
if (!file) return; if (!file) return;
@@ -36,7 +39,12 @@ export function ChatScreen(props: { chatID: ID<Chat> }) {
} }
createImage(file, { owner: chat._owner }).then((image) => { createImage(file, { owner: chat._owner }).then((image) => {
chat.push(Message.create({ text: file.name, image: image }, chat._owner)); chat.push(
Message.create(
{ text: file.name, image: image },
{ owner: chat._owner },
),
);
}); });
}; };

View File

@@ -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} />
)}
</>
);
}

View File

@@ -0,0 +1,36 @@
import { ThemeProvider } from "@/themeProvider.tsx";
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { App } from "./app.tsx";
const Jazz = createJazzReactApp();
export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, state] = useDemoAuth();
return (
<>
<Jazz.Provider
auth={auth}
peer="wss://cloud.jazz.tools/?key=chat-example-jazz@garden.co"
>
{children}
</Jazz.Provider>
{state.state !== "signedIn" && (
<DemoAuthBasicUI appName="Jazz Chat" state={state} />
)}
</>
);
}
createRoot(document.getElementById("root")!).render(
<ThemeProvider>
<StrictMode>
<JazzAndAuth>
<App />
</JazzAndAuth>
</StrictMode>
</ThemeProvider>,
);

View File

@@ -1,58 +1,5 @@
# minimal-auth-clerk # minimal-auth-clerk
## 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
- Updated dependencies [d1d773b]
- jazz-tools@0.9.8
- jazz-react@0.9.8
- jazz-react-auth-clerk@0.9.8
## 0.0.27
### Patch Changes
- jazz-react@0.9.4
- jazz-react-auth-clerk@0.9.4
## 0.0.26
### Patch Changes
- Updated dependencies [1b71969]
- jazz-react@0.9.1
- jazz-tools@0.9.1
- jazz-react-auth-clerk@0.9.1
## 0.0.25
### Patch Changes
- Updated dependencies [956a4d1]
- Updated dependencies [8eda792]
- jazz-react@0.9.0
- jazz-tools@0.9.0
- jazz-react-auth-clerk@0.9.0
## 0.0.24 ## 0.0.24
### Patch Changes ### Patch Changes

View File

@@ -4,60 +4,30 @@ This is an example of how to use clerk authentication with Jazz.
Live version: https://clerk-demo.jazz.tools Live version: https://clerk-demo.jazz.tools
## Getting started ## Installing & running the example locally
You can either (This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
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 ```bash
npm create jazz-app@latest --start clerk --project-name clerk npx degit gardencmp/jazz jazz
```
or
```bash
npx create-jazz-app@latest --start clerk --project-name clerk
``` ```
Go to the new project directory. Go to the clerk example directory:
```bash ```bash
cd clerk cd jazz/examples/clerk
``` ```
Run the dev server. Install and build dependencies:
```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 ```bash
pnpm i && npx turbo build pnpm i && npx turbo build
``` ```
Go to the example directory. Start the dev server:
```bash
cd jazz/examples/clerk/
```
Start the dev server.
```bash ```bash
pnpm dev pnpm dev
``` ```
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
## Questions / problems / feedback ## 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. 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.

View File

@@ -1,7 +1,7 @@
{ {
"name": "clerk", "name": "clerk",
"private": true, "private": true,
"version": "0.0.30", "version": "0.0.24",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
@@ -13,7 +13,7 @@
"dependencies": { "dependencies": {
"@clerk/clerk-react": "^5.4.1", "@clerk/clerk-react": "^5.4.1",
"jazz-react": "workspace:*", "jazz-react": "workspace:*",
"jazz-react-auth-clerk": "workspace:0.9.10", "jazz-react-auth-clerk": "workspace:0.8.51",
"jazz-tools": "workspace:*", "jazz-tools": "workspace:*",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1" "react-dom": "^18.3.1"

View File

@@ -1,4 +1,4 @@
import { useAccount } from "jazz-react"; import { useAccount } from "./main";
function App() { function App() {
const { me, logOut } = useAccount(); const { me, logOut } = useAccount();

View File

@@ -1,10 +1,10 @@
import { ClerkProvider, SignInButton, useClerk } from "@clerk/clerk-react"; import { ClerkProvider, SignInButton, useClerk } from "@clerk/clerk-react";
import { createJazzReactApp } from "jazz-react";
import { useJazzClerkAuth } from "jazz-react-auth-clerk"; import { useJazzClerkAuth } from "jazz-react-auth-clerk";
import { StrictMode } from "react"; import { StrictMode } from "react";
import { createRoot } from "react-dom/client"; import { createRoot } from "react-dom/client";
import App from "./App.tsx"; import App from "./App.tsx";
import "./index.css"; import "./index.css";
import { JazzProvider } from "jazz-react";
// Import your publishable key // Import your publishable key
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY; const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;
@@ -13,6 +13,9 @@ if (!PUBLISHABLE_KEY) {
throw new Error("Add your Clerk publishable key to the .env.local file"); throw new Error("Add your Clerk publishable key to the .env.local file");
} }
const Jazz = createJazzReactApp();
export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) { function JazzAndAuth({ children }: { children: React.ReactNode }) {
const clerk = useClerk(); const clerk = useClerk();
const [auth, state] = useJazzClerkAuth(clerk); const [auth, state] = useJazzClerkAuth(clerk);
@@ -23,12 +26,12 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
<div key={error}>{error}</div> <div key={error}>{error}</div>
))} ))}
{clerk.user && auth ? ( {clerk.user && auth ? (
<JazzProvider <Jazz.Provider
auth={auth} auth={auth}
peer="wss://cloud.jazz.tools/?key=minimal-auth-clerk-example@garden.co" peer="wss://cloud.jazz.tools/?key=minimal-auth-clerk-example@garden.co"
> >
{children} {children}
</JazzProvider> </Jazz.Provider>
) : ( ) : (
<SignInButton /> <SignInButton />
)} )}

View File

@@ -1,46 +1,5 @@
# file-share-svelte # file-share-svelte
## 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
- Updated dependencies [d1d773b]
- jazz-tools@0.9.8
- jazz-svelte@0.9.8
## 0.0.12
### Patch Changes
- Updated dependencies [1b71969]
- jazz-tools@0.9.1
- jazz-svelte@0.9.1
## 0.0.11
### Patch Changes
- Updated dependencies [9dd8d95]
- Updated dependencies [8eda792]
- jazz-svelte@0.9.0
- jazz-tools@0.9.0
## 0.0.10 ## 0.0.10
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "file-share-svelte", "name": "file-share-svelte",
"version": "0.0.15", "version": "0.0.10",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {

View File

@@ -3,7 +3,7 @@
import { SharedFile } from '$lib/schema'; import { SharedFile } from '$lib/schema';
import { FileStream } from 'jazz-tools'; import { FileStream } from 'jazz-tools';
import { File, FileDown, Trash2, Link2 } from 'lucide-svelte'; import { File, FileDown, Trash2, Link2 } from 'lucide-svelte';
import { useAccount } from 'jazz-svelte'; import { useAccount } from '$lib/jazz';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { formatFileSize } from '$lib/utils'; import { formatFileSize } from '$lib/utils';

View File

@@ -0,0 +1,7 @@
import { createJazzApp } from 'jazz-svelte';
import { FileShareAccount } from './schema';
export const { useAccount, useCoState, useAcceptInvite, useAccountOrGuest, Provider } =
createJazzApp({
AccountSchema: FileShareAccount
});

View File

@@ -1,17 +1,8 @@
<script lang="ts" module>
declare module 'jazz-svelte' {
interface Register {
Account: FileShareAccount;
}
}
</script>
<script lang="ts"> <script lang="ts">
import { JazzProvider } from 'jazz-svelte'; import { Provider } from '$lib/jazz';
import { PasskeyAuthBasicUI, usePasskeyAuth } from 'jazz-svelte'; import { PasskeyAuthBasicUI, usePasskeyAuth } from 'jazz-svelte';
import { Toaster } from 'svelte-sonner'; import { Toaster } from 'svelte-sonner';
import '../app.css'; import '../app.css';
import { FileShareAccount } from '$lib/schema';
let { children } = $props(); let { children } = $props();
const auth = usePasskeyAuth({ const auth = usePasskeyAuth({
@@ -33,13 +24,9 @@
</div> </div>
{/if} {/if}
{#if auth.current} {#if auth.current}
<JazzProvider <Provider auth={auth.current} peer="wss://cloud.jazz.tools/?key=file-share-svelte@garden.co">
AccountSchema={FileShareAccount}
auth={auth.current}
peer="wss://cloud.jazz.tools/?key=file-share-svelte@garden.co"
>
<div class="min-h-screen bg-gray-100"> <div class="min-h-screen bg-gray-100">
{@render children()} {@render children()}
</div> </div>
</JazzProvider> </Provider>
{/if} {/if}

View File

@@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { useAccount, useCoState } from 'jazz-svelte'; import { useAccount, useCoState } from '$lib/jazz';
import { SharedFile, ListOfSharedFiles } from '$lib/schema'; import { SharedFile, ListOfSharedFiles } from '$lib/schema';
import { createInviteLink } from 'jazz-svelte'; import { createInviteLink } from 'jazz-svelte';
import { FileStream } from 'jazz-tools'; import { FileStream } from 'jazz-tools';

View File

@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { page } from '$app/stores'; import { page } from '$app/stores';
import { useAccount, useCoState } from 'jazz-svelte'; import { useAccount, useCoState } from '$lib/jazz';
import { SharedFile } from '$lib/schema'; import { SharedFile } from '$lib/schema';
import { File, FileDown, Link2 } from 'lucide-svelte'; import { File, FileDown, Link2 } from 'lucide-svelte';
import type { ID } from 'jazz-tools'; import type { ID } from 'jazz-tools';

View File

@@ -1,57 +1,5 @@
# form # form
## 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
- Updated dependencies [d1d773b]
- jazz-tools@0.9.8
- jazz-react@0.9.8
- jazz-browser-media-images@0.9.8
## 0.0.23
### Patch Changes
- jazz-react@0.9.4
## 0.0.22
### Patch Changes
- Updated dependencies [1b71969]
- jazz-react@0.9.1
- jazz-tools@0.9.1
- jazz-browser-media-images@0.9.1
## 0.0.21
### Patch Changes
- Updated dependencies [956a4d1]
- Updated dependencies [8eda792]
- jazz-react@0.9.0
- jazz-tools@0.9.0
- jazz-browser-media-images@0.9.0
## 0.0.20 ## 0.0.20
### Patch Changes ### Patch Changes

View File

@@ -17,60 +17,30 @@ converting it into a `BubbleTeaOrder`.
[See the full guide here.](https://jazz.tools/docs/react/design-patterns/form) [See the full guide here.](https://jazz.tools/docs/react/design-patterns/form)
## Getting started ## Installing & running the example locally
You can either (This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
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 ```bash
npm create jazz-app@latest --start form --project-name form npx degit gardencmp/jazz jazz
```
or
```bash
npx create-jazz-app@latest --start form --project-name form
``` ```
Go to the new project directory. Go to the form example directory:
```bash ```bash
cd form cd jazz/examples/form
``` ```
Run the dev server. Install and build dependencies:
```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 ```bash
pnpm i && npx turbo build pnpm i && npx turbo build
``` ```
Go to the example directory. Start the dev server:
```bash
cd jazz/examples/form/
```
Start the dev server.
```bash ```bash
pnpm dev pnpm dev
``` ```
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
## Questions / problems / feedback ## 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. 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.
@@ -79,4 +49,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work. By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx). You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/main.tsx](./src/main.tsx).

View File

@@ -1,7 +1,7 @@
{ {
"name": "form", "name": "form",
"private": true, "private": true,
"version": "0.0.26", "version": "0.0.20",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -1,9 +1,9 @@
import { useIframeHashRouter } from "hash-slash"; import { useIframeHashRouter } from "hash-slash";
import { useAccount } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { CreateOrder } from "./CreateOrder.tsx"; import { CreateOrder } from "./CreateOrder.tsx";
import { EditOrder } from "./EditOrder.tsx"; import { EditOrder } from "./EditOrder.tsx";
import { Orders } from "./Orders.tsx"; import { Orders } from "./Orders.tsx";
import { useAccount } from "./main";
import { BubbleTeaOrder } from "./schema.ts"; import { BubbleTeaOrder } from "./schema.ts";
function App() { function App() {

View File

@@ -1,10 +1,10 @@
import { useIframeHashRouter } from "hash-slash"; import { useIframeHashRouter } from "hash-slash";
import { useAccount, useCoState } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { useState } from "react"; import { useState } from "react";
import { Errors } from "./Errors.tsx"; import { Errors } from "./Errors.tsx";
import { LinkToHome } from "./LinkToHome.tsx"; import { LinkToHome } from "./LinkToHome.tsx";
import { OrderForm } from "./OrderForm.tsx"; import { OrderForm } from "./OrderForm.tsx";
import { useAccount, useCoState } from "./main.tsx";
import { import {
BubbleTeaOrder, BubbleTeaOrder,
DraftBubbleTeaOrder, DraftBubbleTeaOrder,
@@ -30,9 +30,12 @@ export function CreateOrder() {
me.root.orders.push(draft as BubbleTeaOrder); me.root.orders.push(draft as BubbleTeaOrder);
// reset the draft // reset the draft
me.root.draft = DraftBubbleTeaOrder.create({ me.root.draft = DraftBubbleTeaOrder.create(
addOns: ListOfBubbleTeaAddOns.create([]), {
}); addOns: ListOfBubbleTeaAddOns.create([], me),
},
me,
);
router.navigate("/"); router.navigate("/");
}; };

View File

@@ -1,4 +1,4 @@
import { useAccount } from "jazz-react"; import { useAccount } from "./main.tsx";
export function DraftIndicator() { export function DraftIndicator() {
const { me } = useAccount({ const { me } = useAccount({

View File

@@ -1,8 +1,8 @@
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { LinkToHome } from "./LinkToHome.tsx"; import { LinkToHome } from "./LinkToHome.tsx";
import { OrderForm } from "./OrderForm.tsx"; import { OrderForm } from "./OrderForm.tsx";
import { OrderThumbnail } from "./OrderThumbnail.tsx"; import { OrderThumbnail } from "./OrderThumbnail.tsx";
import { useCoState } from "./main.tsx";
import { BubbleTeaOrder } from "./schema.ts"; import { BubbleTeaOrder } from "./schema.ts";
export function EditOrder(props: { id: ID<BubbleTeaOrder> }) { export function EditOrder(props: { id: ID<BubbleTeaOrder> }) {

View File

@@ -1,6 +1,6 @@
import { useAccount } from "jazz-react";
import { DraftIndicator } from "./DraftIndicator.tsx"; import { DraftIndicator } from "./DraftIndicator.tsx";
import { OrderThumbnail } from "./OrderThumbnail.tsx"; import { OrderThumbnail } from "./OrderThumbnail.tsx";
import { useAccount } from "./main.tsx";
export function Orders() { export function Orders() {
const { me } = useAccount({ const { me } = useAccount({

View File

@@ -1,22 +1,27 @@
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react"; import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { StrictMode } from "react"; import { StrictMode } from "react";
import { createRoot } from "react-dom/client"; import { createRoot } from "react-dom/client";
import App from "./App.tsx"; import App from "./App.tsx";
import "./index.css"; import "./index.css";
import { JazzAccount } from "./schema.ts"; import { JazzAccount } from "./schema.ts";
const Jazz = createJazzReactApp({
AccountSchema: JazzAccount,
});
export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) { function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, authState] = useDemoAuth(); const [auth, authState] = useDemoAuth();
return ( return (
<> <>
<JazzProvider <Jazz.Provider
auth={auth} auth={auth}
peer="wss://cloud.jazz.tools/?key=form-example@garden.co" peer="wss://cloud.jazz.tools/?key=form-example@garden.co"
AccountSchema={JazzAccount}
> >
{children} {children}
</JazzProvider> </Jazz.Provider>
{authState.state !== "signedIn" && ( {authState.state !== "signedIn" && (
<DemoAuthBasicUI appName="Form" state={authState} /> <DemoAuthBasicUI appName="Form" state={authState} />
@@ -25,12 +30,6 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
); );
} }
declare module "jazz-react" {
interface Register {
Account: JazzAccount;
}
}
createRoot(document.getElementById("root")!).render( createRoot(document.getElementById("root")!).render(
<StrictMode> <StrictMode>
<JazzAndAuth> <JazzAndAuth>

View File

@@ -1,57 +1,5 @@
# image-upload # image-upload
## 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
- Updated dependencies [d1d773b]
- jazz-tools@0.9.8
- jazz-react@0.9.8
- jazz-browser-media-images@0.9.8
## 0.0.25
### Patch Changes
- jazz-react@0.9.4
## 0.0.24
### Patch Changes
- Updated dependencies [1b71969]
- jazz-react@0.9.1
- jazz-tools@0.9.1
- jazz-browser-media-images@0.9.1
## 0.0.23
### Patch Changes
- Updated dependencies [956a4d1]
- Updated dependencies [8eda792]
- jazz-react@0.9.0
- jazz-tools@0.9.0
- jazz-browser-media-images@0.9.0
## 0.0.22 ## 0.0.22
### Patch Changes ### Patch Changes

View File

@@ -4,60 +4,30 @@ This is an example of how to upload and render images with Jazz.
Live version: https://image-upload-demo.jazz.tools Live version: https://image-upload-demo.jazz.tools
## Getting started ## Installing & running the example locally
You can either (This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
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 ```bash
npm create jazz-app@latest --example image-upload --project-name image-upload npx degit gardencmp/jazz jazz
```
or
```bash
npx create-jazz-app@latest --example image-upload --project-name image-upload
``` ```
Go to the new project directory. Go to the image-upload example directory:
```bash ```bash
cd image-upload cd jazz/examples/image-upload
``` ```
Run the dev server. Install and build dependencies:
```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 ```bash
pnpm i && npx turbo build pnpm i && npx turbo build
``` ```
Go to the example directory. Start the dev server:
```bash
cd jazz/examples/image-upload/
```
Start the dev server.
```bash ```bash
pnpm dev pnpm dev
``` ```
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
## Questions / problems / feedback ## 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. 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.

View File

@@ -1,7 +1,7 @@
{ {
"name": "image-upload", "name": "image-upload",
"private": true, "private": true,
"version": "0.0.28", "version": "0.0.22",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -1,5 +1,5 @@
import { useAccount } from "jazz-react";
import ImageUpload from "./ImageUpload.tsx"; import ImageUpload from "./ImageUpload.tsx";
import { useAccount } from "./main";
function App() { function App() {
const { me, logOut } = useAccount(); const { me, logOut } = useAccount();

View File

@@ -1,7 +1,8 @@
import { createImage } from "jazz-browser-media-images"; import { createImage } from "jazz-browser-media-images";
import { ProgressiveImg, useAccount } from "jazz-react"; import { ProgressiveImg } from "jazz-react";
import { ImageDefinition } from "jazz-tools"; import { ImageDefinition } from "jazz-tools";
import { ChangeEvent, useRef } from "react"; import { ChangeEvent, useRef } from "react";
import { useAccount } from "./main.tsx";
function Image({ image }: { image: ImageDefinition }) { function Image({ image }: { image: ImageDefinition }) {
return ( return (

View File

@@ -1,22 +1,27 @@
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react"; import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { StrictMode } from "react"; import { StrictMode } from "react";
import { createRoot } from "react-dom/client"; import { createRoot } from "react-dom/client";
import App from "./App.tsx"; import App from "./App.tsx";
import "./index.css"; import "./index.css";
import { JazzAccount } from "./schema.ts"; import { JazzAccount } from "./schema.ts";
const Jazz = createJazzReactApp({
AccountSchema: JazzAccount,
});
export const { useAccount, useCoState } = Jazz;
function JazzAndAuth({ children }: { children: React.ReactNode }) { function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, authState] = useDemoAuth(); const [auth, authState] = useDemoAuth();
return ( return (
<> <>
<JazzProvider <Jazz.Provider
auth={auth} auth={auth}
peer="wss://cloud.jazz.tools/?key=image-upload-example@garden.co" peer="wss://cloud.jazz.tools/?key=image-upload-example@garden.co"
AccountSchema={JazzAccount}
> >
{children} {children}
</JazzProvider> </Jazz.Provider>
{authState.state !== "signedIn" && ( {authState.state !== "signedIn" && (
<DemoAuthBasicUI appName="Image upload" state={authState} /> <DemoAuthBasicUI appName="Image upload" state={authState} />
@@ -25,12 +30,6 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
); );
} }
declare module "jazz-react" {
interface Register {
Account: JazzAccount;
}
}
createRoot(document.getElementById("root")!).render( createRoot(document.getElementById("root")!).render(
<StrictMode> <StrictMode>
<JazzAndAuth> <JazzAndAuth>

View File

@@ -1,30 +1,5 @@
# jazz-example-inspector # jazz-example-inspector
## 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
- Updated dependencies [8eda792]
- Updated dependencies [1ef3226]
- cojson@0.9.0
- cojson-transport-ws@0.9.0
## 0.0.92 ## 0.0.92
### Patch Changes ### Patch Changes

View File

@@ -1,7 +1,7 @@
{ {
"name": "jazz-inspector", "name": "jazz-inspector",
"private": true, "private": true,
"version": "0.0.95", "version": "0.0.92",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
@@ -16,8 +16,8 @@
"@radix-ui/react-toast": "^1.1.4", "@radix-ui/react-toast": "^1.1.4",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.0.0", "clsx": "^2.0.0",
"cojson": "workspace:0.9.10", "cojson": "workspace:0.8.50",
"cojson-transport-ws": "workspace:0.9.10", "cojson-transport-ws": "workspace:0.8.50",
"hash-slash": "workspace:0.2.1", "hash-slash": "workspace:0.2.1",
"lucide-react": "^0.274.0", "lucide-react": "^0.274.0",
"qrcode": "^1.5.3", "qrcode": "^1.5.3",

View File

@@ -1,52 +1,5 @@
# jazz-example-musicplayer # jazz-example-musicplayer
## 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
- Updated dependencies [d1d773b]
- jazz-tools@0.9.8
- jazz-react@0.9.8
## 0.0.48
### Patch Changes
- jazz-react@0.9.4
## 0.0.47
### Patch Changes
- Updated dependencies [1b71969]
- jazz-react@0.9.1
- jazz-tools@0.9.1
## 0.0.46
### Patch Changes
- Updated dependencies [956a4d1]
- Updated dependencies [8eda792]
- jazz-react@0.9.0
- jazz-tools@0.9.0
## 0.0.45 ## 0.0.45
### Patch Changes ### Patch Changes

View File

@@ -2,60 +2,30 @@
Live version: https://music-demo.jazz.tools Live version: https://music-demo.jazz.tools
## Getting started ## Installing & running the example locally
You can either (This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
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 ```bash
npm create jazz-app@latest --example music-player --project-name music-player npx degit gardencmp/jazz jazz
```
or
```bash
npx create-jazz-app@latest --example music-player --project-name music-player
``` ```
Go to the new project directory. Go to the music-player example directory:
```bash ```bash
cd music-player cd jazz/examples/music-player
``` ```
Run the dev server. Install and build dependencies:
```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 ```bash
pnpm i && npx turbo build pnpm i && npx turbo build
``` ```
Go to the example directory. Start the dev server:
```bash
cd jazz/examples/music-player/
```
Start the dev server.
```bash ```bash
pnpm dev pnpm dev
``` ```
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
## Questions / problems / feedback ## 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. 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.
@@ -64,4 +34,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work. By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx cojson-simple-sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/2_main.tsx](./src/2_main.tsx). You can also run a local sync server by running `npx cojson-simple-sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/2_main.tsx](./src/2_main.tsx).

View File

@@ -1,7 +1,7 @@
{ {
"name": "jazz-example-music-player", "name": "jazz-example-music-player",
"private": true, "private": true,
"version": "0.0.51", "version": "0.0.45",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
@@ -18,8 +18,8 @@
"@radix-ui/react-toast": "^1.1.4", "@radix-ui/react-toast": "^1.1.4",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.0.0", "clsx": "^2.0.0",
"jazz-react": "workspace:0.9.10", "jazz-react": "workspace:0.8.51",
"jazz-tools": "workspace:0.9.10", "jazz-tools": "workspace:0.8.51",
"lucide-react": "^0.274.0", "lucide-react": "^0.274.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",

View File

@@ -10,20 +10,26 @@ import { PlayerControls } from "./components/PlayerControls";
import "./index.css"; import "./index.css";
import { MusicaAccount } from "@/1_schema"; import { MusicaAccount } from "@/1_schema";
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react"; import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { useUploadExampleData } from "./lib/useUploadExampleData"; import { useUploadExampleData } from "./lib/useUploadExampleData";
/** /**
* Walkthrough: The top-level provider `<JazzProvider/>` * Walkthrough: The top-level provider `<Jazz.Provider/>`
* *
* This shows how to use the top-level provider `<JazzProvider/>`, * This shows how to use the top-level provider `<Jazz.Provider/>`,
* which provides the rest of the app with a controlled account (used through `useAccount` later). * which provides the rest of the app with a controlled account (used through `useAccount` later).
* Here we use `DemoAuth` which is great for prototyping you app without wasting time on figuring out * Here we use `DemoAuth` which is great for prototyping you app without wasting time on figuring out
* the best way to do auth. * the best way to do auth.
* *
* `<JazzProvider/>` also runs our account migration * `<Jazz.Provider/>` also runs our account migration
*/ */
const Jazz = createJazzReactApp({
AccountSchema: MusicaAccount,
});
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
function Main() { function Main() {
const mediaPlayer = useMediaPlayer(); const mediaPlayer = useMediaPlayer();
@@ -64,25 +70,18 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
return ( return (
<> <>
<JazzProvider <Jazz.Provider
storage="indexedDB" storage={["singleTabOPFS", "indexedDB"]}
auth={auth} auth={auth}
peer={peer} peer={peer}
AccountSchema={MusicaAccount}
> >
{children} {children}
</JazzProvider> </Jazz.Provider>
<DemoAuthBasicUI appName="Jazz Music Player" state={state} /> <DemoAuthBasicUI appName="Jazz Music Player" state={state} />
</> </>
); );
} }
declare module "jazz-react" {
interface Register {
Account: MusicaAccount;
}
}
ReactDOM.createRoot(document.getElementById("root")!).render( ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode> <React.StrictMode>
<JazzAndAuth> <JazzAndAuth>

View File

@@ -1,8 +1,9 @@
import { useToast } from "@/hooks/use-toast"; import { useToast } from "@/hooks/use-toast";
import { createInviteLink, useAccount, useCoState } from "jazz-react"; import { createInviteLink } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { useNavigate, useParams } from "react-router"; import { useNavigate, useParams } from "react-router";
import { Playlist } from "./1_schema"; import { Playlist } from "./1_schema";
import { useAccount, useCoState } from "./2_main";
import { createNewPlaylist, uploadMusicTracks } from "./4_actions"; import { createNewPlaylist, uploadMusicTracks } from "./4_actions";
import { MediaPlayer } from "./5_useMediaPlayer"; import { MediaPlayer } from "./5_useMediaPlayer";
import { FileUploadButton } from "./components/FileUploadButton"; import { FileUploadButton } from "./components/FileUploadButton";
@@ -31,15 +32,19 @@ export function HomePage({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
const { toast } = useToast(); const { toast } = useToast();
async function handleFileLoad(files: FileList) { async function handleFileLoad(files: FileList) {
if (!me) return;
/** /**
* Follow this function definition to see how we update * Follow this function definition to see how we update
* values in Jazz and manage files! * values in Jazz and manage files!
*/ */
await uploadMusicTracks(files); await uploadMusicTracks(me, files);
} }
async function handleCreatePlaylist() { async function handleCreatePlaylist() {
const playlist = await createNewPlaylist(); if (!me) return;
const playlist = await createNewPlaylist(me);
navigate(`/playlist/${playlist.id}`); navigate(`/playlist/${playlist.id}`);
} }

View File

@@ -22,22 +22,14 @@ import {
* pattern that best fits your app. * pattern that best fits your app.
*/ */
export async function uploadMusicTracks(files: Iterable<File>) { export async function uploadMusicTracks(
const me = await MusicaAccount.getMe().ensureLoaded({ account: MusicaAccount,
root: { files: Iterable<File>,
rootPlaylist: { ) {
tracks: [],
},
playlists: [],
},
});
if (!me) return;
for (const file of files) { for (const file of files) {
// The ownership object defines the user that owns the created coValues // The ownership object defines the user that owns the created coValues
// We are creating a group for each CoValue in order to be able to share them via Playlist // We are creating a group for each CoValue in order to be able to share them via Playlist
const group = Group.create(); const group = Group.create(account);
const data = await getAudioFileData(file); const data = await getAudioFileData(file);
@@ -58,23 +50,15 @@ export async function uploadMusicTracks(files: Iterable<File>) {
// The newly created musicTrack can be associated to the // The newly created musicTrack can be associated to the
// user track list using a simple push call // user track list using a simple push call
me.root.rootPlaylist.tracks.push(musicTrack); account.root?.rootPlaylist?.tracks?.push(musicTrack);
} }
} }
export async function createNewPlaylist() { export async function createNewPlaylist(account: MusicaAccount) {
const me = await MusicaAccount.getMe().ensureLoaded({
root: {
playlists: [],
},
});
if (!me) throw new Error("Current playlist not resolved");
// Since playlists are meant to be shared we associate them // Since playlists are meant to be shared we associate them
// to a group which will contain the keys required to get // to a group which will contain the keys required to get
// access to the "owned" values // access to the "owned" values
const playlistGroup = Group.create(); const playlistGroup = Group.create(account);
const playlist = Playlist.create( const playlist = Playlist.create(
{ {
@@ -86,7 +70,7 @@ export async function createNewPlaylist() {
// Again, we associate the new playlist to the // Again, we associate the new playlist to the
// user by pushing it into the playlists CoList // user by pushing it into the playlists CoList
me.root.playlists.push(playlist); account.root?.playlists?.push(playlist);
return playlist; return playlist;
} }
@@ -94,7 +78,10 @@ export async function createNewPlaylist() {
export async function addTrackToPlaylist( export async function addTrackToPlaylist(
playlist: Playlist, playlist: Playlist,
track: MusicTrack, track: MusicTrack,
account: MusicaAccount | undefined,
) { ) {
if (!account) return;
const alreadyAdded = playlist.tracks?.some( const alreadyAdded = playlist.tracks?.some(
(t) => t?.id === track.id || t?._refs.sourceTrack?.id === track.id, (t) => t?.id === track.id || t?._refs.sourceTrack?.id === track.id,
); );
@@ -121,8 +108,12 @@ export async function addTrackToPlaylist(
* *
* Doing this for backwards compatibility for when the Group inheritance wasn't possible * Doing this for backwards compatibility for when the Group inheritance wasn't possible
*/ */
const blob = await FileStream.loadAsBlob(track._refs.file.id); const blob = await FileStream.loadAsBlob(track._refs.file.id, account);
const waveform = await MusicTrackWaveform.load(track._refs.waveform.id, {}); const waveform = await MusicTrackWaveform.load(
track._refs.waveform.id,
account,
{},
);
if (!blob || !waveform) return; if (!blob || !waveform) return;
@@ -151,25 +142,13 @@ export async function updateMusicTrackTitle(track: MusicTrack, title: string) {
track.title = title; track.title = title;
} }
export async function updateActivePlaylist(playlist?: Playlist) { export async function updateActivePlaylist(
const me = await MusicaAccount.getMe().ensureLoaded({ playlist: Playlist,
root: { me: MusicaAccount,
activePlaylist: {}, ) {
rootPlaylist: {}, me.root!.activePlaylist = playlist ?? me.root!.rootPlaylist;
},
});
if (!me) return;
me.root.activePlaylist = playlist ?? me.root.rootPlaylist;
} }
export async function updateActiveTrack(track: MusicTrack) { export async function updateActiveTrack(track: MusicTrack, me: MusicaAccount) {
const me = await MusicaAccount.getMe().ensureLoaded({ me.root!.activeTrack = track;
root: {},
});
if (!me) return;
me.root.activeTrack = track;
} }

View File

@@ -1,33 +1,33 @@
import { MusicTrack, Playlist } from "@/1_schema"; import { MusicTrack, Playlist } from "@/1_schema";
import { usePlayMedia } from "@/lib/audio/usePlayMedia"; import { usePlayMedia } from "@/lib/audio/usePlayMedia";
import { usePlayState } from "@/lib/audio/usePlayState"; import { usePlayState } from "@/lib/audio/usePlayState";
import { useAccount } from "jazz-react";
import { FileStream, ID } from "jazz-tools"; import { FileStream, ID } from "jazz-tools";
import { useRef, useState } from "react"; import { useRef, useState } from "react";
import { useAccount } from "./2_main";
import { updateActivePlaylist, updateActiveTrack } from "./4_actions"; import { updateActivePlaylist, updateActiveTrack } from "./4_actions";
import { getNextTrack, getPrevTrack } from "./lib/getters"; import { getNextTrack, getPrevTrack } from "./lib/getters";
export function useMediaPlayer() { export function useMediaPlayer() {
const { me } = useAccount({ const { me } = useAccount();
root: {},
});
const playState = usePlayState(); const playState = usePlayState();
const playMedia = usePlayMedia(); const playMedia = usePlayMedia();
const [loading, setLoading] = useState<ID<MusicTrack> | null>(null); const [loading, setLoading] = useState<ID<MusicTrack> | null>(null);
const activeTrackId = me?.root._refs.activeTrack?.id; const activeTrackId = me?.root?._refs.activeTrack?.id;
// Reference used to avoid out-of-order track loads // Reference used to avoid out-of-order track loads
const lastLoadedTrackId = useRef<ID<MusicTrack> | null>(null); const lastLoadedTrackId = useRef<ID<MusicTrack> | null>(null);
async function loadTrack(track: MusicTrack) { async function loadTrack(track: MusicTrack) {
if (!me.root) return;
lastLoadedTrackId.current = track.id; lastLoadedTrackId.current = track.id;
setLoading(track.id); setLoading(track.id);
const file = await FileStream.loadAsBlob(track._refs.file.id); const file = await FileStream.loadAsBlob(track._refs.file.id, me);
if (!file) { if (!file) {
setLoading(null); setLoading(null);
@@ -40,7 +40,7 @@ export function useMediaPlayer() {
return; return;
} }
updateActiveTrack(track); updateActiveTrack(track, me);
await playMedia(file); await playMedia(file);
@@ -48,16 +48,20 @@ export function useMediaPlayer() {
} }
async function playNextTrack() { async function playNextTrack() {
const track = await getNextTrack(); if (!me?.root) return;
const track = await getNextTrack(me);
if (track) { if (track) {
updateActiveTrack(track); updateActiveTrack(track, me);
await loadTrack(track); await loadTrack(track);
} }
} }
async function playPrevTrack() { async function playPrevTrack() {
const track = await getPrevTrack(); if (!me?.root) return;
const track = await getPrevTrack(me);
if (track) { if (track) {
await loadTrack(track); await loadTrack(track);
@@ -65,12 +69,14 @@ export function useMediaPlayer() {
} }
async function setActiveTrack(track: MusicTrack, playlist?: Playlist) { async function setActiveTrack(track: MusicTrack, playlist?: Playlist) {
if (!me?.root) return;
if (activeTrackId === track.id && lastLoadedTrackId.current !== null) { if (activeTrackId === track.id && lastLoadedTrackId.current !== null) {
playState.toggle(); playState.toggle();
return; return;
} }
updateActivePlaylist(playlist); updateActivePlaylist(playlist!, me);
await loadTrack(track); await loadTrack(track);

View File

@@ -1,26 +1,26 @@
import { useAcceptInvite } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { useCallback } from "react"; import { useCallback } from "react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { MusicaAccount, Playlist } from "./1_schema"; import { Playlist } from "./1_schema";
import { useAcceptInvite, useAccount } from "./2_main";
export function InvitePage() { export function InvitePage() {
const navigate = useNavigate(); const navigate = useNavigate();
const { me } = useAccount({
root: {
playlists: [],
},
});
useAcceptInvite({ useAcceptInvite({
invitedObjectSchema: Playlist, invitedObjectSchema: Playlist,
onAccept: useCallback( onAccept: useCallback(
async (playlistId: ID<Playlist>) => { async (playlistId: ID<Playlist>) => {
const playlist = await Playlist.load(playlistId, {});
const me = await MusicaAccount.getMe().ensureLoaded({
root: {
playlists: [],
},
});
if (!me) return; if (!me) return;
const playlist = await Playlist.load(playlistId, me, {});
if ( if (
playlist && playlist &&
!me.root.playlists.some((item) => playlist.id === item?.id) !me.root.playlists.some((item) => playlist.id === item?.id)
@@ -30,7 +30,7 @@ export function InvitePage() {
navigate("/playlist/" + playlistId); navigate("/playlist/" + playlistId);
}, },
[navigate], [navigate, me],
), ),
}); });

View File

@@ -1,4 +1,4 @@
import { useAccount } from "jazz-react"; import { useAccount } from "@/2_main";
import { Button } from "./ui/button"; import { Button } from "./ui/button";
export function LogoutButton() { export function LogoutButton() {

View File

@@ -1,4 +1,5 @@
import { MusicTrack, Playlist } from "@/1_schema"; import { MusicTrack, Playlist } from "@/1_schema";
import { useAccount, useCoState } from "@/2_main";
import { addTrackToPlaylist } from "@/4_actions"; import { addTrackToPlaylist } from "@/4_actions";
import { import {
DropdownMenu, DropdownMenu,
@@ -7,7 +8,6 @@ import {
DropdownMenuTrigger, DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"; } from "@/components/ui/dropdown-menu";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { useAccount, useCoState } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { MoreHorizontal } from "lucide-react"; import { MoreHorizontal } from "lucide-react";
import { MusicTrackTitleInput } from "./MusicTrackTitleInput"; import { MusicTrackTitleInput } from "./MusicTrackTitleInput";
@@ -43,7 +43,7 @@ export function MusicTrackRow({
function handleAddToPlaylist(playlist: Playlist) { function handleAddToPlaylist(playlist: Playlist) {
if (!track) return; if (!track) return;
addTrackToPlaylist(playlist, track); addTrackToPlaylist(playlist, track, me);
} }
return ( return (

View File

@@ -1,6 +1,6 @@
import { MusicTrack } from "@/1_schema"; import { MusicTrack } from "@/1_schema";
import { useCoState } from "@/2_main";
import { updateMusicTrackTitle } from "@/4_actions"; import { updateMusicTrackTitle } from "@/4_actions";
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { ChangeEvent, useState } from "react"; import { ChangeEvent, useState } from "react";

View File

@@ -1,9 +1,9 @@
import { MusicTrack } from "@/1_schema"; import { MusicTrack } from "@/1_schema";
import { useAccount, useCoState } from "@/2_main";
import { MediaPlayer } from "@/5_useMediaPlayer"; import { MediaPlayer } from "@/5_useMediaPlayer";
import { useMediaEndListener } from "@/lib/audio/useMediaEndListener"; import { useMediaEndListener } from "@/lib/audio/useMediaEndListener";
import { usePlayState } from "@/lib/audio/usePlayState"; import { usePlayState } from "@/lib/audio/usePlayState";
import { useKeyboardListener } from "@/lib/useKeyboardListener"; import { useKeyboardListener } from "@/lib/useKeyboardListener";
import { useAccount, useCoState } from "jazz-react";
import { Pause, Play, SkipBack, SkipForward } from "lucide-react"; import { Pause, Play, SkipBack, SkipForward } from "lucide-react";
import { Waveform } from "./Waveform"; import { Waveform } from "./Waveform";

View File

@@ -1,6 +1,6 @@
import { Playlist } from "@/1_schema"; import { Playlist } from "@/1_schema";
import { useCoState } from "@/2_main";
import { updatePlaylistTitle } from "@/4_actions"; import { updatePlaylistTitle } from "@/4_actions";
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { ChangeEvent, useState } from "react"; import { ChangeEvent, useState } from "react";

View File

@@ -1,4 +1,4 @@
import { useAccount } from "jazz-react"; import { useAccount } from "@/2_main";
import { useNavigate, useParams } from "react-router"; import { useNavigate, useParams } from "react-router";
export function SidePanel() { export function SidePanel() {

View File

@@ -1,7 +1,7 @@
import { MusicTrack, MusicTrackWaveform } from "@/1_schema"; import { MusicTrack, MusicTrackWaveform } from "@/1_schema";
import { useCoState } from "@/2_main";
import { usePlayerCurrentTime } from "@/lib/audio/usePlayerCurrentTime"; import { usePlayerCurrentTime } from "@/lib/audio/usePlayerCurrentTime";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { useCoState } from "jazz-react";
export function Waveform(props: { track: MusicTrack; height: number }) { export function Waveform(props: { track: MusicTrack; height: number }) {
const { track, height } = props; const { track, height } = props;

View File

@@ -1,18 +1,10 @@
import { MusicaAccount } from "../1_schema"; import { MusicaAccount } from "../1_schema";
export async function getNextTrack() { export async function getNextTrack(account: MusicaAccount) {
const me = await MusicaAccount.getMe().ensureLoaded({ if (!account.root?.activePlaylist?.tracks) return;
root: {
activePlaylist: {
tracks: [],
},
},
});
if (!me) return; const tracks = account.root.activePlaylist.tracks;
const activeTrack = account.root._refs.activeTrack;
const tracks = me.root.activePlaylist.tracks;
const activeTrack = me.root._refs.activeTrack;
const currentIndex = tracks.findIndex((item) => item?.id === activeTrack.id); const currentIndex = tracks.findIndex((item) => item?.id === activeTrack.id);
@@ -21,19 +13,11 @@ export async function getNextTrack() {
return tracks[nextIndex]; return tracks[nextIndex];
} }
export async function getPrevTrack() { export async function getPrevTrack(account: MusicaAccount) {
const me = await MusicaAccount.getMe().ensureLoaded({ if (!account.root?.activePlaylist?.tracks) return;
root: {
activePlaylist: {
tracks: [],
},
},
});
if (!me) return; const tracks = account.root.activePlaylist.tracks;
const activeTrack = account.root._refs.activeTrack;
const tracks = me.root.activePlaylist.tracks;
const activeTrack = me.root._refs.activeTrack;
const currentIndex = tracks.findIndex((item) => item?.id === activeTrack.id); const currentIndex = tracks.findIndex((item) => item?.id === activeTrack.id);

View File

@@ -1,30 +1,30 @@
import { MusicaAccount } from "@/1_schema"; // eslint-disable-next-line react-compiler/react-compiler
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect } from "react"; import { useEffect } from "react";
import { MusicaAccount } from "../1_schema";
import { useAccount } from "../2_main";
import { uploadMusicTracks } from "../4_actions"; import { uploadMusicTracks } from "../4_actions";
export function useUploadExampleData() { export function useUploadExampleData() {
useEffect(() => { const { me } = useAccount({
uploadOnboardingData();
}, []);
}
async function uploadOnboardingData() {
const me = await MusicaAccount.getMe().ensureLoaded({
root: {}, root: {},
}); });
if (!me) throw new Error("Me not resolved"); const shouldUploadOnboardingData = me?.root?.exampleDataLoaded === false;
if (me.root.exampleDataLoaded) return; useEffect(() => {
if (me?.root && shouldUploadOnboardingData) {
me.root.exampleDataLoaded = true;
me.root.exampleDataLoaded = true; uploadOnboardingData(me).then(() => {
me.root.exampleDataLoaded = true;
try { });
const trackFile = await (await fetch("/example.mp3")).blob(); }
}, [shouldUploadOnboardingData]);
await uploadMusicTracks([new File([trackFile], "Example song")]); }
} catch (error) {
me.root.exampleDataLoaded = false; async function uploadOnboardingData(me: MusicaAccount) {
throw error; const trackFile = await (await fetch("/example.mp3")).blob();
}
return uploadMusicTracks(me, [new File([trackFile], "Example song")]);
} }

View File

@@ -1,57 +1,5 @@
# jazz-example-onboarding # jazz-example-onboarding
## 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
- Updated dependencies [d1d773b]
- jazz-tools@0.9.8
- jazz-react@0.9.8
- jazz-browser-media-images@0.9.8
## 0.0.29
### Patch Changes
- jazz-react@0.9.4
## 0.0.28
### Patch Changes
- Updated dependencies [1b71969]
- jazz-react@0.9.1
- jazz-tools@0.9.1
- jazz-browser-media-images@0.9.1
## 0.0.27
### Patch Changes
- Updated dependencies [956a4d1]
- Updated dependencies [8eda792]
- jazz-react@0.9.0
- jazz-tools@0.9.0
- jazz-browser-media-images@0.9.0
## 0.0.26 ## 0.0.26
### Patch Changes ### Patch Changes

View File

@@ -1,58 +1,29 @@
# Onboarding example with Jazz and React # Onboarding example with Jazz and React
## Getting started ## Installing & running the example locally
You can either (This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
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 ```bash
npm create jazz-app@latest --example onboarding --project-name onboarding npx degit gardencmp/jazz jazz
```
or
```bash
npx create-jazz-app@latest --example onboarding --project-name onboarding
``` ```
Go to the new project directory. Go to the onboarding example directory:
```bash ```bash
cd onboarding cd jazz/examples/onboarding
``` ```
Run the dev server. Install and build dependencies:
```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 ```bash
pnpm i && npx turbo build pnpm i && npx turbo build
``` ```
Go to the example directory. Start the dev server:
```bash
cd jazz/examples/onboarding/
```
Start the dev server.
```bash ```bash
pnpm dev pnpm dev
``` ```
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
## Questions / problems / feedback ## 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. 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.
@@ -61,4 +32,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work. By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx cojson-simple-sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx). You can also run a local sync server by running `npx cojson-simple-sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/main.tsx](./src/main.tsx).

View File

@@ -1,7 +1,7 @@
{ {
"name": "jazz-example-onboarding", "name": "jazz-example-onboarding",
"private": true, "private": true,
"version": "0.0.32", "version": "0.0.26",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -1,9 +1,9 @@
import { Button } from "@/components/Button.tsx"; import { Button } from "@/components/Button.tsx";
import { useAcceptInvite, useAccount, useCoState } from "@/main.tsx";
import { EmployeeList } from "@/pages/EmployeeList.tsx"; import { EmployeeList } from "@/pages/EmployeeList.tsx";
import { EmployeeOnboading } from "@/pages/EmployeeOnboarding.tsx"; import { EmployeeOnboading } from "@/pages/EmployeeOnboarding.tsx";
import { NewEmployee } from "@/pages/NewEmployee.tsx"; import { NewEmployee } from "@/pages/NewEmployee.tsx";
import { CoEmployee, EmployeeCoList } from "@/schema.ts"; import { CoEmployee, EmployeeCoList } from "@/schema.ts";
import { useAcceptInvite, useAccount, useCoState } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { useEffect } from "react"; import { useEffect } from "react";
import { import {

View File

@@ -1,10 +1,15 @@
import App from "@/App.tsx"; import App from "@/App.tsx";
import "@/index.css"; import "@/index.css";
import { HRAccount } from "@/schema.ts"; import { HRAccount } from "@/schema.ts";
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react"; import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import React from "react"; import React from "react";
import ReactDOM from "react-dom/client"; import ReactDOM from "react-dom/client";
const Jazz = createJazzReactApp({
AccountSchema: HRAccount,
});
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
const peer = const peer =
(new URL(window.location.href).searchParams.get( (new URL(window.location.href).searchParams.get(
"peer", "peer",
@@ -15,9 +20,9 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, authState] = useDemoAuth(); const [auth, authState] = useDemoAuth();
return ( return (
<> <>
<JazzProvider AccountSchema={HRAccount} auth={auth} peer={peer}> <Jazz.Provider auth={auth} peer={peer}>
{children} {children}
</JazzProvider> </Jazz.Provider>
{authState.state !== "signedIn" && ( {authState.state !== "signedIn" && (
<DemoAuthBasicUI appName="Jazz Onboarding" state={authState} /> <DemoAuthBasicUI appName="Jazz Onboarding" state={authState} />
)} )}
@@ -25,12 +30,6 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
); );
} }
declare module "jazz-react" {
interface Register {
Account: HRAccount;
}
}
ReactDOM.createRoot(document.getElementById("root")!).render( ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode> <React.StrictMode>
<JazzAndAuth> <JazzAndAuth>

View File

@@ -1,8 +1,8 @@
import { NavLink } from "@/components/NavLink.tsx"; import { NavLink } from "@/components/NavLink.tsx";
import { NavigateButton } from "@/components/NavigateBack.tsx"; import { NavigateButton } from "@/components/NavigateBack.tsx";
import { Stack } from "@/components/Stack.tsx"; import { Stack } from "@/components/Stack.tsx";
import { useCoState } from "@/main.tsx";
import { CoEmployee, EmployeeCoList } from "@/schema.ts"; import { CoEmployee, EmployeeCoList } from "@/schema.ts";
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
export function EmployeeList({ export function EmployeeList({

View File

@@ -2,8 +2,8 @@ import { Button } from "@/components/Button.tsx";
import { NavigateBack } from "@/components/NavigateBack.tsx"; import { NavigateBack } from "@/components/NavigateBack.tsx";
import { Stack } from "@/components/Stack.tsx"; import { Stack } from "@/components/Stack.tsx";
import { TextInput } from "@/components/TextInput.tsx"; import { TextInput } from "@/components/TextInput.tsx";
import { useCoState } from "@/main.tsx";
import { createImage } from "jazz-browser-media-images"; import { createImage } from "jazz-browser-media-images";
import { useCoState } from "jazz-react";
import { ProgressiveImg, createInviteLink } from "jazz-react"; import { ProgressiveImg, createInviteLink } from "jazz-react";
import { CoMap, ID } from "jazz-tools"; import { CoMap, ID } from "jazz-tools";
import { ChangeEvent, ReactNode, useCallback } from "react"; import { ChangeEvent, ReactNode, useCallback } from "react";

View File

@@ -2,7 +2,7 @@ import { Button } from "@/components/Button.tsx";
import { NavigateBack } from "@/components/NavigateBack.tsx"; import { NavigateBack } from "@/components/NavigateBack.tsx";
import { Stack } from "@/components/Stack.tsx"; import { Stack } from "@/components/Stack.tsx";
import { TextInput } from "@/components/TextInput.tsx"; import { TextInput } from "@/components/TextInput.tsx";
import { useAccount, useCoState } from "jazz-react"; import { useAccount, useCoState } from "@/main.tsx";
import { Group, ID } from "jazz-tools"; import { Group, ID } from "jazz-tools";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";

View File

@@ -1,52 +1,5 @@
# organization # organization
## 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
- Updated dependencies [d1d773b]
- jazz-tools@0.9.8
- jazz-react@0.9.8
## 0.0.21
### Patch Changes
- jazz-react@0.9.4
## 0.0.20
### Patch Changes
- Updated dependencies [1b71969]
- jazz-react@0.9.1
- jazz-tools@0.9.1
## 0.0.19
### Patch Changes
- Updated dependencies [956a4d1]
- Updated dependencies [8eda792]
- jazz-react@0.9.0
- jazz-tools@0.9.0
## 0.0.18 ## 0.0.18
### Patch Changes ### Patch Changes

View File

@@ -5,60 +5,30 @@ 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. Refer to the [documentation](https://jazz.tools/docs/react/design-patterns/organization) for more information.
## Getting started ## Installing & running the example locally
You can either (This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation))
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 ```bash
npm create jazz-app@latest --example organization --project-name organization npx degit gardencmp/jazz jazz
```
or
```bash
npx create-jazz-app@latest --example organization --project-name organization
``` ```
Go to the new project directory. Go to the organization example directory:
```bash ```bash
cd organization cd jazz/examples/organization
``` ```
Run the dev server. Install and build dependencies:
```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 ```bash
pnpm i && npx turbo build pnpm i && npx turbo build
``` ```
Go to the example directory. Start the dev server:
```bash
cd jazz/examples/organization/
```
Start the dev server.
```bash ```bash
pnpm dev pnpm dev
``` ```
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
## Questions / problems / feedback ## 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. 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.
@@ -67,4 +37,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work. By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<JazzProvider>` provider component in [./src/main.tsx](./src/main.tsx). You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of the `<Jazz.Provider>` provider component in [./src/main.tsx](./src/main.tsx).

View File

@@ -1,7 +1,7 @@
{ {
"name": "organization", "name": "organization",
"private": true, "private": true,
"version": "0.0.24", "version": "0.0.18",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -1,6 +1,6 @@
import { useAcceptInvite, useAccount } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { useNavigate } from "react-router"; import { useNavigate } from "react-router";
import { useAcceptInvite, useAccount } from "./main.tsx";
import { Organization } from "./schema.ts"; import { Organization } from "./schema.ts";
export function AcceptInvitePage() { export function AcceptInvitePage() {

View File

@@ -1,7 +1,7 @@
import { useAccount } from "jazz-react";
import { Layout } from "./Layout.tsx"; import { Layout } from "./Layout.tsx";
import { CreateOrganization } from "./components/CreateOrganization.tsx"; import { CreateOrganization } from "./components/CreateOrganization.tsx";
import { Heading } from "./components/Heading.tsx"; import { Heading } from "./components/Heading.tsx";
import { useAccount } from "./main.tsx";
export function HomePage() { export function HomePage() {
const { me } = useAccount({ const { me } = useAccount({

View File

@@ -1,5 +1,5 @@
import { useAccount } from "jazz-react";
import { UserIcon } from "lucide-react"; import { UserIcon } from "lucide-react";
import { useAccount } from "./main.tsx";
export function Layout({ children }: { children: React.ReactNode }) { export function Layout({ children }: { children: React.ReactNode }) {
const { me, logOut } = useAccount({ const { me, logOut } = useAccount({

View File

@@ -1,4 +1,3 @@
import { useCoState } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { useParams } from "react-router"; import { useParams } from "react-router";
import { Layout } from "./Layout.tsx"; import { Layout } from "./Layout.tsx";
@@ -6,6 +5,7 @@ import { CreateProject } from "./components/CreateProject.tsx";
import { Heading } from "./components/Heading.tsx"; import { Heading } from "./components/Heading.tsx";
import { InviteLink } from "./components/InviteLink.tsx"; import { InviteLink } from "./components/InviteLink.tsx";
import { OrganizationMembers } from "./components/OrganizationMembers.tsx"; import { OrganizationMembers } from "./components/OrganizationMembers.tsx";
import { useCoState } from "./main.tsx";
import { Organization } from "./schema.ts"; import { Organization } from "./schema.ts";
export function OrganizationPage() { export function OrganizationPage() {

View File

@@ -1,7 +1,7 @@
import { useAccount, useCoState } from "jazz-react";
import { Group, ID } from "jazz-tools"; import { Group, ID } from "jazz-tools";
import { useState } from "react"; import { useState } from "react";
import { useNavigate } from "react-router"; import { useNavigate } from "react-router";
import { useAccount, useCoState } from "../main.tsx";
import { DraftOrganization, ListOfProjects, Organization } from "../schema.ts"; import { DraftOrganization, ListOfProjects, Organization } from "../schema.ts";
import { Errors } from "./Errors.tsx"; import { Errors } from "./Errors.tsx";
import { OrganizationForm } from "./OrganizationForm.tsx"; import { OrganizationForm } from "./OrganizationForm.tsx";

View File

@@ -1,5 +1,5 @@
import { useCoState } from "jazz-react";
import { Account, Group, ID } from "jazz-tools"; import { Account, Group, ID } from "jazz-tools";
import { useCoState } from "../main.tsx";
import { Organization } from "../schema.ts"; import { Organization } from "../schema.ts";
export function OrganizationMembers({ export function OrganizationMembers({

View File

@@ -1,8 +1,8 @@
import { useAccount } from "jazz-react";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { UsersIcon } from "lucide-react"; import { UsersIcon } from "lucide-react";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router"; import { useNavigate, useParams } from "react-router";
import { useAccount } from "../main.tsx";
import { Organization } from "../schema.ts"; import { Organization } from "../schema.ts";
export function OrganizationSelector({ className }: { className?: string }) { export function OrganizationSelector({ className }: { className?: string }) {

View File

@@ -1,4 +1,4 @@
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react"; import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { StrictMode } from "react"; import { StrictMode } from "react";
import { createRoot } from "react-dom/client"; import { createRoot } from "react-dom/client";
import "./index.css"; import "./index.css";
@@ -8,6 +8,11 @@ import { HomePage } from "./HomePage.tsx";
import { OrganizationPage } from "./OrganizationPage.tsx"; import { OrganizationPage } from "./OrganizationPage.tsx";
import { JazzAccount } from "./schema.ts"; import { JazzAccount } from "./schema.ts";
const Jazz = createJazzReactApp({
AccountSchema: JazzAccount,
});
export const { useAccount, useCoState, useAcceptInvite } = Jazz;
function Router() { function Router() {
const router = createHashRouter([ const router = createHashRouter([
{ {
@@ -32,13 +37,12 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
return ( return (
<> <>
<JazzProvider <Jazz.Provider
AccountSchema={JazzAccount}
auth={auth} auth={auth}
peer="wss://cloud.jazz.tools/?key=organization-example@garden.co" peer="wss://cloud.jazz.tools/?key=organization-example@garden.co"
> >
{children} {children}
</JazzProvider> </Jazz.Provider>
{authState.state !== "signedIn" && ( {authState.state !== "signedIn" && (
<DemoAuthBasicUI appName="Organization" state={authState} /> <DemoAuthBasicUI appName="Organization" state={authState} />
@@ -47,12 +51,6 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
); );
} }
declare module "jazz-react" {
interface Register {
Account: JazzAccount;
}
}
createRoot(document.getElementById("root")!).render( createRoot(document.getElementById("root")!).render(
<StrictMode> <StrictMode>
<JazzAndAuth> <JazzAndAuth>

View File

@@ -1,36 +1,5 @@
# passkey-svelte # passkey-svelte
## 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
- jazz-svelte@0.9.8
## 0.0.16
### Patch Changes
- jazz-svelte@0.9.1
## 0.0.15
### Patch Changes
- Updated dependencies [9dd8d95]
- jazz-svelte@0.9.0
## 0.0.14 ## 0.0.14
### Patch Changes ### Patch Changes

View File

@@ -10,59 +10,34 @@ This example showcases how to:
- Manage authentication state - Manage authentication state
- Implement secure login/logout flows - Implement secure login/logout flows
## Getting started ## Getting Started
You can either 1. Clone the repository:
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
npm create jazz-app@latest --example passkey-svelte --project-name passkey-svelte
```
or
```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 git clone https://github.com/garden-co/jazz.git
``` ```
Install and build dependencies. 2. Navigate to the example directory:
```bash
pnpm i && npx turbo build ```sh
cd examples/passkey-svelte
``` ```
Go to the example directory. 3. Install dependencies:
```bash
cd jazz/examples/passkey-svelte/ ```sh
pnpm install
``` ```
Start the dev server. 4. Start the development server:
```bash
```sh
pnpm dev pnpm dev
``` ```
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result. 5. Open your browser and visit [http://localhost:5173](http://localhost:5173)
## Learn More ## Learn More

View File

@@ -1,6 +1,6 @@
{ {
"name": "passkey-svelte", "name": "passkey-svelte",
"version": "0.0.19", "version": "0.0.14",
"type": "module", "type": "module",
"private": true, "private": true,
"scripts": { "scripts": {

View File

@@ -0,0 +1,3 @@
import { createJazzApp } from 'jazz-svelte';
export const { useAccount, useCoState, Provider } = createJazzApp();

Some files were not shown because too many files have changed in this diff Show More