Compare commits
223 Commits
feat/queue
...
pre-releas
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00f1072f5a | ||
|
|
c2d56b5eb8 | ||
|
|
0d9eacc1ec | ||
|
|
75491e65c0 | ||
|
|
b5be0273a6 | ||
|
|
62a1aec555 | ||
|
|
5053a6fc80 | ||
|
|
394feb715d | ||
|
|
76c125e628 | ||
|
|
10ac9d8659 | ||
|
|
9a6d950727 | ||
|
|
326d3b90c2 | ||
|
|
499f39340b | ||
|
|
54eba823ad | ||
|
|
61e787ec89 | ||
|
|
95d42b1340 | ||
|
|
bf9840ea46 | ||
|
|
74dbbaf4d4 | ||
|
|
c2ae5b6206 | ||
|
|
25de660d27 | ||
|
|
de90f45f41 | ||
|
|
dda79df1c3 | ||
|
|
26ea68999b | ||
|
|
4cfb4af1da | ||
|
|
11eaa99af7 | ||
|
|
93231c27f4 | ||
|
|
e7b9c90eef | ||
|
|
2e6c2498b5 | ||
|
|
e7fd617ca9 | ||
|
|
bd5b03b18d | ||
|
|
3a7ab9b3a1 | ||
|
|
0cf789622c | ||
|
|
d63f5eec5e | ||
|
|
42bd8b76a1 | ||
|
|
73742656ae | ||
|
|
f71f26d1dc | ||
|
|
95822300d7 | ||
|
|
679fe040cf | ||
|
|
14b6149f50 | ||
|
|
4446738940 | ||
|
|
c8ad016d9c | ||
|
|
498954fd09 | ||
|
|
198f6d3627 | ||
|
|
f701f2a4f4 | ||
|
|
94131ba6d6 | ||
|
|
c0e892313f | ||
|
|
b426342c02 | ||
|
|
bbbd773c3f | ||
|
|
7d5f4e5881 | ||
|
|
29c44538dc | ||
|
|
198f995b21 | ||
|
|
2d639667a3 | ||
|
|
1be017d69d | ||
|
|
03df4fee8e | ||
|
|
c658ed3404 | ||
|
|
99e58e60dc | ||
|
|
a9ad0284e9 | ||
|
|
6e2d791c4b | ||
|
|
f9be857bbb | ||
|
|
1288ac140e | ||
|
|
7f07f7e049 | ||
|
|
b22589bbad | ||
|
|
be144adeee | ||
|
|
513619b04e | ||
|
|
81f6a75aac | ||
|
|
913d03de75 | ||
|
|
2d0172d839 | ||
|
|
27d46641e3 | ||
|
|
1014816d79 | ||
|
|
441194acb7 | ||
|
|
c9bea7200f | ||
|
|
9eaa88bd83 | ||
|
|
6ada48d57a | ||
|
|
8fa978df21 | ||
|
|
df7356fd24 | ||
|
|
153fa4ce44 | ||
|
|
6105bd2c88 | ||
|
|
c06d63eec1 | ||
|
|
4ee7359370 | ||
|
|
7b5c47b377 | ||
|
|
7ad57e88f3 | ||
|
|
c181e55557 | ||
|
|
5574be699b | ||
|
|
b3142cb8ed | ||
|
|
cb08d9d1a3 | ||
|
|
7e0cd721e6 | ||
|
|
4d01cbae03 | ||
|
|
13f6389559 | ||
|
|
f6ea9bcc50 | ||
|
|
f6f2766eac | ||
|
|
f8f63bface | ||
|
|
5ec561fec4 | ||
|
|
277787cbd2 | ||
|
|
dda4336721 | ||
|
|
59ddff40ab | ||
|
|
064d19b48c | ||
|
|
3ea269f4d8 | ||
|
|
c4b8befe27 | ||
|
|
06f667ef2a | ||
|
|
bac3cc7bf8 | ||
|
|
6ad0a9f886 | ||
|
|
9b12932b66 | ||
|
|
82bb0d51d9 | ||
|
|
39dede92e8 | ||
|
|
84f4e6e48d | ||
|
|
e629dea585 | ||
|
|
2faf22ffff | ||
|
|
2273505a13 | ||
|
|
19eb29d831 | ||
|
|
738c4c2bd7 | ||
|
|
64e2273475 | ||
|
|
5a85c89154 | ||
|
|
8898b10e89 | ||
|
|
dc2d4e25f7 | ||
|
|
9275c4f6c0 | ||
|
|
cb75cc62b2 | ||
|
|
b141f6a62f | ||
|
|
4a251a528c | ||
|
|
ac3c2df474 | ||
|
|
681f973d4b | ||
|
|
338be7622f | ||
|
|
1227047b03 | ||
|
|
9afde8d0be | ||
|
|
c2ca1feba0 | ||
|
|
f8b6119996 | ||
|
|
98c265304a | ||
|
|
675e3e8046 | ||
|
|
4acba8c990 | ||
|
|
a93adeb1fe | ||
|
|
a7c90f749e | ||
|
|
cf8773f3de | ||
|
|
3be94ae1e7 | ||
|
|
6a8aa06d18 | ||
|
|
dc17889209 | ||
|
|
4dab70eea3 | ||
|
|
55f9d8e120 | ||
|
|
15b9457ed8 | ||
|
|
898297e95c | ||
|
|
0fc4f24cd5 | ||
|
|
63b5ad9edf | ||
|
|
873c3264ca | ||
|
|
34f89e48aa | ||
|
|
b01cc1fe9d | ||
|
|
3a6e34589f | ||
|
|
68e9c85d8f | ||
|
|
1b124ff5c7 | ||
|
|
a1d512d9d7 | ||
|
|
51bf6b7fdc | ||
|
|
b5826fc0a5 | ||
|
|
becdd2f451 | ||
|
|
3b20bf354f | ||
|
|
ab2645765d | ||
|
|
2dec852ce2 | ||
|
|
8cb09379f4 | ||
|
|
fff7fe934b | ||
|
|
9fb2e61e01 | ||
|
|
24b3b6afc1 | ||
|
|
c2eed7e2c4 | ||
|
|
f97ef696e3 | ||
|
|
ad65cb8ab5 | ||
|
|
8d8131410a | ||
|
|
7491711b72 | ||
|
|
5933aa59c1 | ||
|
|
da96bec465 | ||
|
|
483422c0e9 | ||
|
|
3df93cc147 | ||
|
|
d686edfa6c | ||
|
|
497b0ade1f | ||
|
|
794927cac3 | ||
|
|
4c8d128eee | ||
|
|
86acbcd0d6 | ||
|
|
9111c85445 | ||
|
|
1d87879787 | ||
|
|
7c777f2bdf | ||
|
|
aa8067b8d0 | ||
|
|
bd66cdeb78 | ||
|
|
8d29e50669 | ||
|
|
5a7398d242 | ||
|
|
74b984fbe6 | ||
|
|
f8e00204b4 | ||
|
|
76543df765 | ||
|
|
15d4b2a5f7 | ||
|
|
2e67f91fe0 | ||
|
|
df106ca680 | ||
|
|
c58f93b597 | ||
|
|
3f2a0ead1b | ||
|
|
c9e6d2998e | ||
|
|
0eb21a3471 | ||
|
|
99e88d3497 | ||
|
|
f09ce70d3c | ||
|
|
7d62e2735f | ||
|
|
40634c6ec1 | ||
|
|
5863badbb0 | ||
|
|
8bc758ce95 | ||
|
|
56d26222e7 | ||
|
|
bd34084104 | ||
|
|
f5e6fe927d | ||
|
|
93c49639c2 | ||
|
|
aabe7bef34 | ||
|
|
909165d813 | ||
|
|
6bee742b65 | ||
|
|
23486d01b9 | ||
|
|
b761d5a730 | ||
|
|
9181e74fc8 | ||
|
|
5e83864f41 | ||
|
|
73079ca1b7 | ||
|
|
c36f19a97f | ||
|
|
109338923a | ||
|
|
f4c2501b06 | ||
|
|
9161229474 | ||
|
|
265f2f40bf | ||
|
|
d2935ac2ae | ||
|
|
aaf00b8a20 | ||
|
|
f9c6a49d2a | ||
|
|
2f54a48a3d | ||
|
|
be4dd0a787 | ||
|
|
f3f072e7cf | ||
|
|
a6270bf552 | ||
|
|
de5f2d6d5b | ||
|
|
4aa377dea7 | ||
|
|
31ae73fe0e | ||
|
|
7a5adfc4dc | ||
|
|
850e264912 |
5
.changeset/afraid-queens-bathe.md
Normal file
5
.changeset/afraid-queens-bathe.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"cojson": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Export the coValue loading config to reduce the timeout on tests
|
||||||
16
.changeset/blue-kids-remain.md
Normal file
16
.changeset/blue-kids-remain.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
"jazz-react-native-auth-clerk": minor
|
||||||
|
"jazz-react-auth-clerk": minor
|
||||||
|
"cojson-transport-ws": minor
|
||||||
|
"jazz-react-native": minor
|
||||||
|
"jazz-auth-clerk": minor
|
||||||
|
"jazz-react-core": minor
|
||||||
|
"jazz-inspector": minor
|
||||||
|
"jazz-browser": minor
|
||||||
|
"jazz-nodejs": minor
|
||||||
|
"jazz-react": minor
|
||||||
|
"jazz-tools": minor
|
||||||
|
"cojson": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Introducing the new auth system!
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
"cojson-storage-sqlite",
|
"cojson-storage-sqlite",
|
||||||
"cojson-transport-ws",
|
"cojson-transport-ws",
|
||||||
"jazz-browser",
|
"jazz-browser",
|
||||||
"jazz-browser-auth-clerk",
|
"jazz-auth-clerk",
|
||||||
"jazz-browser-media-images",
|
"jazz-browser-media-images",
|
||||||
"jazz-nodejs",
|
"jazz-nodejs",
|
||||||
"jazz-react",
|
"jazz-react",
|
||||||
|
|||||||
5
.changeset/eighty-dingos-whisper.md
Normal file
5
.changeset/eighty-dingos-whisper.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"create-jazz-app": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Add framework and api-key param to create-jazz-app
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
"chat-rn-clerk": patch
|
|
||||||
"jazz-react-native": patch
|
|
||||||
"jazz-example-chat": patch
|
|
||||||
---
|
|
||||||
|
|
||||||
Fix image handling in react-native
|
|
||||||
15
.changeset/purple-eagles-cover.md
Normal file
15
.changeset/purple-eagles-cover.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
"jazz-nodejs": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Remove ws dependency to use native WebSocket.
|
||||||
|
|
||||||
|
NodeJS versions prior to v22 will need to provide a WebSocket constructor from ws:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { WebSocket } from "ws"
|
||||||
|
|
||||||
|
const { worker } = await startWorker({ WebSocket, synServer });
|
||||||
|
```
|
||||||
|
|
||||||
|
This makes it easier to run workers on every JS runtime.
|
||||||
8
.changeset/silent-turtles-obey.md
Normal file
8
.changeset/silent-turtles-obey.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
"jazz-react-core": minor
|
||||||
|
"jazz-svelte": minor
|
||||||
|
"jazz-tools": minor
|
||||||
|
"jazz-vue": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Return null when a coValue is not found
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
"cojson": patch
|
|
||||||
---
|
|
||||||
|
|
||||||
Optimize queue management
|
|
||||||
9
.github/workflows/build-examples.yaml
vendored
9
.github/workflows/build-examples.yaml
vendored
@@ -27,8 +27,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- name: Enable corepack
|
- name: Enable latestcorepack
|
||||||
run: corepack enable
|
run: |
|
||||||
|
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
|
||||||
|
npm install -g corepack@latest
|
||||||
|
echo "After : corepack version => $(corepack --version)"
|
||||||
|
corepack enable
|
||||||
|
pnpm --version
|
||||||
|
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
|
|||||||
9
.github/workflows/build-starters.yaml
vendored
9
.github/workflows/build-starters.yaml
vendored
@@ -18,8 +18,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- name: Enable corepack
|
- name: Enable latestcorepack
|
||||||
run: corepack enable
|
run: |
|
||||||
|
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
|
||||||
|
npm install -g corepack@latest
|
||||||
|
echo "After : corepack version => $(corepack --version)"
|
||||||
|
corepack enable
|
||||||
|
pnpm --version
|
||||||
|
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
|
|||||||
9
.github/workflows/jazz-run.yml
vendored
9
.github/workflows/jazz-run.yml
vendored
@@ -16,8 +16,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- name: Enable corepack
|
- name: Enable latestcorepack
|
||||||
run: corepack enable
|
run: |
|
||||||
|
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
|
||||||
|
npm install -g corepack@latest
|
||||||
|
echo "After : corepack version => $(corepack --version)"
|
||||||
|
corepack enable
|
||||||
|
pnpm --version
|
||||||
|
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
|
|||||||
9
.github/workflows/playwright.yml
vendored
9
.github/workflows/playwright.yml
vendored
@@ -20,8 +20,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- name: Enable corepack
|
- name: Enable latestcorepack
|
||||||
run: corepack enable
|
run: |
|
||||||
|
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
|
||||||
|
npm install -g corepack@latest
|
||||||
|
echo "After : corepack version => $(corepack --version)"
|
||||||
|
corepack enable
|
||||||
|
pnpm --version
|
||||||
|
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
|
|||||||
49
.github/workflows/pre-release.yml
vendored
Normal file
49
.github/workflows/pre-release.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
name: Pre-Publish tagged Pull Requests
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pre-release:
|
||||||
|
if: contains(github.event.pull_request.labels.*.name, 'pre-release')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Enable latestcorepack
|
||||||
|
run: |
|
||||||
|
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
|
||||||
|
npm install -g corepack@latest
|
||||||
|
echo "After : corepack version => $(corepack --version)"
|
||||||
|
corepack enable
|
||||||
|
pnpm --version
|
||||||
|
|
||||||
|
- name: Install Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: '.node-version'
|
||||||
|
cache: 'pnpm'
|
||||||
|
|
||||||
|
- name: Get pnpm store directory
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- uses: actions/cache@v4
|
||||||
|
name: Setup pnpm cache
|
||||||
|
with:
|
||||||
|
path: ${{ env.STORE_PATH }}
|
||||||
|
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-pnpm-store-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Pnpm Build
|
||||||
|
run: pnpm turbo build --filter="./packages/*"
|
||||||
|
|
||||||
|
- name: Pre publish
|
||||||
|
run: pnpm exec pkg-pr-new publish "./packages/*"
|
||||||
9
.github/workflows/release.yml
vendored
9
.github/workflows/release.yml
vendored
@@ -22,8 +22,13 @@ jobs:
|
|||||||
- name: Checkout Repo
|
- name: Checkout Repo
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Enable corepack
|
- name: Enable latestcorepack
|
||||||
run: corepack enable
|
run: |
|
||||||
|
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
|
||||||
|
npm install -g corepack@latest
|
||||||
|
echo "After : corepack version => $(corepack --version)"
|
||||||
|
corepack enable
|
||||||
|
pnpm --version
|
||||||
|
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
|
|||||||
9
.github/workflows/unit-test.yml
vendored
9
.github/workflows/unit-test.yml
vendored
@@ -15,8 +15,13 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Enable corepack
|
- name: Enable latestcorepack
|
||||||
run: corepack enable
|
run: |
|
||||||
|
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
|
||||||
|
npm install -g corepack@latest
|
||||||
|
echo "After : corepack version => $(corepack --version)"
|
||||||
|
corepack enable
|
||||||
|
pnpm --version
|
||||||
|
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
|
|||||||
@@ -42,6 +42,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"overrides": [
|
"overrides": [
|
||||||
|
{
|
||||||
|
"include": ["**/package.json"],
|
||||||
|
"linter": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"formatter": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"include": ["packages/**/src/**"],
|
"include": ["packages/**/src/**"],
|
||||||
"linter": {
|
"linter": {
|
||||||
|
|||||||
@@ -1,5 +1,130 @@
|
|||||||
# chat-rn-clerk
|
# chat-rn-clerk
|
||||||
|
|
||||||
|
## 1.0.63
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react-native@0.9.22
|
||||||
|
- jazz-react-native-auth-clerk@0.9.22
|
||||||
|
|
||||||
|
## 1.0.62
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [1be017d]
|
||||||
|
- jazz-tools@0.9.21
|
||||||
|
- jazz-react-native@0.9.21
|
||||||
|
- jazz-react-native-auth-clerk@0.9.21
|
||||||
|
- jazz-react-native-media-images@0.9.21
|
||||||
|
|
||||||
|
## 1.0.61
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [b01cc1f]
|
||||||
|
- jazz-tools@0.9.20
|
||||||
|
- jazz-react-native@0.9.20
|
||||||
|
- jazz-react-native-auth-clerk@0.9.20
|
||||||
|
- jazz-react-native-media-images@0.9.20
|
||||||
|
|
||||||
|
## 1.0.60
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react-native@0.9.19
|
||||||
|
- jazz-react-native-auth-clerk@0.9.19
|
||||||
|
- jazz-tools@0.9.19
|
||||||
|
- jazz-react-native-media-images@0.9.19
|
||||||
|
|
||||||
|
## 1.0.59
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react-native@0.9.18
|
||||||
|
- jazz-react-native-auth-clerk@0.9.18
|
||||||
|
- jazz-tools@0.9.18
|
||||||
|
- jazz-react-native-media-images@0.9.18
|
||||||
|
|
||||||
|
## 1.0.58
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [c2ca1fe]
|
||||||
|
- Updated dependencies [1227047]
|
||||||
|
- jazz-tools@0.9.17
|
||||||
|
- jazz-react-native@0.9.17
|
||||||
|
- jazz-react-native-auth-clerk@0.9.17
|
||||||
|
- jazz-react-native-media-images@0.9.17
|
||||||
|
|
||||||
|
## 1.0.57
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [24b3b6a]
|
||||||
|
- jazz-react-native-auth-clerk@0.9.16
|
||||||
|
- jazz-tools@0.9.16
|
||||||
|
- jazz-react-native@0.9.16
|
||||||
|
- jazz-react-native-media-images@0.9.16
|
||||||
|
|
||||||
|
## 1.0.56
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [7491711]
|
||||||
|
- jazz-tools@0.9.15
|
||||||
|
- jazz-react-native@0.9.15
|
||||||
|
- jazz-react-native-auth-clerk@0.9.15
|
||||||
|
- jazz-react-native-media-images@0.9.15
|
||||||
|
|
||||||
|
## 1.0.55
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [3df93cc]
|
||||||
|
- jazz-tools@0.9.14
|
||||||
|
- jazz-react-native@0.9.14
|
||||||
|
- jazz-react-native-auth-clerk@0.9.14
|
||||||
|
- jazz-react-native-media-images@0.9.14
|
||||||
|
|
||||||
|
## 1.0.54
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react-native@0.9.13
|
||||||
|
- jazz-react-native-auth-clerk@0.9.13
|
||||||
|
- jazz-tools@0.9.13
|
||||||
|
- jazz-react-native-media-images@0.9.13
|
||||||
|
|
||||||
|
## 1.0.53
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react-native@0.9.12
|
||||||
|
- jazz-react-native-auth-clerk@0.9.12
|
||||||
|
- jazz-tools@0.9.12
|
||||||
|
- jazz-react-native-media-images@0.9.12
|
||||||
|
|
||||||
|
## 1.0.52
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react-native@0.9.11
|
||||||
|
- jazz-react-native-auth-clerk@0.9.11
|
||||||
|
- jazz-tools@0.9.11
|
||||||
|
- jazz-react-native-media-images@0.9.11
|
||||||
|
|
||||||
|
## 1.0.51
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- f76274c: Fix image handling in react-native
|
||||||
|
- Updated dependencies [f76274c]
|
||||||
|
- Updated dependencies [5e83864]
|
||||||
|
- jazz-react-native@0.9.10
|
||||||
|
- jazz-tools@0.9.10
|
||||||
|
- jazz-react-native-auth-clerk@0.9.10
|
||||||
|
- jazz-react-native-media-images@0.9.10
|
||||||
|
|
||||||
## 1.0.50
|
## 1.0.50
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Redirect, Stack } from "expo-router";
|
import { Redirect, Stack } from "expo-router";
|
||||||
|
import { useIsAuthenticated } from "jazz-react-native";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useAuth } from "../../src/auth-context";
|
|
||||||
|
|
||||||
export default function HomeLayout() {
|
export default function HomeLayout() {
|
||||||
const { isAuthenticated } = useAuth();
|
const isAuthenticated = useIsAuthenticated();
|
||||||
|
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
return <Redirect href={"/chat"} />;
|
return <Redirect href={"/chat"} />;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Redirect, Stack } from "expo-router";
|
import { Redirect, Stack } from "expo-router";
|
||||||
import { useAuth } from "../../src/auth-context";
|
import { useIsAuthenticated } from "jazz-react-native";
|
||||||
|
|
||||||
export default function UnAuthenticatedLayout() {
|
export default function UnAuthenticatedLayout() {
|
||||||
const { isAuthenticated } = useAuth();
|
const isAuthenticated = useIsAuthenticated();
|
||||||
|
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
return <Redirect href={"/chat"} />;
|
return <Redirect href={"/chat"} />;
|
||||||
|
|||||||
@@ -20,10 +20,15 @@ export default function ChatScreen() {
|
|||||||
const navigation = useNavigation();
|
const navigation = useNavigation();
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
|
|
||||||
|
function handleLogOut() {
|
||||||
|
logOut();
|
||||||
|
router.navigate("/");
|
||||||
|
}
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
headerTitle: "Chat",
|
headerTitle: "Chat",
|
||||||
headerRight: () => <Button onPress={logOut} title="Logout" />,
|
headerRight: () => <Button onPress={handleLogOut} title="Logout" />,
|
||||||
});
|
});
|
||||||
}, [navigation]);
|
}, [navigation]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "chat-rn-clerk",
|
"name": "chat-rn-clerk",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"version": "1.0.50",
|
"version": "1.0.63",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "expo export -p ios",
|
"build": "expo export -p ios",
|
||||||
"start": "expo start",
|
"start": "expo start",
|
||||||
|
|||||||
1
examples/chat-rn-clerk/src/apiKey.ts
Normal file
1
examples/chat-rn-clerk/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const apiKey = "chat-rn-clerk-example-jazz@garden.co";
|
||||||
@@ -1,63 +1,21 @@
|
|||||||
import { useClerk, useUser } from "@clerk/clerk-expo";
|
import { useClerk } from "@clerk/clerk-expo";
|
||||||
import { JazzProvider, setupKvStore } from "jazz-react-native";
|
import { JazzProviderWithClerk } from "jazz-react-native-auth-clerk";
|
||||||
import { useJazzClerkAuth } from "jazz-react-native-auth-clerk";
|
import React, { PropsWithChildren } from "react";
|
||||||
import React, {
|
import { apiKey } from "./apiKey";
|
||||||
createContext,
|
|
||||||
PropsWithChildren,
|
|
||||||
useContext,
|
|
||||||
useEffect,
|
|
||||||
useState,
|
|
||||||
} from "react";
|
|
||||||
import { Text, View } from "react-native";
|
|
||||||
const AuthContext = createContext<{
|
|
||||||
isAuthenticated: boolean;
|
|
||||||
isLoading: boolean;
|
|
||||||
}>({
|
|
||||||
isAuthenticated: false,
|
|
||||||
isLoading: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
export function useAuth() {
|
|
||||||
return useContext(AuthContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
const kvStore = setupKvStore();
|
|
||||||
|
|
||||||
export function JazzAndAuth({ children }: PropsWithChildren) {
|
export function JazzAndAuth({ children }: PropsWithChildren) {
|
||||||
const { isSignedIn, isLoaded: isClerkLoaded } = useUser();
|
|
||||||
const clerk = useClerk();
|
const clerk = useClerk();
|
||||||
const [auth, state] = useJazzClerkAuth(clerk, kvStore);
|
|
||||||
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isSignedIn && isClerkLoaded && auth) {
|
|
||||||
setIsAuthenticated(true);
|
|
||||||
} else {
|
|
||||||
setIsAuthenticated(false);
|
|
||||||
}
|
|
||||||
}, [isSignedIn, isClerkLoaded, auth]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AuthContext.Provider
|
<JazzProviderWithClerk
|
||||||
value={{ isAuthenticated, isLoading: !isClerkLoaded || !auth }}
|
clerk={clerk}
|
||||||
|
storage="sqlite"
|
||||||
|
sync={{
|
||||||
|
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||||
|
when: "signedUp", // This makes the app work in local mode when the user is not authenticated
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{state?.errors?.length > 0 &&
|
{children}
|
||||||
state.errors.map((error) => (
|
</JazzProviderWithClerk>
|
||||||
<View key={error}>
|
|
||||||
<Text style={{ color: "red" }}>{error}</Text>
|
|
||||||
</View>
|
|
||||||
))}
|
|
||||||
{auth && clerk.user ? (
|
|
||||||
<JazzProvider
|
|
||||||
auth={auth}
|
|
||||||
storage="sqlite"
|
|
||||||
peer="wss://cloud.jazz.tools/?key=chat-rn-clerk-example-jazz@garden.co"
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</JazzProvider>
|
|
||||||
) : (
|
|
||||||
children
|
|
||||||
)}
|
|
||||||
</AuthContext.Provider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,104 @@
|
|||||||
# chat-rn
|
# chat-rn
|
||||||
|
|
||||||
|
## 1.0.60
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react-native@0.9.22
|
||||||
|
|
||||||
|
## 1.0.59
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [1be017d]
|
||||||
|
- jazz-tools@0.9.21
|
||||||
|
- jazz-react-native@0.9.21
|
||||||
|
|
||||||
|
## 1.0.58
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [b01cc1f]
|
||||||
|
- jazz-tools@0.9.20
|
||||||
|
- jazz-react-native@0.9.20
|
||||||
|
|
||||||
|
## 1.0.57
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react-native@0.9.19
|
||||||
|
- jazz-tools@0.9.19
|
||||||
|
|
||||||
|
## 1.0.56
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react-native@0.9.18
|
||||||
|
- jazz-tools@0.9.18
|
||||||
|
|
||||||
|
## 1.0.55
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [c2ca1fe]
|
||||||
|
- Updated dependencies [1227047]
|
||||||
|
- jazz-tools@0.9.17
|
||||||
|
- jazz-react-native@0.9.17
|
||||||
|
|
||||||
|
## 1.0.54
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [24b3b6a]
|
||||||
|
- jazz-tools@0.9.16
|
||||||
|
- jazz-react-native@0.9.16
|
||||||
|
|
||||||
|
## 1.0.53
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [7491711]
|
||||||
|
- jazz-tools@0.9.15
|
||||||
|
- jazz-react-native@0.9.15
|
||||||
|
|
||||||
|
## 1.0.52
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [3df93cc]
|
||||||
|
- jazz-tools@0.9.14
|
||||||
|
- jazz-react-native@0.9.14
|
||||||
|
|
||||||
|
## 1.0.51
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react-native@0.9.13
|
||||||
|
- jazz-tools@0.9.13
|
||||||
|
|
||||||
|
## 1.0.50
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react-native@0.9.12
|
||||||
|
- jazz-tools@0.9.12
|
||||||
|
|
||||||
|
## 1.0.49
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react-native@0.9.11
|
||||||
|
- jazz-tools@0.9.11
|
||||||
|
|
||||||
|
## 1.0.48
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [f76274c]
|
||||||
|
- Updated dependencies [5e83864]
|
||||||
|
- jazz-react-native@0.9.10
|
||||||
|
- jazz-tools@0.9.10
|
||||||
|
|
||||||
## 1.0.47
|
## 1.0.47
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "chat-rn",
|
"name": "chat-rn",
|
||||||
"version": "1.0.47",
|
"version": "1.0.60",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "expo export -p ios",
|
"build": "expo export -p ios",
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ 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 { JazzProvider } from "jazz-react-native";
|
||||||
|
import { apiKey } from "./apiKey";
|
||||||
import ChatScreen from "./chat";
|
import ChatScreen from "./chat";
|
||||||
|
|
||||||
const Stack = createNativeStackNavigator();
|
const Stack = createNativeStackNavigator();
|
||||||
@@ -28,7 +29,6 @@ const linking = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [auth, state] = useDemoAuth();
|
|
||||||
const [initialRoute, setInitialRoute] = useState<
|
const [initialRoute, setInitialRoute] = useState<
|
||||||
"ChatScreen" | "HandleInviteScreen"
|
"ChatScreen" | "HandleInviteScreen"
|
||||||
>("ChatScreen");
|
>("ChatScreen");
|
||||||
@@ -43,16 +43,13 @@ function App() {
|
|||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (!auth) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<JazzProvider
|
<JazzProvider
|
||||||
auth={auth}
|
|
||||||
storage="sqlite"
|
storage="sqlite"
|
||||||
peer="wss://cloud.jazz.tools/?key=chat-rn-example-jazz@garden.co"
|
sync={{
|
||||||
|
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<NavigationContainer linking={linking} ref={navigationRef}>
|
<NavigationContainer linking={linking} ref={navigationRef}>
|
||||||
<Stack.Navigator initialRouteName={initialRoute}>
|
<Stack.Navigator initialRouteName={initialRoute}>
|
||||||
@@ -69,9 +66,6 @@ function App() {
|
|||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
</NavigationContainer>
|
</NavigationContainer>
|
||||||
</JazzProvider>
|
</JazzProvider>
|
||||||
{state.state !== "signedIn" ? (
|
|
||||||
<DemoAuthBasicUI appName="Jazz Chat" state={state} />
|
|
||||||
) : null}
|
|
||||||
</StrictMode>
|
</StrictMode>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
1
examples/chat-rn/src/apiKey.ts
Normal file
1
examples/chat-rn/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const apiKey = "chat-rn-example-jazz@garden.co";
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import * as Clipboard from "expo-clipboard";
|
import * as Clipboard from "expo-clipboard";
|
||||||
import { Group, ID } from "jazz-tools";
|
import { Group, ID, Profile } from "jazz-tools";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import React, {
|
import React, {
|
||||||
Button,
|
Button,
|
||||||
@@ -22,10 +22,16 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
|
|||||||
const [chatId, setChatId] = useState<ID<Chat>>();
|
const [chatId, setChatId] = useState<ID<Chat>>();
|
||||||
const loadedChat = useCoState(Chat, chatId, [{}]);
|
const loadedChat = useCoState(Chat, chatId, [{}]);
|
||||||
const [message, setMessage] = useState("");
|
const [message, setMessage] = useState("");
|
||||||
|
const profile = useCoState(Profile, me._refs.profile?.id, {});
|
||||||
|
|
||||||
|
function handleLogOut() {
|
||||||
|
setChatId(undefined);
|
||||||
|
logOut();
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
headerRight: () => <Button onPress={logOut} title="Logout" />,
|
headerRight: () => <Button onPress={handleLogOut} title="Logout" />,
|
||||||
headerLeft: () =>
|
headerLeft: () =>
|
||||||
loadedChat ? (
|
loadedChat ? (
|
||||||
<Button
|
<Button
|
||||||
@@ -131,6 +137,18 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
|
|||||||
<View className="flex flex-col h-full">
|
<View className="flex flex-col h-full">
|
||||||
{!loadedChat ? (
|
{!loadedChat ? (
|
||||||
<View className="flex flex-col h-full items-center justify-center">
|
<View className="flex flex-col h-full items-center justify-center">
|
||||||
|
<Text className="text-m font-bold mb-6">Username</Text>
|
||||||
|
<TextInput
|
||||||
|
className="rounded h-12 p-2 mb-12 w-40 border border-gray-200 block"
|
||||||
|
value={profile?.name ?? ""}
|
||||||
|
onChangeText={(value) => {
|
||||||
|
if (profile) {
|
||||||
|
profile.name = value;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
textAlignVertical="center"
|
||||||
|
onSubmitEditing={sendMessage}
|
||||||
|
/>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
onPress={createChat}
|
onPress={createChat}
|
||||||
className="bg-blue-500 p-4 rounded-md"
|
className="bg-blue-500 p-4 rounded-md"
|
||||||
|
|||||||
@@ -1,5 +1,116 @@
|
|||||||
# chat-vue
|
# chat-vue
|
||||||
|
|
||||||
|
## 0.0.47
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-browser@0.9.22
|
||||||
|
- jazz-vue@0.9.22
|
||||||
|
|
||||||
|
## 0.0.46
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [1be017d]
|
||||||
|
- jazz-tools@0.9.21
|
||||||
|
- jazz-browser@0.9.21
|
||||||
|
- jazz-vue@0.9.21
|
||||||
|
|
||||||
|
## 0.0.45
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [b01cc1f]
|
||||||
|
- jazz-tools@0.9.20
|
||||||
|
- jazz-browser@0.9.20
|
||||||
|
- jazz-vue@0.9.20
|
||||||
|
|
||||||
|
## 0.0.44
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-browser@0.9.19
|
||||||
|
- jazz-tools@0.9.19
|
||||||
|
- jazz-vue@0.9.19
|
||||||
|
|
||||||
|
## 0.0.43
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-browser@0.9.18
|
||||||
|
- jazz-tools@0.9.18
|
||||||
|
- jazz-vue@0.9.18
|
||||||
|
|
||||||
|
## 0.0.42
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [c2ca1fe]
|
||||||
|
- Updated dependencies [1227047]
|
||||||
|
- jazz-tools@0.9.17
|
||||||
|
- jazz-browser@0.9.17
|
||||||
|
- jazz-vue@0.9.17
|
||||||
|
|
||||||
|
## 0.0.41
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [24b3b6a]
|
||||||
|
- jazz-tools@0.9.16
|
||||||
|
- jazz-browser@0.9.16
|
||||||
|
- jazz-vue@0.9.16
|
||||||
|
|
||||||
|
## 0.0.40
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [7491711]
|
||||||
|
- jazz-tools@0.9.15
|
||||||
|
- jazz-browser@0.9.15
|
||||||
|
- jazz-vue@0.9.15
|
||||||
|
|
||||||
|
## 0.0.39
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [3df93cc]
|
||||||
|
- jazz-tools@0.9.14
|
||||||
|
- jazz-browser@0.9.14
|
||||||
|
- jazz-vue@0.9.14
|
||||||
|
|
||||||
|
## 0.0.38
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-browser@0.9.13
|
||||||
|
- jazz-tools@0.9.13
|
||||||
|
- jazz-vue@0.9.13
|
||||||
|
|
||||||
|
## 0.0.37
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-browser@0.9.12
|
||||||
|
- jazz-tools@0.9.12
|
||||||
|
- jazz-vue@0.9.12
|
||||||
|
|
||||||
|
## 0.0.36
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-browser@0.9.11
|
||||||
|
- jazz-tools@0.9.11
|
||||||
|
- jazz-vue@0.9.11
|
||||||
|
|
||||||
|
## 0.0.35
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [5e83864]
|
||||||
|
- jazz-tools@0.9.10
|
||||||
|
- jazz-browser@0.9.10
|
||||||
|
- jazz-vue@0.9.10
|
||||||
|
|
||||||
## 0.0.34
|
## 0.0.34
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -11,10 +11,6 @@ You can either
|
|||||||
|
|
||||||
Create a new Jazz project, and use this 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
|
|
||||||
```
|
|
||||||
or
|
|
||||||
```bash
|
|
||||||
npx create-jazz-app@latest --example chat-vue --project-name chat-vue
|
npx create-jazz-app@latest --example chat-vue --project-name chat-vue
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "chat-vue",
|
"name": "chat-vue",
|
||||||
"version": "0.0.34",
|
"version": "0.0.47",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
1
examples/chat-vue/src/apiKey.ts
Normal file
1
examples/chat-vue/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const apiKey = "chat-example-jazz@garden.co";
|
||||||
@@ -1,32 +1,31 @@
|
|||||||
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-vue";
|
import { DemoAuthBasicUI, JazzProvider } 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 { apiKey } from "@/apiKey";
|
||||||
import router from "./router";
|
import router from "./router";
|
||||||
|
|
||||||
const RootComponent = defineComponent({
|
const RootComponent = defineComponent({
|
||||||
name: "RootComponent",
|
name: "RootComponent",
|
||||||
setup() {
|
setup() {
|
||||||
const { authMethod, state } = useDemoAuth();
|
return () =>
|
||||||
|
|
||||||
return () => [
|
|
||||||
h(
|
h(
|
||||||
JazzProvider,
|
JazzProvider,
|
||||||
{
|
{
|
||||||
auth: authMethod.value,
|
sync: {
|
||||||
peer: "wss://cloud.jazz.tools/?key=chat-example-jazz@garden.co",
|
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
h(
|
||||||
default: () => h(App),
|
DemoAuthBasicUI,
|
||||||
},
|
{
|
||||||
),
|
appName: "Jazz Vue Chat",
|
||||||
|
},
|
||||||
state.state !== "signedIn" &&
|
{
|
||||||
h(DemoAuthBasicUI, {
|
default: () => h(App),
|
||||||
appName: "Jazz Chat",
|
},
|
||||||
state,
|
),
|
||||||
}),
|
);
|
||||||
];
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,117 @@
|
|||||||
# jazz-example-chat
|
# jazz-example-chat
|
||||||
|
|
||||||
|
## 0.0.143
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-browser-media-images@0.9.22
|
||||||
|
- jazz-react@0.9.22
|
||||||
|
|
||||||
|
## 0.0.142
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [1be017d]
|
||||||
|
- jazz-tools@0.9.21
|
||||||
|
- jazz-browser-media-images@0.9.21
|
||||||
|
- jazz-react@0.9.21
|
||||||
|
|
||||||
|
## 0.0.141
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [b01cc1f]
|
||||||
|
- jazz-tools@0.9.20
|
||||||
|
- jazz-browser-media-images@0.9.20
|
||||||
|
- jazz-react@0.9.20
|
||||||
|
|
||||||
|
## 0.0.140
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.19
|
||||||
|
- jazz-tools@0.9.19
|
||||||
|
- jazz-browser-media-images@0.9.19
|
||||||
|
|
||||||
|
## 0.0.139
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.18
|
||||||
|
- jazz-tools@0.9.18
|
||||||
|
- jazz-browser-media-images@0.9.18
|
||||||
|
|
||||||
|
## 0.0.138
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [c2ca1fe]
|
||||||
|
- Updated dependencies [1227047]
|
||||||
|
- jazz-tools@0.9.17
|
||||||
|
- jazz-browser-media-images@0.9.17
|
||||||
|
- jazz-react@0.9.17
|
||||||
|
|
||||||
|
## 0.0.137
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [24b3b6a]
|
||||||
|
- jazz-tools@0.9.16
|
||||||
|
- jazz-browser-media-images@0.9.16
|
||||||
|
- jazz-react@0.9.16
|
||||||
|
|
||||||
|
## 0.0.136
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [7491711]
|
||||||
|
- jazz-tools@0.9.15
|
||||||
|
- jazz-browser-media-images@0.9.15
|
||||||
|
- jazz-react@0.9.15
|
||||||
|
|
||||||
|
## 0.0.135
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [3df93cc]
|
||||||
|
- jazz-tools@0.9.14
|
||||||
|
- jazz-browser-media-images@0.9.14
|
||||||
|
- jazz-react@0.9.14
|
||||||
|
|
||||||
|
## 0.0.134
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.13
|
||||||
|
- jazz-tools@0.9.13
|
||||||
|
- jazz-browser-media-images@0.9.13
|
||||||
|
|
||||||
|
## 0.0.133
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.12
|
||||||
|
- jazz-tools@0.9.12
|
||||||
|
- jazz-browser-media-images@0.9.12
|
||||||
|
|
||||||
|
## 0.0.132
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.11
|
||||||
|
- jazz-tools@0.9.11
|
||||||
|
- jazz-browser-media-images@0.9.11
|
||||||
|
|
||||||
|
## 0.0.131
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- f76274c: Fix image handling in react-native
|
||||||
|
- Updated dependencies [5e83864]
|
||||||
|
- jazz-react@0.9.10
|
||||||
|
- jazz-tools@0.9.10
|
||||||
|
- jazz-browser-media-images@0.9.10
|
||||||
|
|
||||||
## 0.0.130
|
## 0.0.130
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -13,10 +13,6 @@ You can either
|
|||||||
|
|
||||||
Create a new Jazz project, and use this 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
|
|
||||||
```
|
|
||||||
or
|
|
||||||
```bash
|
|
||||||
npx create-jazz-app@latest --example chat --project-name chat
|
npx create-jazz-app@latest --example chat --project-name chat
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "jazz-example-chat",
|
"name": "jazz-example-chat",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.130",
|
"version": "0.0.143",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
1
examples/chat/src/apiKey.ts
Normal file
1
examples/chat/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const apiKey = "chat-example-jazz@garden.co";
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { inIframe, onChatLoad } from "@/util.ts";
|
import { apiKey } from "@/apiKey.ts";
|
||||||
|
import { getRandomUsername, inIframe, onChatLoad } from "@/util.ts";
|
||||||
import { useIframeHashRouter } from "hash-slash";
|
import { useIframeHashRouter } from "hash-slash";
|
||||||
import { useAccount } from "jazz-react";
|
import { JazzProvider, useAccount } from "jazz-react";
|
||||||
import { Group, ID } from "jazz-tools";
|
import { Group, ID } from "jazz-tools";
|
||||||
import { StrictMode } from "react";
|
import { StrictMode } from "react";
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
import { ChatScreen } from "./chatScreen.tsx";
|
import { ChatScreen } from "./chatScreen.tsx";
|
||||||
import { JazzAndAuth } from "./jazz.tsx";
|
|
||||||
import { Chat } from "./schema.ts";
|
import { Chat } from "./schema.ts";
|
||||||
import { ThemeProvider } from "./themeProvider.tsx";
|
import { ThemeProvider } from "./themeProvider.tsx";
|
||||||
import { AppContainer, TopBar } from "./ui.tsx";
|
import { AppContainer, TopBar } from "./ui.tsx";
|
||||||
@@ -28,7 +28,15 @@ export function App() {
|
|||||||
return (
|
return (
|
||||||
<AppContainer>
|
<AppContainer>
|
||||||
<TopBar>
|
<TopBar>
|
||||||
<p>{me?.profile?.name}</p>
|
<input
|
||||||
|
type="text"
|
||||||
|
value={me?.profile?.name ?? ""}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (!me?.profile) return;
|
||||||
|
me.profile.name = e.target.value;
|
||||||
|
}}
|
||||||
|
placeholder="Set username"
|
||||||
|
/>
|
||||||
{!inIframe && <button onClick={logOut}>Log out</button>}
|
{!inIframe && <button onClick={logOut}>Log out</button>}
|
||||||
</TopBar>
|
</TopBar>
|
||||||
{router.route({
|
{router.route({
|
||||||
@@ -39,12 +47,20 @@ export function App() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
const defaultProfileName = url.searchParams.get("user") ?? getRandomUsername();
|
||||||
|
|
||||||
createRoot(document.getElementById("root")!).render(
|
createRoot(document.getElementById("root")!).render(
|
||||||
<ThemeProvider>
|
<ThemeProvider>
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<JazzAndAuth>
|
<JazzProvider
|
||||||
|
sync={{
|
||||||
|
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||||
|
}}
|
||||||
|
defaultProfileName={defaultProfileName}
|
||||||
|
>
|
||||||
<App />
|
<App />
|
||||||
</JazzAndAuth>
|
</JazzProvider>
|
||||||
</StrictMode>
|
</StrictMode>
|
||||||
</ThemeProvider>,
|
</ThemeProvider>,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
|
|
||||||
|
|
||||||
export function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
|
||||||
const [auth, state] = useDemoAuth();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<JazzProvider
|
|
||||||
auth={auth}
|
|
||||||
peer="wss://cloud.jazz.tools/?key=chat-example-jazz@garden.co"
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</JazzProvider>
|
|
||||||
{state.state !== "signedIn" && (
|
|
||||||
<DemoAuthBasicUI appName="Jazz Chat" state={state} />
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -15,3 +15,20 @@ export function onChatLoad(chat: Chat) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const inIframe = window.self !== window.top;
|
export const inIframe = window.self !== window.top;
|
||||||
|
|
||||||
|
const animals = [
|
||||||
|
"elephant",
|
||||||
|
"penguin",
|
||||||
|
"giraffe",
|
||||||
|
"octopus",
|
||||||
|
"kangaroo",
|
||||||
|
"dolphin",
|
||||||
|
"cheetah",
|
||||||
|
"koala",
|
||||||
|
"platypus",
|
||||||
|
"pangolin",
|
||||||
|
];
|
||||||
|
|
||||||
|
export function getRandomUsername() {
|
||||||
|
return `Anonymous ${animals[Math.floor(Math.random() * animals.length)]}`;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,48 +1,35 @@
|
|||||||
import { test } from "@playwright/test";
|
import { test } from "@playwright/test";
|
||||||
import { ChatPage } from "./pages/ChatPage";
|
import { ChatPage } from "./pages/ChatPage";
|
||||||
import { LoginPage } from "./pages/LoginPage";
|
|
||||||
|
|
||||||
test("chat between two users", async ({ page }) => {
|
test("chat between two users", async ({ page: marioPage, browser }) => {
|
||||||
const loginPage = new LoginPage(page);
|
const context = await browser.newContext();
|
||||||
|
const luigiPage = await context.newPage();
|
||||||
|
|
||||||
const mario = "S. Mario";
|
await marioPage.goto("/");
|
||||||
const luigi = "Luigi";
|
|
||||||
|
|
||||||
await loginPage.goto();
|
const marioChat = new ChatPage(marioPage);
|
||||||
await loginPage.fillUsername(mario);
|
const luigiChat = new ChatPage(luigiPage);
|
||||||
await loginPage.signup();
|
|
||||||
|
|
||||||
const chatPage = new ChatPage(page);
|
await marioChat.setUsername("Mario");
|
||||||
|
|
||||||
const message1ByMario = "Hello Luigi, are you ready to save the princess?";
|
const message1ByMario = "Hello Luigi, are you ready to save the princess?";
|
||||||
|
|
||||||
await chatPage.sendMessage(message1ByMario);
|
await marioChat.sendMessage(message1ByMario);
|
||||||
await chatPage.expectMessageRow(message1ByMario);
|
await marioChat.expectMessageRow(message1ByMario);
|
||||||
|
|
||||||
const roomURL = page.url();
|
const roomURL = marioPage.url();
|
||||||
|
await luigiPage.goto(roomURL);
|
||||||
|
|
||||||
await chatPage.logout();
|
await luigiChat.setUsername("Luigi");
|
||||||
|
|
||||||
await loginPage.expectLoaded();
|
await luigiChat.expectMessageRow(message1ByMario);
|
||||||
|
|
||||||
await loginPage.fillUsername(luigi);
|
|
||||||
await loginPage.signup();
|
|
||||||
|
|
||||||
await page.goto(roomURL);
|
|
||||||
|
|
||||||
await chatPage.expectMessageRow(message1ByMario);
|
|
||||||
|
|
||||||
const message2ByLuigi =
|
const message2ByLuigi =
|
||||||
"No, I'm not ready yet. I'm still trying to find the key to the castle.";
|
"No, I'm not ready yet. I'm still trying to find the key to the castle.";
|
||||||
|
|
||||||
await chatPage.sendMessage(message2ByLuigi);
|
await luigiChat.sendMessage(message2ByLuigi);
|
||||||
await chatPage.expectMessageRow(message2ByLuigi);
|
await luigiChat.expectMessageRow(message2ByLuigi);
|
||||||
|
|
||||||
await chatPage.logout();
|
await marioChat.expectMessageRow(message1ByMario);
|
||||||
await loginPage.loginAs(mario);
|
await luigiChat.expectMessageRow(message2ByLuigi);
|
||||||
|
|
||||||
await page.goto(roomURL);
|
|
||||||
|
|
||||||
await chatPage.expectMessageRow(message1ByMario);
|
|
||||||
await chatPage.expectMessageRow(message2ByLuigi);
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export class ChatPage {
|
|||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
readonly messageInput: Locator;
|
readonly messageInput: Locator;
|
||||||
readonly logoutButton: Locator;
|
readonly logoutButton: Locator;
|
||||||
|
readonly usernameInput: Locator;
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.messageInput = page.getByRole("textbox", {
|
this.messageInput = page.getByRole("textbox", {
|
||||||
@@ -13,6 +13,11 @@ export class ChatPage {
|
|||||||
this.logoutButton = page.getByRole("button", {
|
this.logoutButton = page.getByRole("button", {
|
||||||
name: "Log out",
|
name: "Log out",
|
||||||
});
|
});
|
||||||
|
this.usernameInput = page.getByPlaceholder("Set username");
|
||||||
|
}
|
||||||
|
|
||||||
|
async setUsername(username: string) {
|
||||||
|
await this.usernameInput.fill(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendMessage(message: string) {
|
async sendMessage(message: string) {
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
import { Locator, Page, expect } from "@playwright/test";
|
|
||||||
|
|
||||||
export class LoginPage {
|
|
||||||
readonly page: Page;
|
|
||||||
readonly usernameInput: Locator;
|
|
||||||
readonly signupButton: Locator;
|
|
||||||
|
|
||||||
constructor(page: Page) {
|
|
||||||
this.page = page;
|
|
||||||
this.usernameInput = page.getByRole("textbox");
|
|
||||||
this.signupButton = page.getByRole("button", {
|
|
||||||
name: "Sign up",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async goto() {
|
|
||||||
this.page.goto("/");
|
|
||||||
}
|
|
||||||
|
|
||||||
async fillUsername(value: string) {
|
|
||||||
await this.usernameInput.clear();
|
|
||||||
await this.usernameInput.fill(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
async loginAs(value: string) {
|
|
||||||
await this.page
|
|
||||||
.getByRole("button", {
|
|
||||||
name: value,
|
|
||||||
})
|
|
||||||
.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async signup() {
|
|
||||||
await this.signupButton.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async expectLoaded() {
|
|
||||||
await expect(this.signupButton).toBeVisible();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,116 @@
|
|||||||
# minimal-auth-clerk
|
# minimal-auth-clerk
|
||||||
|
|
||||||
|
## 0.0.42
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.22
|
||||||
|
- jazz-react-auth-clerk@0.9.22
|
||||||
|
|
||||||
|
## 0.0.41
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [1be017d]
|
||||||
|
- jazz-tools@0.9.21
|
||||||
|
- jazz-react@0.9.21
|
||||||
|
- jazz-react-auth-clerk@0.9.21
|
||||||
|
|
||||||
|
## 0.0.40
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [b01cc1f]
|
||||||
|
- jazz-tools@0.9.20
|
||||||
|
- jazz-react@0.9.20
|
||||||
|
- jazz-react-auth-clerk@0.9.20
|
||||||
|
|
||||||
|
## 0.0.39
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.19
|
||||||
|
- jazz-react-auth-clerk@0.9.19
|
||||||
|
- jazz-tools@0.9.19
|
||||||
|
|
||||||
|
## 0.0.38
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.18
|
||||||
|
- jazz-react-auth-clerk@0.9.18
|
||||||
|
- jazz-tools@0.9.18
|
||||||
|
|
||||||
|
## 0.0.37
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [c2ca1fe]
|
||||||
|
- Updated dependencies [1227047]
|
||||||
|
- jazz-tools@0.9.17
|
||||||
|
- jazz-react@0.9.17
|
||||||
|
- jazz-react-auth-clerk@0.9.17
|
||||||
|
|
||||||
|
## 0.0.36
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [24b3b6a]
|
||||||
|
- jazz-react-auth-clerk@0.9.16
|
||||||
|
- jazz-tools@0.9.16
|
||||||
|
- jazz-react@0.9.16
|
||||||
|
|
||||||
|
## 0.0.35
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [7491711]
|
||||||
|
- jazz-tools@0.9.15
|
||||||
|
- jazz-react@0.9.15
|
||||||
|
- jazz-react-auth-clerk@0.9.15
|
||||||
|
|
||||||
|
## 0.0.34
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [3df93cc]
|
||||||
|
- jazz-tools@0.9.14
|
||||||
|
- jazz-react@0.9.14
|
||||||
|
- jazz-react-auth-clerk@0.9.14
|
||||||
|
|
||||||
|
## 0.0.33
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.13
|
||||||
|
- jazz-react-auth-clerk@0.9.13
|
||||||
|
- jazz-tools@0.9.13
|
||||||
|
|
||||||
|
## 0.0.32
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.12
|
||||||
|
- jazz-react-auth-clerk@0.9.12
|
||||||
|
- jazz-tools@0.9.12
|
||||||
|
|
||||||
|
## 0.0.31
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.11
|
||||||
|
- jazz-react-auth-clerk@0.9.11
|
||||||
|
- jazz-tools@0.9.11
|
||||||
|
|
||||||
|
## 0.0.30
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [5e83864]
|
||||||
|
- jazz-react@0.9.10
|
||||||
|
- jazz-tools@0.9.10
|
||||||
|
- jazz-react-auth-clerk@0.9.10
|
||||||
|
|
||||||
## 0.0.29
|
## 0.0.29
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -15,11 +15,7 @@ You can either
|
|||||||
|
|
||||||
Create a new Jazz project, and use this 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 create-jazz-app@latest --example clerk --project-name clerk
|
||||||
```
|
|
||||||
or
|
|
||||||
```bash
|
|
||||||
npx create-jazz-app@latest --start clerk --project-name clerk
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Go to the new project directory.
|
Go to the new project directory.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "clerk",
|
"name": "clerk",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.29",
|
"version": "0.0.42",
|
||||||
"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.9",
|
"jazz-react-auth-clerk": "workspace:0.9.22",
|
||||||
"jazz-tools": "workspace:*",
|
"jazz-tools": "workspace:*",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1"
|
"react-dom": "^18.3.1"
|
||||||
|
|||||||
@@ -1,13 +1,25 @@
|
|||||||
import { useAccount } from "jazz-react";
|
import { SignInButton } from "@clerk/clerk-react";
|
||||||
|
import { useAccount, useIsAuthenticated } from "jazz-react";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const { me, logOut } = useAccount();
|
const { me, logOut } = useAccount();
|
||||||
|
|
||||||
|
const isAuthenticated = useIsAuthenticated();
|
||||||
|
|
||||||
|
if (isAuthenticated) {
|
||||||
|
return (
|
||||||
|
<div className="container">
|
||||||
|
<h1>You're logged in</h1>
|
||||||
|
<p>Welcome back, {me?.profile?.name}</p>
|
||||||
|
<button onClick={() => logOut()}>Logout</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<h1>You're logged in</h1>
|
<h1>You're not logged in</h1>
|
||||||
<p>Welcome back, {me?.profile?.name}</p>
|
<SignInButton />
|
||||||
<button onClick={() => logOut()}>Logout</button>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
1
examples/clerk/src/apiKey.ts
Normal file
1
examples/clerk/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const apiKey = "minimal-auth-clerk-example@garden.co";
|
||||||
@@ -62,7 +62,7 @@ button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
max-width: 200px;
|
max-width: 400px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { ClerkProvider, SignInButton, useClerk } from "@clerk/clerk-react";
|
import { ClerkProvider, useClerk } from "@clerk/clerk-react";
|
||||||
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 { JazzProviderWithClerk } from "jazz-react-auth-clerk";
|
||||||
|
import { apiKey } from "./apiKey";
|
||||||
|
|
||||||
// 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,35 +13,28 @@ 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");
|
||||||
}
|
}
|
||||||
|
|
||||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
function JazzProvider({ children }: { children: React.ReactNode }) {
|
||||||
const clerk = useClerk();
|
const clerk = useClerk();
|
||||||
const [auth, state] = useJazzClerkAuth(clerk);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="container">
|
<JazzProviderWithClerk
|
||||||
{state?.errors?.map((error) => (
|
clerk={clerk}
|
||||||
<div key={error}>{error}</div>
|
sync={{
|
||||||
))}
|
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||||
{clerk.user && auth ? (
|
when: "signedUp", // This makes the app work in local mode when the user is not authenticated
|
||||||
<JazzProvider
|
}}
|
||||||
auth={auth}
|
>
|
||||||
peer="wss://cloud.jazz.tools/?key=minimal-auth-clerk-example@garden.co"
|
{children}
|
||||||
>
|
</JazzProviderWithClerk>
|
||||||
{children}
|
|
||||||
</JazzProvider>
|
|
||||||
) : (
|
|
||||||
<SignInButton />
|
|
||||||
)}
|
|
||||||
</main>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
createRoot(document.getElementById("root")!).render(
|
createRoot(document.getElementById("root")!).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<ClerkProvider publishableKey={PUBLISHABLE_KEY} afterSignOutUrl="/">
|
<ClerkProvider publishableKey={PUBLISHABLE_KEY} afterSignOutUrl="/">
|
||||||
<JazzAndAuth>
|
<JazzProvider>
|
||||||
<App />
|
<App />
|
||||||
</JazzAndAuth>
|
</JazzProvider>
|
||||||
</ClerkProvider>
|
</ClerkProvider>
|
||||||
</StrictMode>,
|
</StrictMode>,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,103 @@
|
|||||||
# file-share-svelte
|
# file-share-svelte
|
||||||
|
|
||||||
|
## 0.0.27
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-svelte@0.9.22
|
||||||
|
|
||||||
|
## 0.0.26
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [1be017d]
|
||||||
|
- jazz-tools@0.9.21
|
||||||
|
- jazz-svelte@0.9.21
|
||||||
|
|
||||||
|
## 0.0.25
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [b01cc1f]
|
||||||
|
- jazz-tools@0.9.20
|
||||||
|
- jazz-svelte@0.9.20
|
||||||
|
|
||||||
|
## 0.0.24
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-svelte@0.9.19
|
||||||
|
- jazz-tools@0.9.19
|
||||||
|
|
||||||
|
## 0.0.23
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-svelte@0.9.18
|
||||||
|
- jazz-tools@0.9.18
|
||||||
|
|
||||||
|
## 0.0.22
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [c2ca1fe]
|
||||||
|
- Updated dependencies [1227047]
|
||||||
|
- jazz-tools@0.9.17
|
||||||
|
- jazz-svelte@0.9.17
|
||||||
|
|
||||||
|
## 0.0.21
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [24b3b6a]
|
||||||
|
- jazz-tools@0.9.16
|
||||||
|
- jazz-svelte@0.9.16
|
||||||
|
|
||||||
|
## 0.0.20
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [7491711]
|
||||||
|
- jazz-tools@0.9.15
|
||||||
|
- jazz-svelte@0.9.15
|
||||||
|
|
||||||
|
## 0.0.19
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [3df93cc]
|
||||||
|
- jazz-tools@0.9.14
|
||||||
|
- jazz-svelte@0.9.14
|
||||||
|
|
||||||
|
## 0.0.18
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-svelte@0.9.13
|
||||||
|
- jazz-tools@0.9.13
|
||||||
|
|
||||||
|
## 0.0.17
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-svelte@0.9.12
|
||||||
|
- jazz-tools@0.9.12
|
||||||
|
|
||||||
|
## 0.0.16
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-svelte@0.9.11
|
||||||
|
- jazz-tools@0.9.11
|
||||||
|
|
||||||
|
## 0.0.15
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [5e83864]
|
||||||
|
- jazz-tools@0.9.10
|
||||||
|
- jazz-svelte@0.9.10
|
||||||
|
|
||||||
## 0.0.14
|
## 0.0.14
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "file-share-svelte",
|
"name": "file-share-svelte",
|
||||||
"version": "0.0.14",
|
"version": "0.0.27",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
1
examples/file-share-svelte/src/apiKey.ts
Normal file
1
examples/file-share-svelte/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const apiKey = "file-share-svelte@garden.co"
|
||||||
@@ -17,6 +17,6 @@ export function formatFileSize(bytes: number): string {
|
|||||||
* @param createdAt The creation date
|
* @param createdAt The creation date
|
||||||
* @returns A unique file ID string
|
* @returns A unique file ID string
|
||||||
*/
|
*/
|
||||||
export function generateTempFileId(fileName: string, createdAt: Date): string {
|
export function generateTempFileId(fileName: string | undefined, createdAt: Date | undefined): string {
|
||||||
return `file-${fileName}-${createdAt.getTime()}`;
|
return `file-${fileName ?? 'unknown'}-${createdAt?.getTime() ?? 0}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,9 @@
|
|||||||
import { Toaster } from 'svelte-sonner';
|
import { Toaster } from 'svelte-sonner';
|
||||||
import '../app.css';
|
import '../app.css';
|
||||||
import { FileShareAccount } from '$lib/schema';
|
import { FileShareAccount } from '$lib/schema';
|
||||||
|
import {apiKey} from '../apiKey';
|
||||||
|
|
||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
const auth = usePasskeyAuth({
|
|
||||||
appName: 'File Share'
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@@ -25,21 +23,16 @@
|
|||||||
|
|
||||||
<Toaster richColors />
|
<Toaster richColors />
|
||||||
|
|
||||||
{#if auth.state.state === 'ready'}
|
<JazzProvider
|
||||||
<div class="fixed inset-0 flex items-center justify-center bg-gray-50/80">
|
AccountSchema={FileShareAccount}
|
||||||
<div class="rounded-lg bg-white p-8 shadow-lg">
|
sync={{
|
||||||
<PasskeyAuthBasicUI state={auth.state} />
|
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||||
</div>
|
when: "signedUp",
|
||||||
</div>
|
}}
|
||||||
{/if}
|
>
|
||||||
{#if auth.current}
|
<PasskeyAuthBasicUI appName="File Share">
|
||||||
<JazzProvider
|
|
||||||
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>
|
</PasskeyAuthBasicUI>
|
||||||
{/if}
|
</JazzProvider>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
const input = event.target as HTMLInputElement;
|
const input = event.target as HTMLInputElement;
|
||||||
const files = input.files;
|
const files = input.files;
|
||||||
|
|
||||||
if (!files || !files.length || !me?.root?.sharedFiles || !me.root.publicGroup) return;
|
if (!files || !files.length || !me.root?.sharedFiles || !me.root.publicGroup) return;
|
||||||
|
|
||||||
const file = files[0];
|
const file = files[0];
|
||||||
const fileName = file.name;
|
const fileName = file.name;
|
||||||
@@ -129,12 +129,14 @@
|
|||||||
{#if sharedFiles.current}
|
{#if sharedFiles.current}
|
||||||
{#if !(sharedFiles.current.length === 0 && uploadingFiles.size === 0)}
|
{#if !(sharedFiles.current.length === 0 && uploadingFiles.size === 0)}
|
||||||
{#each [...sharedFiles.current, ...uploadingFiles.values()] as file (generateTempFileId(file?.name, file?.createdAt))}
|
{#each [...sharedFiles.current, ...uploadingFiles.values()] as file (generateTempFileId(file?.name, file?.createdAt))}
|
||||||
<FileItem
|
{#if file}
|
||||||
{file}
|
<FileItem
|
||||||
loading={uploadingFiles.has(generateTempFileId(file?.name, file?.createdAt))}
|
{file}
|
||||||
onShare={shareFile}
|
loading={uploadingFiles.has(generateTempFileId(file?.name, file?.createdAt))}
|
||||||
onDelete={deleteFile}
|
onShare={shareFile}
|
||||||
/>
|
onDelete={deleteFile}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
{:else}
|
{:else}
|
||||||
<p class="text-center text-gray-500">No files yet</p>
|
<p class="text-center text-gray-500">No files yet</p>
|
||||||
|
|||||||
@@ -1,5 +1,116 @@
|
|||||||
# form
|
# form
|
||||||
|
|
||||||
|
## 0.0.38
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-browser-media-images@0.9.22
|
||||||
|
- jazz-react@0.9.22
|
||||||
|
|
||||||
|
## 0.0.37
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [1be017d]
|
||||||
|
- jazz-tools@0.9.21
|
||||||
|
- jazz-browser-media-images@0.9.21
|
||||||
|
- jazz-react@0.9.21
|
||||||
|
|
||||||
|
## 0.0.36
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [b01cc1f]
|
||||||
|
- jazz-tools@0.9.20
|
||||||
|
- jazz-browser-media-images@0.9.20
|
||||||
|
- jazz-react@0.9.20
|
||||||
|
|
||||||
|
## 0.0.35
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.19
|
||||||
|
- jazz-tools@0.9.19
|
||||||
|
- jazz-browser-media-images@0.9.19
|
||||||
|
|
||||||
|
## 0.0.34
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.18
|
||||||
|
- jazz-tools@0.9.18
|
||||||
|
- jazz-browser-media-images@0.9.18
|
||||||
|
|
||||||
|
## 0.0.33
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [c2ca1fe]
|
||||||
|
- Updated dependencies [1227047]
|
||||||
|
- jazz-tools@0.9.17
|
||||||
|
- jazz-browser-media-images@0.9.17
|
||||||
|
- jazz-react@0.9.17
|
||||||
|
|
||||||
|
## 0.0.32
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [24b3b6a]
|
||||||
|
- jazz-tools@0.9.16
|
||||||
|
- jazz-browser-media-images@0.9.16
|
||||||
|
- jazz-react@0.9.16
|
||||||
|
|
||||||
|
## 0.0.31
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [7491711]
|
||||||
|
- jazz-tools@0.9.15
|
||||||
|
- jazz-browser-media-images@0.9.15
|
||||||
|
- jazz-react@0.9.15
|
||||||
|
|
||||||
|
## 0.0.30
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [3df93cc]
|
||||||
|
- jazz-tools@0.9.14
|
||||||
|
- jazz-browser-media-images@0.9.14
|
||||||
|
- jazz-react@0.9.14
|
||||||
|
|
||||||
|
## 0.0.29
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.13
|
||||||
|
- jazz-tools@0.9.13
|
||||||
|
- jazz-browser-media-images@0.9.13
|
||||||
|
|
||||||
|
## 0.0.28
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.12
|
||||||
|
- jazz-tools@0.9.12
|
||||||
|
- jazz-browser-media-images@0.9.12
|
||||||
|
|
||||||
|
## 0.0.27
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.11
|
||||||
|
- jazz-tools@0.9.11
|
||||||
|
- jazz-browser-media-images@0.9.11
|
||||||
|
|
||||||
|
## 0.0.26
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [5e83864]
|
||||||
|
- jazz-react@0.9.10
|
||||||
|
- jazz-tools@0.9.10
|
||||||
|
- jazz-browser-media-images@0.9.10
|
||||||
|
|
||||||
## 0.0.25
|
## 0.0.25
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -28,11 +28,7 @@ You can either
|
|||||||
|
|
||||||
Create a new Jazz project, and use this 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 create-jazz-app@latest --example form --project-name form
|
||||||
```
|
|
||||||
or
|
|
||||||
```bash
|
|
||||||
npx create-jazz-app@latest --start form --project-name form
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Go to the new project directory.
|
Go to the new project directory.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "form",
|
"name": "form",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.25",
|
"version": "0.0.38",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
1
examples/form/src/apiKey.ts
Normal file
1
examples/form/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const apiKey = "form-example@garden.co";
|
||||||
@@ -1,30 +1,11 @@
|
|||||||
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
|
import { JazzProvider } 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 { apiKey } from "./apiKey";
|
||||||
import { JazzAccount } from "./schema.ts";
|
import { JazzAccount } from "./schema.ts";
|
||||||
|
|
||||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
|
||||||
const [auth, authState] = useDemoAuth();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<JazzProvider
|
|
||||||
auth={auth}
|
|
||||||
peer="wss://cloud.jazz.tools/?key=form-example@garden.co"
|
|
||||||
AccountSchema={JazzAccount}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</JazzProvider>
|
|
||||||
|
|
||||||
{authState.state !== "signedIn" && (
|
|
||||||
<DemoAuthBasicUI appName="Form" state={authState} />
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "jazz-react" {
|
declare module "jazz-react" {
|
||||||
interface Register {
|
interface Register {
|
||||||
Account: JazzAccount;
|
Account: JazzAccount;
|
||||||
@@ -33,8 +14,13 @@ declare module "jazz-react" {
|
|||||||
|
|
||||||
createRoot(document.getElementById("root")!).render(
|
createRoot(document.getElementById("root")!).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<JazzAndAuth>
|
<JazzProvider
|
||||||
|
sync={{
|
||||||
|
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||||
|
}}
|
||||||
|
AccountSchema={JazzAccount}
|
||||||
|
>
|
||||||
<App />
|
<App />
|
||||||
</JazzAndAuth>
|
</JazzProvider>
|
||||||
</StrictMode>,
|
</StrictMode>,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "@playwright/test";
|
||||||
import { LoginPage } from "./pages/LoginPage";
|
|
||||||
|
|
||||||
test("create and edit an order", async ({ page }) => {
|
test("create and edit an order", async ({ page }) => {
|
||||||
const loginPage = new LoginPage(page);
|
await page.goto("/");
|
||||||
|
|
||||||
await loginPage.goto();
|
|
||||||
await loginPage.fillUsername("Alice");
|
|
||||||
await loginPage.signup();
|
|
||||||
|
|
||||||
// start an order
|
// start an order
|
||||||
await page.getByRole("link", { name: "Add new order" }).click();
|
await page.getByRole("link", { name: "Add new order" }).click();
|
||||||
await page.getByLabel("Base tea").selectOption("Oolong");
|
await page.getByLabel("Base tea").selectOption("Oolong");
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
import { Locator, Page, expect } from "@playwright/test";
|
|
||||||
|
|
||||||
export class LoginPage {
|
|
||||||
readonly page: Page;
|
|
||||||
readonly usernameInput: Locator;
|
|
||||||
readonly signupButton: Locator;
|
|
||||||
|
|
||||||
constructor(page: Page) {
|
|
||||||
this.page = page;
|
|
||||||
this.usernameInput = page.getByRole("textbox");
|
|
||||||
this.signupButton = page.getByRole("button", {
|
|
||||||
name: "Sign up",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async goto() {
|
|
||||||
this.page.goto("/");
|
|
||||||
}
|
|
||||||
|
|
||||||
async fillUsername(value: string) {
|
|
||||||
await this.usernameInput.clear();
|
|
||||||
await this.usernameInput.fill(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
async loginAs(value: string) {
|
|
||||||
await this.page
|
|
||||||
.getByRole("button", {
|
|
||||||
name: value,
|
|
||||||
})
|
|
||||||
.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async signup() {
|
|
||||||
await this.signupButton.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async expectLoaded() {
|
|
||||||
await expect(this.signupButton).toBeVisible();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,116 @@
|
|||||||
# image-upload
|
# image-upload
|
||||||
|
|
||||||
|
## 0.0.40
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-browser-media-images@0.9.22
|
||||||
|
- jazz-react@0.9.22
|
||||||
|
|
||||||
|
## 0.0.39
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [1be017d]
|
||||||
|
- jazz-tools@0.9.21
|
||||||
|
- jazz-browser-media-images@0.9.21
|
||||||
|
- jazz-react@0.9.21
|
||||||
|
|
||||||
|
## 0.0.38
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [b01cc1f]
|
||||||
|
- jazz-tools@0.9.20
|
||||||
|
- jazz-browser-media-images@0.9.20
|
||||||
|
- jazz-react@0.9.20
|
||||||
|
|
||||||
|
## 0.0.37
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.19
|
||||||
|
- jazz-tools@0.9.19
|
||||||
|
- jazz-browser-media-images@0.9.19
|
||||||
|
|
||||||
|
## 0.0.36
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.18
|
||||||
|
- jazz-tools@0.9.18
|
||||||
|
- jazz-browser-media-images@0.9.18
|
||||||
|
|
||||||
|
## 0.0.35
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [c2ca1fe]
|
||||||
|
- Updated dependencies [1227047]
|
||||||
|
- jazz-tools@0.9.17
|
||||||
|
- jazz-browser-media-images@0.9.17
|
||||||
|
- jazz-react@0.9.17
|
||||||
|
|
||||||
|
## 0.0.34
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [24b3b6a]
|
||||||
|
- jazz-tools@0.9.16
|
||||||
|
- jazz-browser-media-images@0.9.16
|
||||||
|
- jazz-react@0.9.16
|
||||||
|
|
||||||
|
## 0.0.33
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [7491711]
|
||||||
|
- jazz-tools@0.9.15
|
||||||
|
- jazz-browser-media-images@0.9.15
|
||||||
|
- jazz-react@0.9.15
|
||||||
|
|
||||||
|
## 0.0.32
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [3df93cc]
|
||||||
|
- jazz-tools@0.9.14
|
||||||
|
- jazz-browser-media-images@0.9.14
|
||||||
|
- jazz-react@0.9.14
|
||||||
|
|
||||||
|
## 0.0.31
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.13
|
||||||
|
- jazz-tools@0.9.13
|
||||||
|
- jazz-browser-media-images@0.9.13
|
||||||
|
|
||||||
|
## 0.0.30
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.12
|
||||||
|
- jazz-tools@0.9.12
|
||||||
|
- jazz-browser-media-images@0.9.12
|
||||||
|
|
||||||
|
## 0.0.29
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.11
|
||||||
|
- jazz-tools@0.9.11
|
||||||
|
- jazz-browser-media-images@0.9.11
|
||||||
|
|
||||||
|
## 0.0.28
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [5e83864]
|
||||||
|
- jazz-react@0.9.10
|
||||||
|
- jazz-tools@0.9.10
|
||||||
|
- jazz-browser-media-images@0.9.10
|
||||||
|
|
||||||
## 0.0.27
|
## 0.0.27
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -15,10 +15,6 @@ You can either
|
|||||||
|
|
||||||
Create a new Jazz project, and use this 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
|
|
||||||
```
|
|
||||||
or
|
|
||||||
```bash
|
|
||||||
npx create-jazz-app@latest --example image-upload --project-name image-upload
|
npx create-jazz-app@latest --example image-upload --project-name image-upload
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "image-upload",
|
"name": "image-upload",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.27",
|
"version": "0.0.40",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
1
examples/image-upload/src/apiKey.ts
Normal file
1
examples/image-upload/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const apiKey = "image-upload-example@garden.co";
|
||||||
@@ -1,30 +1,11 @@
|
|||||||
import { DemoAuthBasicUI, JazzProvider, useDemoAuth } from "jazz-react";
|
import { JazzProvider } 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 { apiKey } from "./apiKey.ts";
|
||||||
import { JazzAccount } from "./schema.ts";
|
import { JazzAccount } from "./schema.ts";
|
||||||
|
|
||||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
|
||||||
const [auth, authState] = useDemoAuth();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<JazzProvider
|
|
||||||
auth={auth}
|
|
||||||
peer="wss://cloud.jazz.tools/?key=image-upload-example@garden.co"
|
|
||||||
AccountSchema={JazzAccount}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</JazzProvider>
|
|
||||||
|
|
||||||
{authState.state !== "signedIn" && (
|
|
||||||
<DemoAuthBasicUI appName="Image upload" state={authState} />
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "jazz-react" {
|
declare module "jazz-react" {
|
||||||
interface Register {
|
interface Register {
|
||||||
Account: JazzAccount;
|
Account: JazzAccount;
|
||||||
@@ -33,8 +14,13 @@ declare module "jazz-react" {
|
|||||||
|
|
||||||
createRoot(document.getElementById("root")!).render(
|
createRoot(document.getElementById("root")!).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<JazzAndAuth>
|
<JazzProvider
|
||||||
|
sync={{
|
||||||
|
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||||
|
}}
|
||||||
|
AccountSchema={JazzAccount}
|
||||||
|
>
|
||||||
<App />
|
<App />
|
||||||
</JazzAndAuth>
|
</JazzProvider>
|
||||||
</StrictMode>,
|
</StrictMode>,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,61 @@
|
|||||||
# jazz-example-inspector
|
# jazz-example-inspector
|
||||||
|
|
||||||
|
## 0.0.101
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [14b6149]
|
||||||
|
- cojson-transport-ws@0.9.22
|
||||||
|
|
||||||
|
## 0.0.100
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [6ad0a9f]
|
||||||
|
- cojson@0.9.19
|
||||||
|
- cojson-transport-ws@0.9.19
|
||||||
|
|
||||||
|
## 0.0.99
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [8898b10]
|
||||||
|
- cojson@0.9.18
|
||||||
|
- cojson-transport-ws@0.9.18
|
||||||
|
|
||||||
|
## 0.0.98
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [8d29e50]
|
||||||
|
- cojson-transport-ws@0.9.13
|
||||||
|
- cojson@0.9.13
|
||||||
|
|
||||||
|
## 0.0.97
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [15d4b2a]
|
||||||
|
- cojson-transport-ws@0.9.12
|
||||||
|
- cojson@0.9.12
|
||||||
|
|
||||||
|
## 0.0.96
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [efbf3d8]
|
||||||
|
- Updated dependencies [5863bad]
|
||||||
|
- cojson@0.9.11
|
||||||
|
- cojson-transport-ws@0.9.11
|
||||||
|
|
||||||
|
## 0.0.95
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [4aa377d]
|
||||||
|
- cojson@0.9.10
|
||||||
|
- cojson-transport-ws@0.9.10
|
||||||
|
|
||||||
## 0.0.94
|
## 0.0.94
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "jazz-inspector",
|
"name": "jazz-inspector-app",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.94",
|
"version": "0.0.101",
|
||||||
"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.9",
|
"cojson": "workspace:0.9.19",
|
||||||
"cojson-transport-ws": "workspace:0.9.9",
|
"cojson-transport-ws": "workspace:0.9.22",
|
||||||
"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",
|
||||||
|
|||||||
1
examples/inspector/src/apiKey.ts
Normal file
1
examples/inspector/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const apiKey = "";
|
||||||
@@ -1,5 +1,121 @@
|
|||||||
# jazz-example-musicplayer
|
# jazz-example-musicplayer
|
||||||
|
|
||||||
|
## 0.0.64
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.22
|
||||||
|
|
||||||
|
## 0.0.63
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [1be017d]
|
||||||
|
- jazz-tools@0.9.21
|
||||||
|
- jazz-inspector@0.9.22
|
||||||
|
- jazz-react@0.9.21
|
||||||
|
|
||||||
|
## 0.0.62
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [b01cc1f]
|
||||||
|
- jazz-tools@0.9.20
|
||||||
|
- jazz-inspector@0.9.21
|
||||||
|
- jazz-react@0.9.20
|
||||||
|
|
||||||
|
## 0.0.61
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-inspector@0.9.20
|
||||||
|
- jazz-react@0.9.19
|
||||||
|
- jazz-tools@0.9.19
|
||||||
|
|
||||||
|
## 0.0.60
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [2faf22f]
|
||||||
|
- jazz-inspector@0.9.19
|
||||||
|
|
||||||
|
## 0.0.59
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-inspector@0.9.18
|
||||||
|
- jazz-react@0.9.18
|
||||||
|
- jazz-tools@0.9.18
|
||||||
|
|
||||||
|
## 0.0.58
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [c2ca1fe]
|
||||||
|
- Updated dependencies [1227047]
|
||||||
|
- jazz-tools@0.9.17
|
||||||
|
- jazz-inspector@0.9.17
|
||||||
|
- jazz-react@0.9.17
|
||||||
|
|
||||||
|
## 0.0.57
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [24b3b6a]
|
||||||
|
- jazz-tools@0.9.16
|
||||||
|
- jazz-inspector@0.9.16
|
||||||
|
- jazz-react@0.9.16
|
||||||
|
|
||||||
|
## 0.0.56
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [7491711]
|
||||||
|
- jazz-tools@0.9.15
|
||||||
|
- jazz-inspector@0.9.15
|
||||||
|
- jazz-react@0.9.15
|
||||||
|
|
||||||
|
## 0.0.55
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [3df93cc]
|
||||||
|
- jazz-tools@0.9.14
|
||||||
|
- jazz-inspector@0.9.14
|
||||||
|
- jazz-react@0.9.14
|
||||||
|
|
||||||
|
## 0.0.54
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-inspector@0.9.13
|
||||||
|
- jazz-react@0.9.13
|
||||||
|
- jazz-tools@0.9.13
|
||||||
|
|
||||||
|
## 0.0.53
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-inspector@0.9.12
|
||||||
|
- jazz-react@0.9.12
|
||||||
|
- jazz-tools@0.9.12
|
||||||
|
|
||||||
|
## 0.0.52
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-inspector@0.9.11
|
||||||
|
- jazz-react@0.9.11
|
||||||
|
- jazz-tools@0.9.11
|
||||||
|
|
||||||
|
## 0.0.51
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [5e83864]
|
||||||
|
- jazz-react@0.9.10
|
||||||
|
- jazz-tools@0.9.10
|
||||||
|
|
||||||
## 0.0.50
|
## 0.0.50
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -13,10 +13,6 @@ You can either
|
|||||||
|
|
||||||
Create a new Jazz project, and use this 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
|
|
||||||
```
|
|
||||||
or
|
|
||||||
```bash
|
|
||||||
npx create-jazz-app@latest --example music-player --project-name music-player
|
npx create-jazz-app@latest --example music-player --project-name music-player
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "jazz-example-music-player",
|
"name": "jazz-example-music-player",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.50",
|
"version": "0.0.64",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
@@ -13,13 +13,17 @@
|
|||||||
"test:ui": "playwright test --ui"
|
"test:ui": "playwright test --ui"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@radix-ui/react-dialog": "^1.1.4",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-label": "^2.1.1",
|
||||||
|
"@radix-ui/react-slot": "^1.1.1",
|
||||||
"@radix-ui/react-toast": "^1.1.4",
|
"@radix-ui/react-toast": "^1.1.4",
|
||||||
|
"@radix-ui/react-tooltip": "^1.1.6",
|
||||||
"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.9",
|
"jazz-react": "workspace:0.9.22",
|
||||||
"jazz-tools": "workspace:0.9.9",
|
"jazz-tools": "workspace:0.9.21",
|
||||||
|
"jazz-inspector": "workspace:*",
|
||||||
"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",
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ export class MusicTrack extends CoMap {
|
|||||||
*/
|
*/
|
||||||
file = co.ref(FileStream);
|
file = co.ref(FileStream);
|
||||||
waveform = co.ref(MusicTrackWaveform);
|
waveform = co.ref(MusicTrackWaveform);
|
||||||
|
|
||||||
|
isExampleTrack = co.optional.boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MusicTrackWaveform extends CoMap {
|
export class MusicTrackWaveform extends CoMap {
|
||||||
@@ -86,28 +88,20 @@ export class MusicaAccount extends Account {
|
|||||||
* You can use it to set up the account root and any other initial CoValues you need.
|
* You can use it to set up the account root and any other initial CoValues you need.
|
||||||
*/
|
*/
|
||||||
migrate() {
|
migrate() {
|
||||||
if (!this._refs.root) {
|
if (this.root === undefined) {
|
||||||
const ownership = { owner: this };
|
const tracks = ListOfTracks.create([]);
|
||||||
|
const rootPlaylist = Playlist.create({
|
||||||
|
tracks,
|
||||||
|
title: "",
|
||||||
|
});
|
||||||
|
|
||||||
const tracks = ListOfTracks.create([], ownership);
|
this.root = MusicaAccountRoot.create({
|
||||||
const rootPlaylist = Playlist.create(
|
rootPlaylist,
|
||||||
{
|
playlists: ListOfPlaylists.create([]),
|
||||||
tracks,
|
activeTrack: null,
|
||||||
title: "",
|
activePlaylist: rootPlaylist,
|
||||||
},
|
exampleDataLoaded: false,
|
||||||
ownership,
|
});
|
||||||
);
|
|
||||||
|
|
||||||
this.root = MusicaAccountRoot.create(
|
|
||||||
{
|
|
||||||
rootPlaylist,
|
|
||||||
playlists: ListOfPlaylists.create([], ownership),
|
|
||||||
activeTrack: null,
|
|
||||||
activePlaylist: rootPlaylist,
|
|
||||||
exampleDataLoaded: false,
|
|
||||||
},
|
|
||||||
ownership,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Toaster } from "@/components/ui/toaster";
|
import { Toaster } from "@/components/ui/toaster";
|
||||||
|
import { JazzInspector } from "jazz-inspector";
|
||||||
/* eslint-disable react-refresh/only-export-components */
|
/* eslint-disable react-refresh/only-export-components */
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
@@ -10,7 +11,9 @@ 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 { apiKey } from "@/apiKey.ts";
|
||||||
|
import { JazzProvider } from "jazz-react";
|
||||||
|
import { onAnonymousUserDiscarded } from "./4_actions";
|
||||||
import { useUploadExampleData } from "./lib/useUploadExampleData";
|
import { useUploadExampleData } from "./lib/useUploadExampleData";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,29 +56,10 @@ function Main() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
const peer =
|
||||||
const [auth, state] = useDemoAuth();
|
(new URL(window.location.href).searchParams.get(
|
||||||
|
"peer",
|
||||||
const peer =
|
) as `ws://${string}`) ?? `wss://cloud.jazz.tools/?key=${apiKey}`;
|
||||||
(new URL(window.location.href).searchParams.get(
|
|
||||||
"peer",
|
|
||||||
) as `ws://${string}`) ??
|
|
||||||
"wss://cloud.jazz.tools/?key=music-player-example-jazz@garden.co";
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<JazzProvider
|
|
||||||
storage="indexedDB"
|
|
||||||
auth={auth}
|
|
||||||
peer={peer}
|
|
||||||
AccountSchema={MusicaAccount}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</JazzProvider>
|
|
||||||
<DemoAuthBasicUI appName="Jazz Music Player" state={state} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "jazz-react" {
|
declare module "jazz-react" {
|
||||||
interface Register {
|
interface Register {
|
||||||
@@ -85,8 +69,18 @@ declare module "jazz-react" {
|
|||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<JazzAndAuth>
|
<JazzProvider
|
||||||
|
sync={{
|
||||||
|
peer,
|
||||||
|
when: "signedUp", // This makes the app work in local mode when the user is anonymous
|
||||||
|
}}
|
||||||
|
storage="indexedDB"
|
||||||
|
AccountSchema={MusicaAccount}
|
||||||
|
defaultProfileName="Anonymous unicorn"
|
||||||
|
onAnonymousUserDiscarded={onAnonymousUserDiscarded}
|
||||||
|
>
|
||||||
<Main />
|
<Main />
|
||||||
</JazzAndAuth>
|
<JazzInspector />
|
||||||
|
</JazzProvider>
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
import { useToast } from "@/hooks/use-toast";
|
import { useToast } from "@/hooks/use-toast";
|
||||||
import { createInviteLink, useAccount, useCoState } from "jazz-react";
|
import {
|
||||||
|
createInviteLink,
|
||||||
|
useAccount,
|
||||||
|
useCoState,
|
||||||
|
useIsAuthenticated,
|
||||||
|
} from "jazz-react";
|
||||||
import { ID } from "jazz-tools";
|
import { 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 { createNewPlaylist, uploadMusicTracks } from "./4_actions";
|
import { createNewPlaylist, uploadMusicTracks } from "./4_actions";
|
||||||
import { MediaPlayer } from "./5_useMediaPlayer";
|
import { MediaPlayer } from "./5_useMediaPlayer";
|
||||||
|
import { AuthButton } from "./components/AuthButton";
|
||||||
import { FileUploadButton } from "./components/FileUploadButton";
|
import { FileUploadButton } from "./components/FileUploadButton";
|
||||||
import { LogoutButton } from "./components/LogoutButton";
|
|
||||||
import { MusicTrackRow } from "./components/MusicTrackRow";
|
import { MusicTrackRow } from "./components/MusicTrackRow";
|
||||||
import { PlaylistTitleInput } from "./components/PlaylistTitleInput";
|
import { PlaylistTitleInput } from "./components/PlaylistTitleInput";
|
||||||
import { SidePanel } from "./components/SidePanel";
|
import { SidePanel } from "./components/SidePanel";
|
||||||
@@ -66,6 +71,8 @@ export function HomePage({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isAuthenticated = useIsAuthenticated();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col h-screen text-gray-800 bg-blue-50">
|
<div className="flex flex-col h-screen text-gray-800 bg-blue-50">
|
||||||
<div className="flex flex-1 overflow-hidden">
|
<div className="flex flex-1 overflow-hidden">
|
||||||
@@ -86,12 +93,12 @@ export function HomePage({ mediaPlayer }: { mediaPlayer: MediaPlayer }) {
|
|||||||
<Button onClick={handleCreatePlaylist}>New playlist</Button>
|
<Button onClick={handleCreatePlaylist}>New playlist</Button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{!isRootPlaylist && (
|
{!isRootPlaylist && isAuthenticated && (
|
||||||
<Button onClick={handlePlaylistShareClick}>
|
<Button onClick={handlePlaylistShareClick}>
|
||||||
Share playlist
|
Share playlist
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<LogoutButton />
|
<AuthButton />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul className="flex flex-col">
|
<ul className="flex flex-col">
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ import {
|
|||||||
* pattern that best fits your app.
|
* pattern that best fits your app.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export async function uploadMusicTracks(files: Iterable<File>) {
|
export async function uploadMusicTracks(
|
||||||
|
files: Iterable<File>,
|
||||||
|
isExampleTrack: boolean = false,
|
||||||
|
) {
|
||||||
const me = await MusicaAccount.getMe().ensureLoaded({
|
const me = await MusicaAccount.getMe().ensureLoaded({
|
||||||
root: {
|
root: {
|
||||||
rootPlaylist: {
|
rootPlaylist: {
|
||||||
@@ -52,6 +55,7 @@ export async function uploadMusicTracks(files: Iterable<File>) {
|
|||||||
duration: data.duration,
|
duration: data.duration,
|
||||||
waveform: MusicTrackWaveform.create({ data: data.waveform }, group),
|
waveform: MusicTrackWaveform.create({ data: data.waveform }, group),
|
||||||
title: file.name,
|
title: file.name,
|
||||||
|
isExampleTrack,
|
||||||
},
|
},
|
||||||
group,
|
group,
|
||||||
);
|
);
|
||||||
@@ -173,3 +177,39 @@ export async function updateActiveTrack(track: MusicTrack) {
|
|||||||
|
|
||||||
me.root.activeTrack = track;
|
me.root.activeTrack = track;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function onAnonymousUserDiscarded(
|
||||||
|
anonymousAccount: MusicaAccount,
|
||||||
|
) {
|
||||||
|
const anonymousAccountWithPlaylist = await anonymousAccount.ensureLoaded({
|
||||||
|
root: {
|
||||||
|
rootPlaylist: {
|
||||||
|
tracks: [{}],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!anonymousAccountWithPlaylist)
|
||||||
|
throw new Error("Unable to load anonymous account with playlist");
|
||||||
|
|
||||||
|
const me = await MusicaAccount.getMe().ensureLoaded({
|
||||||
|
root: {
|
||||||
|
rootPlaylist: {
|
||||||
|
tracks: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!me) throw new Error("Me not resolved");
|
||||||
|
|
||||||
|
const rootPlaylist = anonymousAccountWithPlaylist.root.rootPlaylist;
|
||||||
|
|
||||||
|
for (const track of rootPlaylist.tracks) {
|
||||||
|
if (track.isExampleTrack) continue;
|
||||||
|
|
||||||
|
const trackGroup = track._owner.castAs(Group);
|
||||||
|
await trackGroup.addMember(me, "admin");
|
||||||
|
|
||||||
|
me.root.rootPlaylist.tracks.push(track);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
1
examples/music-player/src/apiKey.ts
Normal file
1
examples/music-player/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const apiKey = "music-player-example-jazz@garden.co";
|
||||||
40
examples/music-player/src/components/AuthButton.tsx
Normal file
40
examples/music-player/src/components/AuthButton.tsx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { useAccount, useIsAuthenticated } from "jazz-react";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { AuthModal } from "./AuthModal";
|
||||||
|
|
||||||
|
export function AuthButton() {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const { logOut } = useAccount();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const isAuthenticated = useIsAuthenticated();
|
||||||
|
|
||||||
|
function handleSignOut() {
|
||||||
|
logOut();
|
||||||
|
navigate("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAuthenticated) {
|
||||||
|
return (
|
||||||
|
<Button variant="outline" onClick={handleSignOut}>
|
||||||
|
Sign out
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
onClick={() => setOpen(true)}
|
||||||
|
className="bg-white text-black hover:bg-gray-100"
|
||||||
|
>
|
||||||
|
Sign up
|
||||||
|
</Button>
|
||||||
|
<AuthModal open={open} onOpenChange={setOpen} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
116
examples/music-player/src/components/AuthModal.tsx
Normal file
116
examples/music-player/src/components/AuthModal.tsx
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
import { useAccount, usePasskeyAuth } from "jazz-react";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
interface AuthModalProps {
|
||||||
|
open: boolean;
|
||||||
|
onOpenChange: (open: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AuthModal({ open, onOpenChange }: AuthModalProps) {
|
||||||
|
const [username, setUsername] = useState("");
|
||||||
|
const [isSignUp, setIsSignUp] = useState(true);
|
||||||
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
|
const { me } = useAccount({
|
||||||
|
root: {
|
||||||
|
rootPlaylist: {
|
||||||
|
tracks: [{}],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const auth = usePasskeyAuth({
|
||||||
|
appName: "Jazz Music Player",
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleViewChange = () => {
|
||||||
|
setIsSignUp(!isSignUp);
|
||||||
|
setError(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (isSignUp) {
|
||||||
|
await auth.signUp(username);
|
||||||
|
} else {
|
||||||
|
await auth.logIn();
|
||||||
|
}
|
||||||
|
onOpenChange(false);
|
||||||
|
} catch (error) {
|
||||||
|
setError(error instanceof Error ? error.message : "Unknown error");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const shouldShowTransferRootPlaylist =
|
||||||
|
!isSignUp &&
|
||||||
|
me?.root.rootPlaylist.tracks.some((track) => !track.isExampleTrack);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||||
|
<DialogContent className="sm:max-w-[425px]">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle className="text-2xl font-bold">
|
||||||
|
{isSignUp ? "Create account" : "Welcome back"}
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
{isSignUp
|
||||||
|
? "Sign up to enable network sync and share your playlists with others"
|
||||||
|
: "Changes done before logging in will be lost"}
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<form onSubmit={handleSubmit} className="space-y-4">
|
||||||
|
{isSignUp && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="username">Username</Label>
|
||||||
|
<Input
|
||||||
|
id="username"
|
||||||
|
value={username}
|
||||||
|
onChange={(e) => setUsername(e.target.value)}
|
||||||
|
placeholder="Enter your username"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{error && <div className="text-sm text-red-500">{error}</div>}
|
||||||
|
{shouldShowTransferRootPlaylist && (
|
||||||
|
<div className="text-sm text-red-500">
|
||||||
|
You have tracks in your root playlist that are not example tracks.
|
||||||
|
If you log in with a passkey, your playlists will be transferred
|
||||||
|
to your logged account.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
className="w-full bg-blue-600 hover:bg-blue-700"
|
||||||
|
>
|
||||||
|
{isSignUp ? "Sign up with passkey" : "Login with passkey"}
|
||||||
|
</Button>
|
||||||
|
<div className="text-center text-sm">
|
||||||
|
{isSignUp ? "Already have an account?" : "Don't have an account?"}{" "}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleViewChange}
|
||||||
|
className="text-blue-600 hover:underline"
|
||||||
|
>
|
||||||
|
{isSignUp ? "Login" : "Sign up"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
37
examples/music-player/src/components/LocalOnlyTag.tsx
Normal file
37
examples/music-player/src/components/LocalOnlyTag.tsx
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import {
|
||||||
|
Tooltip,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipProvider,
|
||||||
|
TooltipTrigger,
|
||||||
|
} from "@/components/ui/tooltip";
|
||||||
|
import { useIsAuthenticated } from "jazz-react";
|
||||||
|
import { Info } from "lucide-react";
|
||||||
|
|
||||||
|
export function LocalOnlyTag() {
|
||||||
|
const isAuthenticated = useIsAuthenticated();
|
||||||
|
|
||||||
|
if (isAuthenticated) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div className="inline-flex items-center gap-1.5 cursor-help">
|
||||||
|
<Badge variant="default" className="h-5 text-xs font-normal">
|
||||||
|
Local only
|
||||||
|
</Badge>
|
||||||
|
<Info className="h-3.5 w-3.5 text-muted-foreground" />
|
||||||
|
</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent className="max-w-[250px]">
|
||||||
|
<p>
|
||||||
|
Sign up to enable network sync and share your playlists with others
|
||||||
|
</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useAccount } from "jazz-react";
|
import { useAccount } from "jazz-react";
|
||||||
import { useNavigate, useParams } from "react-router";
|
import { useNavigate, useParams } from "react-router";
|
||||||
|
import { LocalOnlyTag } from "./LocalOnlyTag";
|
||||||
|
|
||||||
export function SidePanel() {
|
export function SidePanel() {
|
||||||
const { playlistId } = useParams();
|
const { playlistId } = useParams();
|
||||||
@@ -25,7 +26,7 @@ export function SidePanel() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className="w-64 p-6 bg-white overflow-y-auto">
|
<aside className="w-64 p-6 bg-white overflow-y-auto">
|
||||||
<div className="flex items-center mb-6">
|
<div className="flex items-center mb-1">
|
||||||
<svg
|
<svg
|
||||||
className="w-8 h-8 mr-2"
|
className="w-8 h-8 mr-2"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@@ -46,6 +47,9 @@ export function SidePanel() {
|
|||||||
</svg>
|
</svg>
|
||||||
<span className="text-xl font-bold text-blue-600">Music Player</span>
|
<span className="text-xl font-bold text-blue-600">Music Player</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mb-6">
|
||||||
|
<LocalOnlyTag />
|
||||||
|
</div>
|
||||||
<nav>
|
<nav>
|
||||||
<h2 className="mb-2 text-sm font-semibold text-gray-600">Playlists</h2>
|
<h2 className="mb-2 text-sm font-semibold text-gray-600">Playlists</h2>
|
||||||
<ul className="space-y-1">
|
<ul className="space-y-1">
|
||||||
|
|||||||
36
examples/music-player/src/components/ui/badge.tsx
Normal file
36
examples/music-player/src/components/ui/badge.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { type VariantProps, cva } from "class-variance-authority";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const badgeVariants = cva(
|
||||||
|
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||||
|
{
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
default:
|
||||||
|
"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
|
||||||
|
secondary:
|
||||||
|
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||||
|
destructive:
|
||||||
|
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
||||||
|
outline: "text-foreground",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: "default",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export interface BadgeProps
|
||||||
|
extends React.HTMLAttributes<HTMLDivElement>,
|
||||||
|
VariantProps<typeof badgeVariants> {}
|
||||||
|
|
||||||
|
function Badge({ className, variant, ...props }: BadgeProps) {
|
||||||
|
return (
|
||||||
|
<div className={cn(badgeVariants({ variant }), className)} {...props} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Badge, badgeVariants };
|
||||||
120
examples/music-player/src/components/ui/dialog.tsx
Normal file
120
examples/music-player/src/components/ui/dialog.tsx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||||
|
import { X } from "lucide-react";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const Dialog = DialogPrimitive.Root;
|
||||||
|
|
||||||
|
const DialogTrigger = DialogPrimitive.Trigger;
|
||||||
|
|
||||||
|
const DialogPortal = DialogPrimitive.Portal;
|
||||||
|
|
||||||
|
const DialogClose = DialogPrimitive.Close;
|
||||||
|
|
||||||
|
const DialogOverlay = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Overlay>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DialogPrimitive.Overlay
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
||||||
|
|
||||||
|
const DialogContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<DialogPortal>
|
||||||
|
<DialogOverlay />
|
||||||
|
<DialogPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||||
|
<X className="h-4 w-4" />
|
||||||
|
<span className="sr-only">Close</span>
|
||||||
|
</DialogPrimitive.Close>
|
||||||
|
</DialogPrimitive.Content>
|
||||||
|
</DialogPortal>
|
||||||
|
));
|
||||||
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
||||||
|
|
||||||
|
const DialogHeader = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"flex flex-col space-y-1.5 text-center sm:text-left",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
DialogHeader.displayName = "DialogHeader";
|
||||||
|
|
||||||
|
const DialogFooter = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
DialogFooter.displayName = "DialogFooter";
|
||||||
|
|
||||||
|
const DialogTitle = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Title>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DialogPrimitive.Title
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-lg font-semibold leading-none tracking-tight",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
||||||
|
|
||||||
|
const DialogDescription = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Description>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DialogPrimitive.Description
|
||||||
|
ref={ref}
|
||||||
|
className={cn("text-sm text-muted-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
||||||
|
|
||||||
|
export {
|
||||||
|
Dialog,
|
||||||
|
DialogPortal,
|
||||||
|
DialogOverlay,
|
||||||
|
DialogClose,
|
||||||
|
DialogTrigger,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogFooter,
|
||||||
|
DialogTitle,
|
||||||
|
DialogDescription,
|
||||||
|
};
|
||||||
22
examples/music-player/src/components/ui/input.tsx
Normal file
22
examples/music-player/src/components/ui/input.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
|
||||||
|
({ className, type, ...props }, ref) => {
|
||||||
|
return (
|
||||||
|
<input
|
||||||
|
type={type}
|
||||||
|
className={cn(
|
||||||
|
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
ref={ref}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
Input.displayName = "Input";
|
||||||
|
|
||||||
|
export { Input };
|
||||||
24
examples/music-player/src/components/ui/label.tsx
Normal file
24
examples/music-player/src/components/ui/label.tsx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import * as LabelPrimitive from "@radix-ui/react-label";
|
||||||
|
import { type VariantProps, cva } from "class-variance-authority";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const labelVariants = cva(
|
||||||
|
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||||
|
);
|
||||||
|
|
||||||
|
const Label = React.forwardRef<
|
||||||
|
React.ElementRef<typeof LabelPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
|
||||||
|
VariantProps<typeof labelVariants>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<LabelPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn(labelVariants(), className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
Label.displayName = LabelPrimitive.Root.displayName;
|
||||||
|
|
||||||
|
export { Label };
|
||||||
30
examples/music-player/src/components/ui/tooltip.tsx
Normal file
30
examples/music-player/src/components/ui/tooltip.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const TooltipProvider = TooltipPrimitive.Provider;
|
||||||
|
|
||||||
|
const Tooltip = TooltipPrimitive.Root;
|
||||||
|
|
||||||
|
const TooltipTrigger = TooltipPrimitive.Trigger;
|
||||||
|
|
||||||
|
const TooltipContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof TooltipPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
|
||||||
|
>(({ className, sideOffset = 4, ...props }, ref) => (
|
||||||
|
<TooltipPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
sideOffset={sideOffset}
|
||||||
|
className={cn(
|
||||||
|
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
||||||
|
|
||||||
|
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
import { MusicaAccount } from "@/1_schema";
|
import { MusicaAccount } from "@/1_schema";
|
||||||
|
import { useAccount } from "jazz-react";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { uploadMusicTracks } from "../4_actions";
|
import { uploadMusicTracks } from "../4_actions";
|
||||||
|
|
||||||
export function useUploadExampleData() {
|
export function useUploadExampleData() {
|
||||||
|
const { me } = useAccount();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
uploadOnboardingData();
|
uploadOnboardingData();
|
||||||
}, []);
|
}, [me.id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function uploadOnboardingData() {
|
async function uploadOnboardingData() {
|
||||||
@@ -22,7 +25,7 @@ async function uploadOnboardingData() {
|
|||||||
try {
|
try {
|
||||||
const trackFile = await (await fetch("/example.mp3")).blob();
|
const trackFile = await (await fetch("/example.mp3")).blob();
|
||||||
|
|
||||||
await uploadMusicTracks([new File([trackFile], "Example song")]);
|
await uploadMusicTracks([new File([trackFile], "Example song")], true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
me.root.exampleDataLoaded = false;
|
me.root.exampleDataLoaded = false;
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
@@ -1,44 +1,84 @@
|
|||||||
import { test } from "@playwright/test";
|
import { BrowserContext, test } from "@playwright/test";
|
||||||
import { HomePage } from "./pages/HomePage";
|
import { HomePage } from "./pages/HomePage";
|
||||||
import { LoginPage } from "./pages/LoginPage";
|
|
||||||
|
|
||||||
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
|
||||||
test("create a new playlist and share", async ({ page }) => {
|
async function mockAuthenticator(context: BrowserContext) {
|
||||||
const loginPage = new LoginPage(page);
|
await context.addInitScript(() => {
|
||||||
|
Object.defineProperty(window.navigator, "credentials", {
|
||||||
|
value: {
|
||||||
|
...window.navigator.credentials,
|
||||||
|
create: async () => ({
|
||||||
|
type: "public-key",
|
||||||
|
id: new Uint8Array([1, 2, 3, 4]),
|
||||||
|
rawId: new Uint8Array([1, 2, 3, 4]),
|
||||||
|
response: {
|
||||||
|
clientDataJSON: new Uint8Array([1]),
|
||||||
|
attestationObject: new Uint8Array([2]),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
get: async () => ({
|
||||||
|
type: "public-key",
|
||||||
|
id: new Uint8Array([1, 2, 3, 4]),
|
||||||
|
rawId: new Uint8Array([1, 2, 3, 4]),
|
||||||
|
response: {
|
||||||
|
authenticatorData: new Uint8Array([1]),
|
||||||
|
clientDataJSON: new Uint8Array([2]),
|
||||||
|
signature: new Uint8Array([3]),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
await loginPage.goto();
|
// Configure the authenticator
|
||||||
await loginPage.fillUsername("S. Mario");
|
test.beforeEach(async ({ context }) => {
|
||||||
await loginPage.signup();
|
// Enable virtual authenticator environment
|
||||||
|
await mockAuthenticator(context);
|
||||||
|
});
|
||||||
|
|
||||||
const homePage = new HomePage(page);
|
test("create a new playlist and share", async ({
|
||||||
|
page: marioPage,
|
||||||
|
browser,
|
||||||
|
}) => {
|
||||||
|
await marioPage.goto("/");
|
||||||
|
|
||||||
|
const marioHome = new HomePage(marioPage);
|
||||||
|
|
||||||
// The example song should be loaded
|
// The example song should be loaded
|
||||||
await homePage.expectMusicTrack("Example song");
|
await marioHome.expectMusicTrack("Example song");
|
||||||
await homePage.editTrackTitle("Example song", "Super Mario World");
|
await marioHome.editTrackTitle("Example song", "Super Mario World");
|
||||||
|
|
||||||
await homePage.createPlaylist();
|
await marioHome.createPlaylist();
|
||||||
await homePage.editPlaylistTitle("Save the princess");
|
await marioHome.editPlaylistTitle("Save the princess");
|
||||||
|
|
||||||
await homePage.navigateToPlaylist("All tracks");
|
await marioHome.navigateToPlaylist("All tracks");
|
||||||
await homePage.addTrackToPlaylist("Super Mario World", "Save the princess");
|
await marioHome.addTrackToPlaylist("Super Mario World", "Save the princess");
|
||||||
|
|
||||||
await homePage.navigateToPlaylist("Save the princess");
|
await marioHome.navigateToPlaylist("Save the princess");
|
||||||
await homePage.expectMusicTrack("Super Mario World");
|
await marioHome.expectMusicTrack("Super Mario World");
|
||||||
|
|
||||||
const url = await homePage.getShareLink();
|
await marioHome.signUp("Mario");
|
||||||
|
|
||||||
|
const url = await marioHome.getShareLink();
|
||||||
|
|
||||||
await sleep(4000); // Wait for the sync to complete
|
await sleep(4000); // Wait for the sync to complete
|
||||||
|
|
||||||
await homePage.logout();
|
const luigiContext = await browser.newContext();
|
||||||
|
await mockAuthenticator(luigiContext);
|
||||||
|
|
||||||
await loginPage.goto();
|
const luigiPage = await luigiContext.newPage();
|
||||||
await loginPage.fillUsername("Luigi");
|
await luigiPage.goto("/");
|
||||||
await loginPage.signup();
|
|
||||||
|
|
||||||
await page.goto(url);
|
const luigiHome = new HomePage(luigiPage);
|
||||||
|
|
||||||
await homePage.expectMusicTrack("Super Mario World");
|
await luigiHome.signUp("Luigi");
|
||||||
await homePage.playMusicTrack("Super Mario World");
|
|
||||||
await homePage.expectActiveTrackPlaying();
|
await luigiPage.goto(url);
|
||||||
|
|
||||||
|
await luigiHome.expectMusicTrack("Super Mario World");
|
||||||
|
await luigiHome.playMusicTrack("Super Mario World");
|
||||||
|
await luigiHome.expectActiveTrackPlaying();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -95,6 +95,17 @@ export class HomePage {
|
|||||||
.click();
|
.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async signUp(name: string) {
|
||||||
|
await this.page.getByRole("button", { name: "Sign up" }).click();
|
||||||
|
await this.page.getByRole("textbox", { name: "Username" }).fill(name);
|
||||||
|
await this.page
|
||||||
|
.getByRole("button", { name: "Sign up with passkey" })
|
||||||
|
.click();
|
||||||
|
await expect(
|
||||||
|
this.page.getByRole("button", { name: "Sign out" }),
|
||||||
|
).toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
async logout() {
|
async logout() {
|
||||||
await this.logoutButton.click();
|
await this.logoutButton.click();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
import { Locator, Page, expect } from "@playwright/test";
|
|
||||||
|
|
||||||
export class LoginPage {
|
|
||||||
readonly page: Page;
|
|
||||||
readonly usernameInput: Locator;
|
|
||||||
readonly signupButton: Locator;
|
|
||||||
|
|
||||||
constructor(page: Page) {
|
|
||||||
this.page = page;
|
|
||||||
this.usernameInput = page.getByRole("textbox");
|
|
||||||
this.signupButton = page.getByRole("button", {
|
|
||||||
name: "Sign up",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async goto() {
|
|
||||||
this.page.goto("/");
|
|
||||||
}
|
|
||||||
|
|
||||||
async fillUsername(value: string) {
|
|
||||||
await this.usernameInput.clear();
|
|
||||||
await this.usernameInput.fill(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
async loginAs(value: string) {
|
|
||||||
await this.page
|
|
||||||
.getByRole("button", {
|
|
||||||
name: value,
|
|
||||||
})
|
|
||||||
.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async signup() {
|
|
||||||
await this.signupButton.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async expectLoaded() {
|
|
||||||
await expect(this.signupButton).toBeVisible();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,116 @@
|
|||||||
# jazz-example-onboarding
|
# jazz-example-onboarding
|
||||||
|
|
||||||
|
## 0.0.44
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-browser-media-images@0.9.22
|
||||||
|
- jazz-react@0.9.22
|
||||||
|
|
||||||
|
## 0.0.43
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [1be017d]
|
||||||
|
- jazz-tools@0.9.21
|
||||||
|
- jazz-browser-media-images@0.9.21
|
||||||
|
- jazz-react@0.9.21
|
||||||
|
|
||||||
|
## 0.0.42
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [b01cc1f]
|
||||||
|
- jazz-tools@0.9.20
|
||||||
|
- jazz-browser-media-images@0.9.20
|
||||||
|
- jazz-react@0.9.20
|
||||||
|
|
||||||
|
## 0.0.41
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.19
|
||||||
|
- jazz-tools@0.9.19
|
||||||
|
- jazz-browser-media-images@0.9.19
|
||||||
|
|
||||||
|
## 0.0.40
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.18
|
||||||
|
- jazz-tools@0.9.18
|
||||||
|
- jazz-browser-media-images@0.9.18
|
||||||
|
|
||||||
|
## 0.0.39
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [c2ca1fe]
|
||||||
|
- Updated dependencies [1227047]
|
||||||
|
- jazz-tools@0.9.17
|
||||||
|
- jazz-browser-media-images@0.9.17
|
||||||
|
- jazz-react@0.9.17
|
||||||
|
|
||||||
|
## 0.0.38
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [24b3b6a]
|
||||||
|
- jazz-tools@0.9.16
|
||||||
|
- jazz-browser-media-images@0.9.16
|
||||||
|
- jazz-react@0.9.16
|
||||||
|
|
||||||
|
## 0.0.37
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [7491711]
|
||||||
|
- jazz-tools@0.9.15
|
||||||
|
- jazz-browser-media-images@0.9.15
|
||||||
|
- jazz-react@0.9.15
|
||||||
|
|
||||||
|
## 0.0.36
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [3df93cc]
|
||||||
|
- jazz-tools@0.9.14
|
||||||
|
- jazz-browser-media-images@0.9.14
|
||||||
|
- jazz-react@0.9.14
|
||||||
|
|
||||||
|
## 0.0.35
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.13
|
||||||
|
- jazz-tools@0.9.13
|
||||||
|
- jazz-browser-media-images@0.9.13
|
||||||
|
|
||||||
|
## 0.0.34
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.12
|
||||||
|
- jazz-tools@0.9.12
|
||||||
|
- jazz-browser-media-images@0.9.12
|
||||||
|
|
||||||
|
## 0.0.33
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.11
|
||||||
|
- jazz-tools@0.9.11
|
||||||
|
- jazz-browser-media-images@0.9.11
|
||||||
|
|
||||||
|
## 0.0.32
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [5e83864]
|
||||||
|
- jazz-react@0.9.10
|
||||||
|
- jazz-tools@0.9.10
|
||||||
|
- jazz-browser-media-images@0.9.10
|
||||||
|
|
||||||
## 0.0.31
|
## 0.0.31
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -11,10 +11,6 @@ You can either
|
|||||||
|
|
||||||
Create a new Jazz project, and use this 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
|
|
||||||
```
|
|
||||||
or
|
|
||||||
```bash
|
|
||||||
npx create-jazz-app@latest --example onboarding --project-name onboarding
|
npx create-jazz-app@latest --example onboarding --project-name onboarding
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "jazz-example-onboarding",
|
"name": "jazz-example-onboarding",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.31",
|
"version": "0.0.44",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
1
examples/onboarding/src/apiKey.ts
Normal file
1
examples/onboarding/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const apiKey = "onboarding-example-jazz@garden.co";
|
||||||
@@ -1,29 +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 { JazzProvider } from "jazz-react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
|
import { apiKey } from "./apiKey";
|
||||||
|
|
||||||
const peer =
|
const peer =
|
||||||
(new URL(window.location.href).searchParams.get(
|
(new URL(window.location.href).searchParams.get(
|
||||||
"peer",
|
"peer",
|
||||||
) as `ws://${string}`) ??
|
) as `ws://${string}`) ?? `wss://cloud.jazz.tools/?key=${apiKey}`;
|
||||||
"wss://cloud.jazz.tools/?key=onboarding-example-jazz@garden.co";
|
|
||||||
|
|
||||||
function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
|
||||||
const [auth, authState] = useDemoAuth();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<JazzProvider AccountSchema={HRAccount} auth={auth} peer={peer}>
|
|
||||||
{children}
|
|
||||||
</JazzProvider>
|
|
||||||
{authState.state !== "signedIn" && (
|
|
||||||
<DemoAuthBasicUI appName="Jazz Onboarding" state={authState} />
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "jazz-react" {
|
declare module "jazz-react" {
|
||||||
interface Register {
|
interface Register {
|
||||||
@@ -33,8 +19,13 @@ declare module "jazz-react" {
|
|||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<JazzAndAuth>
|
<JazzProvider
|
||||||
|
AccountSchema={HRAccount}
|
||||||
|
sync={{
|
||||||
|
peer,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<App />
|
<App />
|
||||||
</JazzAndAuth>
|
</JazzProvider>
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -16,25 +16,6 @@ async function scrollToBottom(page: Page) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const login = async ({
|
|
||||||
page,
|
|
||||||
userName,
|
|
||||||
loginAs = false,
|
|
||||||
}: {
|
|
||||||
page: Page;
|
|
||||||
userName: string;
|
|
||||||
loginAs?: boolean;
|
|
||||||
}) => {
|
|
||||||
const loginPage = new LoginPage(page);
|
|
||||||
await loginPage.goto("/");
|
|
||||||
if (loginAs) {
|
|
||||||
await loginPage.loginAs(userName);
|
|
||||||
} else {
|
|
||||||
await loginPage.fillUsername(userName);
|
|
||||||
await loginPage.signup();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
test.describe("Admin onboarding flow", () => {
|
test.describe("Admin onboarding flow", () => {
|
||||||
let browser: Browser;
|
let browser: Browser;
|
||||||
let adminContext: BrowserContext;
|
let adminContext: BrowserContext;
|
||||||
@@ -54,7 +35,7 @@ test.describe("Admin onboarding flow", () => {
|
|||||||
|
|
||||||
test("Create and delete flow", async () => {
|
test("Create and delete flow", async () => {
|
||||||
const adminPage = await adminContext.newPage();
|
const adminPage = await adminContext.newPage();
|
||||||
await login({ page: adminPage, userName: "HR specialist" });
|
await adminPage.goto("/");
|
||||||
const adminHomePage = new HomePage(adminPage);
|
const adminHomePage = new HomePage(adminPage);
|
||||||
await adminHomePage.createEmployee("Paul");
|
await adminHomePage.createEmployee("Paul");
|
||||||
await adminHomePage.createEmployee("Sean");
|
await adminHomePage.createEmployee("Sean");
|
||||||
@@ -70,10 +51,8 @@ test.describe("Admin onboarding flow", () => {
|
|||||||
const adminPage = await adminContext.newPage();
|
const adminPage = await adminContext.newPage();
|
||||||
const writerPage = await writerContext.newPage();
|
const writerPage = await writerContext.newPage();
|
||||||
|
|
||||||
const adminUser = "HR specialist";
|
await adminPage.goto("/");
|
||||||
const writerUser = "Invitee";
|
await writerPage.goto("/");
|
||||||
await login({ page: adminPage, userName: adminUser });
|
|
||||||
await login({ page: writerPage, userName: writerUser });
|
|
||||||
|
|
||||||
const adminHomePage = new HomePage(adminPage);
|
const adminHomePage = new HomePage(adminPage);
|
||||||
await adminHomePage.createEmployee("Paul");
|
await adminHomePage.createEmployee("Paul");
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// vite.config.ts
|
||||||
|
import path from "path";
|
||||||
|
import react from "file:///Users/brad/dev/jazz/node_modules/@vitejs/plugin-react-swc/index.mjs";
|
||||||
|
import topLevelAwait from "file:///Users/brad/dev/jazz/node_modules/vite-plugin-top-level-await/exports/import.mjs";
|
||||||
|
import { defineConfig } from "file:///Users/brad/dev/jazz/node_modules/vite/dist/node/index.js";
|
||||||
|
var __vite_injected_original_dirname =
|
||||||
|
"/Users/brad/dev/jazz/examples/onboarding";
|
||||||
|
var vite_config_default = defineConfig({
|
||||||
|
plugins: [react(), topLevelAwait()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@": path.resolve(__vite_injected_original_dirname, "./src"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
minify: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export { vite_config_default as default };
|
||||||
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvVXNlcnMvYnJhZC9kZXYvamF6ei9leGFtcGxlcy9vbmJvYXJkaW5nXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCIvVXNlcnMvYnJhZC9kZXYvamF6ei9leGFtcGxlcy9vbmJvYXJkaW5nL3ZpdGUuY29uZmlnLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9Vc2Vycy9icmFkL2Rldi9qYXp6L2V4YW1wbGVzL29uYm9hcmRpbmcvdml0ZS5jb25maWcudHNcIjtpbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHJlYWN0IGZyb20gXCJAdml0ZWpzL3BsdWdpbi1yZWFjdC1zd2NcIjtcbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gXCJ2aXRlXCI7XG5pbXBvcnQgdG9wTGV2ZWxBd2FpdCBmcm9tIFwidml0ZS1wbHVnaW4tdG9wLWxldmVsLWF3YWl0XCI7XG5cbi8vIGh0dHBzOi8vdml0ZWpzLmRldi9jb25maWcvXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xuICBwbHVnaW5zOiBbcmVhY3QoKSwgdG9wTGV2ZWxBd2FpdCgpXSxcbiAgcmVzb2x2ZToge1xuICAgIGFsaWFzOiB7XG4gICAgICBcIkBcIjogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgXCIuL3NyY1wiKSxcbiAgICB9LFxuICB9LFxuICBidWlsZDoge1xuICAgIG1pbmlmeTogZmFsc2UsXG4gIH0sXG59KTtcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBMFMsT0FBTyxVQUFVO0FBQzNULE9BQU8sV0FBVztBQUNsQixTQUFTLG9CQUFvQjtBQUM3QixPQUFPLG1CQUFtQjtBQUgxQixJQUFNLG1DQUFtQztBQU16QyxJQUFPLHNCQUFRLGFBQWE7QUFBQSxFQUMxQixTQUFTLENBQUMsTUFBTSxHQUFHLGNBQWMsQ0FBQztBQUFBLEVBQ2xDLFNBQVM7QUFBQSxJQUNQLE9BQU87QUFBQSxNQUNMLEtBQUssS0FBSyxRQUFRLGtDQUFXLE9BQU87QUFBQSxJQUN0QztBQUFBLEVBQ0Y7QUFBQSxFQUNBLE9BQU87QUFBQSxJQUNMLFFBQVE7QUFBQSxFQUNWO0FBQ0YsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
|
||||||
@@ -1,5 +1,103 @@
|
|||||||
# organization
|
# organization
|
||||||
|
|
||||||
|
## 0.0.36
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.22
|
||||||
|
|
||||||
|
## 0.0.35
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [1be017d]
|
||||||
|
- jazz-tools@0.9.21
|
||||||
|
- jazz-react@0.9.21
|
||||||
|
|
||||||
|
## 0.0.34
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [b01cc1f]
|
||||||
|
- jazz-tools@0.9.20
|
||||||
|
- jazz-react@0.9.20
|
||||||
|
|
||||||
|
## 0.0.33
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.19
|
||||||
|
- jazz-tools@0.9.19
|
||||||
|
|
||||||
|
## 0.0.32
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.18
|
||||||
|
- jazz-tools@0.9.18
|
||||||
|
|
||||||
|
## 0.0.31
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [c2ca1fe]
|
||||||
|
- Updated dependencies [1227047]
|
||||||
|
- jazz-tools@0.9.17
|
||||||
|
- jazz-react@0.9.17
|
||||||
|
|
||||||
|
## 0.0.30
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [24b3b6a]
|
||||||
|
- jazz-tools@0.9.16
|
||||||
|
- jazz-react@0.9.16
|
||||||
|
|
||||||
|
## 0.0.29
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [7491711]
|
||||||
|
- jazz-tools@0.9.15
|
||||||
|
- jazz-react@0.9.15
|
||||||
|
|
||||||
|
## 0.0.28
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [3df93cc]
|
||||||
|
- jazz-tools@0.9.14
|
||||||
|
- jazz-react@0.9.14
|
||||||
|
|
||||||
|
## 0.0.27
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.13
|
||||||
|
- jazz-tools@0.9.13
|
||||||
|
|
||||||
|
## 0.0.26
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.12
|
||||||
|
- jazz-tools@0.9.12
|
||||||
|
|
||||||
|
## 0.0.25
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- jazz-react@0.9.11
|
||||||
|
- jazz-tools@0.9.11
|
||||||
|
|
||||||
|
## 0.0.24
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [5e83864]
|
||||||
|
- jazz-react@0.9.10
|
||||||
|
- jazz-tools@0.9.10
|
||||||
|
|
||||||
## 0.0.23
|
## 0.0.23
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user