Compare commits
533 Commits
jazz-react
...
cojson-sto
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66b5f8d4c8 | ||
|
|
9c6ca9e864 | ||
|
|
858386b5b1 | ||
|
|
f45af0a5cf | ||
|
|
22af329930 | ||
|
|
fc342306e2 | ||
|
|
8e4a9c7211 | ||
|
|
362284f6b7 | ||
|
|
975c7bc785 | ||
|
|
9a1295d4f6 | ||
|
|
256fdfd0db | ||
|
|
4cf2bf5fef | ||
|
|
cae74bd051 | ||
|
|
05a3786e23 | ||
|
|
0fa051a59d | ||
|
|
1378a1ff68 | ||
|
|
5ad093cb6a | ||
|
|
98407c2314 | ||
|
|
65e14c6176 | ||
|
|
9fa79b3a5f | ||
|
|
c90222d32e | ||
|
|
d084b41929 | ||
|
|
65e78014fa | ||
|
|
d693800eb3 | ||
|
|
4ab0b1f4b2 | ||
|
|
9157effdb3 | ||
|
|
30b2820a8c | ||
|
|
bb561e2650 | ||
|
|
7cdf397a01 | ||
|
|
44116b805b | ||
|
|
e93c27910d | ||
|
|
16428cace4 | ||
|
|
f48dabaa1a | ||
|
|
7ff90cb81e | ||
|
|
3a53cc4c00 | ||
|
|
ea6c50b2b8 | ||
|
|
6d93f7b388 | ||
|
|
ebc0139559 | ||
|
|
01c07e34e4 | ||
|
|
c89b94aa3b | ||
|
|
01e2977a13 | ||
|
|
41354cb2c1 | ||
|
|
530f9d3e11 | ||
|
|
c965c904bc | ||
|
|
d527ae2db0 | ||
|
|
b9261aa4c1 | ||
|
|
41dd1fa80b | ||
|
|
469ac44ff5 | ||
|
|
ea0045580c | ||
|
|
b84bf1826b | ||
|
|
a4fb2edfc2 | ||
|
|
06c5a1c2ba | ||
|
|
b85423b39f | ||
|
|
b698ffbf45 | ||
|
|
a026073c41 | ||
|
|
5763c684c5 | ||
|
|
a82b216901 | ||
|
|
f20182b1cc | ||
|
|
ef4fdff4fc | ||
|
|
0f5e22f522 | ||
|
|
fc71d4548c | ||
|
|
f5c90d875f | ||
|
|
65963fffc8 | ||
|
|
7f09bc9475 | ||
|
|
d97956e5db | ||
|
|
38e0e3f29b | ||
|
|
2526e88cd1 | ||
|
|
5360000f61 | ||
|
|
ca638e4d92 | ||
|
|
594d68e9ee | ||
|
|
de1ea09ec5 | ||
|
|
cf30fbd575 | ||
|
|
598e669705 | ||
|
|
e4ed11cd9d | ||
|
|
e74a077823 | ||
|
|
680a2e2b99 | ||
|
|
861d7b88f8 | ||
|
|
e35a380d16 | ||
|
|
08b1601dd1 | ||
|
|
d413df4864 | ||
|
|
b897e950bb | ||
|
|
69c92ab908 | ||
|
|
b177b09724 | ||
|
|
3110459530 | ||
|
|
f66ed45460 | ||
|
|
10e1612fd4 | ||
|
|
282a2798c7 | ||
|
|
31b89adb03 | ||
|
|
793787bc66 | ||
|
|
9cbbd55eef | ||
|
|
17710122af | ||
|
|
e4e3e173da | ||
|
|
9a438a05ae | ||
|
|
fb126b8194 | ||
|
|
a58ca736ec | ||
|
|
39d916aeff | ||
|
|
554dd8e6e6 | ||
|
|
8d8cb77316 | ||
|
|
4c615ba5c2 | ||
|
|
30dc4a8caa | ||
|
|
ffdad97a32 | ||
|
|
f548199027 | ||
|
|
9fecaee697 | ||
|
|
f3409d8575 | ||
|
|
1173884769 | ||
|
|
1c40b3fd6d | ||
|
|
8b66c92c46 | ||
|
|
dd60538ea2 | ||
|
|
8a7aab8520 | ||
|
|
d3fc467514 | ||
|
|
6d1bd2b70a | ||
|
|
6e79c8679e | ||
|
|
222a8c2976 | ||
|
|
5b7f02024e | ||
|
|
4b94b25a11 | ||
|
|
a99df9cb13 | ||
|
|
d359a4f491 | ||
|
|
588d7f41a2 | ||
|
|
1951d0f5b1 | ||
|
|
3ffb74d170 | ||
|
|
597545741b | ||
|
|
5e42e2a8d8 | ||
|
|
19e2a61398 | ||
|
|
cb5fe3380e | ||
|
|
5b06a9d0a7 | ||
|
|
41c4fbb8f9 | ||
|
|
95febc7777 | ||
|
|
7ddff0a550 | ||
|
|
cebc58cd3a | ||
|
|
044626fbc8 | ||
|
|
28fdc43c89 | ||
|
|
2602a49f12 | ||
|
|
8505b0a0b6 | ||
|
|
f2418ff364 | ||
|
|
c81a49ebc3 | ||
|
|
3cd07dca31 | ||
|
|
f69707f1af | ||
|
|
57e748d2ba | ||
|
|
c0cfdc0d32 | ||
|
|
3763a99e14 | ||
|
|
201e2fd015 | ||
|
|
3e743d56d3 | ||
|
|
b3ff726794 | ||
|
|
f98f88d89b | ||
|
|
56974412df | ||
|
|
adaedd2da2 | ||
|
|
a11472a497 | ||
|
|
3f269c7483 | ||
|
|
81b6b8fd04 | ||
|
|
2939790335 | ||
|
|
7e4ba07c4c | ||
|
|
48c29435bc | ||
|
|
8668906376 | ||
|
|
6d84e9e83f | ||
|
|
1fea0ef69c | ||
|
|
e4314accb6 | ||
|
|
ee3a4048ef | ||
|
|
9ee1edef3b | ||
|
|
8ab5a09a86 | ||
|
|
2624442903 | ||
|
|
2d199089d5 | ||
|
|
683c170b9d | ||
|
|
ce0e9f0102 | ||
|
|
518406e23d | ||
|
|
4dcbafa058 | ||
|
|
7ae9e01848 | ||
|
|
dd9ecf660d | ||
|
|
4f849050dc | ||
|
|
7591ac1f7e | ||
|
|
681600220f | ||
|
|
384e239ad5 | ||
|
|
54e1a09a46 | ||
|
|
392a9c5aac | ||
|
|
7f9b82a975 | ||
|
|
5f65ca0874 | ||
|
|
5a88024420 | ||
|
|
bf025724aa | ||
|
|
478334eabf | ||
|
|
479f9b0113 | ||
|
|
812622b161 | ||
|
|
8b35fae4b6 | ||
|
|
9e2ecb0378 | ||
|
|
fe908b5300 | ||
|
|
1f99807971 | ||
|
|
47f54c4d81 | ||
|
|
814f65acaf | ||
|
|
78fd4c86a1 | ||
|
|
678f326bc1 | ||
|
|
ea33ad4864 | ||
|
|
57b6d5efb4 | ||
|
|
15929b121d | ||
|
|
6edd061202 | ||
|
|
eb4cef196c | ||
|
|
85703f9241 | ||
|
|
865d5385e9 | ||
|
|
5bb12523ee | ||
|
|
190cb1efb2 | ||
|
|
46ab1f6db2 | ||
|
|
a44fc6fc6d | ||
|
|
2376a8d3b2 | ||
|
|
2c3ec2fea6 | ||
|
|
da6f6ec4d5 | ||
|
|
8c78b37bfb | ||
|
|
5f382309de | ||
|
|
aa7eb3cf2c | ||
|
|
9b41762e96 | ||
|
|
28be460286 | ||
|
|
df8af06814 | ||
|
|
2ef460fccf | ||
|
|
9660e2c03c | ||
|
|
908645e4b7 | ||
|
|
f3ca37ed5e | ||
|
|
a9d0fd14c4 | ||
|
|
c496f49bb0 | ||
|
|
b26666ab4c | ||
|
|
9088a349a0 | ||
|
|
54b12dcb7a | ||
|
|
a998f94789 | ||
|
|
d17eecfe16 | ||
|
|
71b9a5ce25 | ||
|
|
8ebfbc86db | ||
|
|
abad8e762f | ||
|
|
037e16392e | ||
|
|
49ac65c123 | ||
|
|
3510fb1273 | ||
|
|
bc3efe7ca0 | ||
|
|
3b06a7809e | ||
|
|
58aa04bb10 | ||
|
|
afb94ef043 | ||
|
|
7554dd9f88 | ||
|
|
7a3cfabb4c | ||
|
|
df7101a8ee | ||
|
|
f74b46ee2f | ||
|
|
9177579f53 | ||
|
|
f1c00903f9 | ||
|
|
1ca9299590 | ||
|
|
4f0fb6c27f | ||
|
|
34082ccaf5 | ||
|
|
a09c417d81 | ||
|
|
034bd20b39 | ||
|
|
00a188c22f | ||
|
|
dc630b0807 | ||
|
|
484baabe22 | ||
|
|
f529bede7b | ||
|
|
87f82ac7cd | ||
|
|
6f637d21ab | ||
|
|
aeb96510da | ||
|
|
d53cc3676d | ||
|
|
81dedb6395 | ||
|
|
17cb04bfb1 | ||
|
|
a98b4e5d81 | ||
|
|
7eb7e2f656 | ||
|
|
80703ea1cc | ||
|
|
d46e0b9d0c | ||
|
|
430a9e252a | ||
|
|
6f519462df | ||
|
|
a0ae2811ce | ||
|
|
73e5a3548a | ||
|
|
c5da3a42a1 | ||
|
|
74fa115709 | ||
|
|
baa5278cf3 | ||
|
|
6852b60e72 | ||
|
|
fc2b054fc2 | ||
|
|
048ac1d54f | ||
|
|
4ed7d61ea4 | ||
|
|
ced325da06 | ||
|
|
5563799a2a | ||
|
|
5a783f8eac | ||
|
|
0ea1530ee9 | ||
|
|
164579ee9c | ||
|
|
fc453e68c1 | ||
|
|
48544ca4d1 | ||
|
|
b2e2b91dd7 | ||
|
|
36d7791326 | ||
|
|
707d84dea0 | ||
|
|
6da8e3948c | ||
|
|
225da5ca42 | ||
|
|
3943f7fc41 | ||
|
|
d982bb50db | ||
|
|
92de0a6683 | ||
|
|
e10d00b444 | ||
|
|
89b6c1cbb9 | ||
|
|
6ec1933d65 | ||
|
|
854c6761a4 | ||
|
|
fc8acb0688 | ||
|
|
7a65b35ac5 | ||
|
|
2ef3938d71 | ||
|
|
1e71b23779 | ||
|
|
31071a4b21 | ||
|
|
8f53a52110 | ||
|
|
08b105508f | ||
|
|
f567b3d24b | ||
|
|
dd750fc6e8 | ||
|
|
814d99e0bc | ||
|
|
0eb70c2171 | ||
|
|
64e787a57f | ||
|
|
1e8c3df83e | ||
|
|
5013b1d97d | ||
|
|
c4837b9b92 | ||
|
|
e527cb676b | ||
|
|
2c75c46029 | ||
|
|
f92f65cc28 | ||
|
|
d88a94bc68 | ||
|
|
e9bf27467f | ||
|
|
c9bd778c03 | ||
|
|
c3832ad794 | ||
|
|
9b807cbba9 | ||
|
|
32fd3cab19 | ||
|
|
7502dba11b | ||
|
|
e9baf69126 | ||
|
|
f597d64423 | ||
|
|
5c8ce99ab5 | ||
|
|
679ca6c36b | ||
|
|
e6130219fe | ||
|
|
046075288b | ||
|
|
57fa927640 | ||
|
|
8ef14d4850 | ||
|
|
1a7b7942ad | ||
|
|
5f42c97184 | ||
|
|
2a2b474aa4 | ||
|
|
b45bf9248e | ||
|
|
6c2b8a8f8f | ||
|
|
7be49602dd | ||
|
|
cb73d474a6 | ||
|
|
cd03cb77f5 | ||
|
|
d9d5662b7a | ||
|
|
39cd197494 | ||
|
|
5397fb27bc | ||
|
|
f0bfdc3f5f | ||
|
|
5f45036e2a | ||
|
|
20eab19676 | ||
|
|
6af2feb2e7 | ||
|
|
60df32ba05 | ||
|
|
90f36e61d6 | ||
|
|
2d27cd5356 | ||
|
|
0262b9d501 | ||
|
|
115e22c89d | ||
|
|
687d9bbbff | ||
|
|
56ad6379d9 | ||
|
|
481ffa1d96 | ||
|
|
a383c7e984 | ||
|
|
8ca283147d | ||
|
|
c3d87796ed | ||
|
|
cb88caced9 | ||
|
|
6313ead62d | ||
|
|
f674910aa9 | ||
|
|
37fc25f5a6 | ||
|
|
5e9c338c27 | ||
|
|
4b61f7c7a5 | ||
|
|
1c8472ffbd | ||
|
|
9dba68ac36 | ||
|
|
13b57aa576 | ||
|
|
aedf0f3ac5 | ||
|
|
7fa61644b0 | ||
|
|
dbc6342222 | ||
|
|
12389c82f9 | ||
|
|
4c03a17d3a | ||
|
|
5d1ea45a9c | ||
|
|
780961d46f | ||
|
|
cc0479afe0 | ||
|
|
c102f18b62 | ||
|
|
57fb69fa6f | ||
|
|
8985e2d4ff | ||
|
|
cfb6786468 | ||
|
|
5662faa9c0 | ||
|
|
3e7d9cb585 | ||
|
|
ec65ba74a8 | ||
|
|
f679e6b392 | ||
|
|
3bcaa81c17 | ||
|
|
2116a598ae | ||
|
|
8a00392894 | ||
|
|
f3f2e85c53 | ||
|
|
0ff08e9893 | ||
|
|
ca517517f9 | ||
|
|
55bdbbf12e | ||
|
|
5c7a7d0f7c | ||
|
|
af388c11d5 | ||
|
|
df255f850f | ||
|
|
d14a069a12 | ||
|
|
aacef80994 | ||
|
|
2a237e5d32 | ||
|
|
0fe30eca0b | ||
|
|
dea7a8dfd9 | ||
|
|
ab7191bed0 | ||
|
|
901b7c0a51 | ||
|
|
17bea5975c | ||
|
|
e005ecd0a1 | ||
|
|
e7e505e5f3 | ||
|
|
d6ffe03d3c | ||
|
|
1120747a24 | ||
|
|
1e2d7d1c4e | ||
|
|
e26f110acd | ||
|
|
28f84a4ee6 | ||
|
|
cffe4abb84 | ||
|
|
2e0b7cee8c | ||
|
|
d3b47f59e8 | ||
|
|
aea3287965 | ||
|
|
6525f8a12e | ||
|
|
fe4c934a4b | ||
|
|
60261c8dba | ||
|
|
7411049faa | ||
|
|
356b06559b | ||
|
|
193738cfe2 | ||
|
|
ddb74fa167 | ||
|
|
aca5642671 | ||
|
|
a5bed20c4a | ||
|
|
09bf53a8d3 | ||
|
|
061ec996b1 | ||
|
|
a7ee0465b5 | ||
|
|
e995d8a1fe | ||
|
|
5ccb48446e | ||
|
|
04b20c2e42 | ||
|
|
7aae2441a1 | ||
|
|
650e95a528 | ||
|
|
3d80ab11d9 | ||
|
|
85e6489a3e | ||
|
|
45b6c87ade | ||
|
|
edadc4b986 | ||
|
|
455b722357 | ||
|
|
ad2e1d1e98 | ||
|
|
7c94b70c31 | ||
|
|
74bcf1752e | ||
|
|
97a54b3911 | ||
|
|
c393c8880f | ||
|
|
359157fa70 | ||
|
|
62d9680449 | ||
|
|
db6067439d | ||
|
|
5051d6a410 | ||
|
|
25efaf30f5 | ||
|
|
98aadd9842 | ||
|
|
d555b18c11 | ||
|
|
550111f8a1 | ||
|
|
3d4a00a19d | ||
|
|
d06c6677dc | ||
|
|
ce30f3c4ff | ||
|
|
1072b9c2fe | ||
|
|
5ea41c69ef | ||
|
|
2d8eed3b69 | ||
|
|
45c9c8558f | ||
|
|
dccb80edf0 | ||
|
|
6f72419b6e | ||
|
|
fc55e5c8e8 | ||
|
|
4a74ccf399 | ||
|
|
a442315995 | ||
|
|
0d5ee3ed07 | ||
|
|
4e32cae8a7 | ||
|
|
49d721a29b | ||
|
|
2c6d27598d | ||
|
|
e637cb0700 | ||
|
|
c42848ece9 | ||
|
|
841a818dff | ||
|
|
f74881a3fe | ||
|
|
c559054378 | ||
|
|
d6d9c0adcb | ||
|
|
cdf9b5a71c | ||
|
|
4b950bce14 | ||
|
|
8343d8f0fe | ||
|
|
eeb280f17b | ||
|
|
a927334b40 | ||
|
|
be0c1bcda5 | ||
|
|
b861daca60 | ||
|
|
b4cd307eba | ||
|
|
1d0e83d3fa | ||
|
|
be7c4c29a1 | ||
|
|
ffa4db0b61 | ||
|
|
7daf992c51 | ||
|
|
333c583265 | ||
|
|
fa2227716f | ||
|
|
bfa5e14112 | ||
|
|
38dabd4602 | ||
|
|
dcdf89bba7 | ||
|
|
a6e6939015 | ||
|
|
71aa24054d | ||
|
|
4c88421440 | ||
|
|
64bad01d9a | ||
|
|
4dfa809a77 | ||
|
|
726df167f8 | ||
|
|
2f62cbde13 | ||
|
|
93ef74219d | ||
|
|
495aa81335 | ||
|
|
99caaba328 | ||
|
|
4bfcc787a1 | ||
|
|
7e96eb12dd | ||
|
|
a71eba2eb5 | ||
|
|
b129cf9328 | ||
|
|
a6e31c41b7 | ||
|
|
47746ff9ba | ||
|
|
4e4319a546 | ||
|
|
d1de8baf1d | ||
|
|
d427a2a13c | ||
|
|
1fa6c3987a | ||
|
|
ddf49e532f | ||
|
|
bf9312ad15 | ||
|
|
b54eac6484 | ||
|
|
156167e6d7 | ||
|
|
aef84cf2ef | ||
|
|
275a26e2c1 | ||
|
|
946ae63070 | ||
|
|
5cfe47ebbe | ||
|
|
6ee0ec755e | ||
|
|
8ffca202bd | ||
|
|
6d2bcc7490 | ||
|
|
69709c2cf2 | ||
|
|
e7733a5428 | ||
|
|
286b17431a | ||
|
|
e8c1a3535a | ||
|
|
b05878962b | ||
|
|
54b4595f23 | ||
|
|
99a2d9be00 | ||
|
|
bf1fbdc8c4 | ||
|
|
7c88b2c55d | ||
|
|
14b3aa29c7 | ||
|
|
bfaadb9d67 | ||
|
|
cb770e565d | ||
|
|
15190250e5 | ||
|
|
a50a9e6c9b | ||
|
|
b8f91dcb9d | ||
|
|
23f5879b54 | ||
|
|
f882b68490 | ||
|
|
ce149eba76 | ||
|
|
41d3a5c755 | ||
|
|
e88252bee4 | ||
|
|
a6b7857f6f | ||
|
|
265c30158e | ||
|
|
505e132f1e | ||
|
|
c6d5195cb5 | ||
|
|
8af543e7d6 | ||
|
|
016b2098a7 | ||
|
|
bb67d6c5fd | ||
|
|
60bf6f0a7a | ||
|
|
4683cc7ada | ||
|
|
83765a8509 | ||
|
|
be8ac6fc70 |
@@ -2,35 +2,20 @@
|
||||
"$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json",
|
||||
"changelog": "@changesets/cli/changelog",
|
||||
"commit": false,
|
||||
"fixed": [],
|
||||
"linked": [
|
||||
"linked": [],
|
||||
"fixed": [
|
||||
[
|
||||
"cojson",
|
||||
"cojson-storage",
|
||||
"cojson-storage-indexeddb",
|
||||
"cojson-storage-sqlite",
|
||||
"cojson-transport-ws",
|
||||
"jazz-browser",
|
||||
"jazz-auth-clerk",
|
||||
"jazz-auth-betterauth",
|
||||
"jazz-betterauth-client-plugin",
|
||||
"jazz-betterauth-server-plugin",
|
||||
"jazz-react-auth-betterauth",
|
||||
"jazz-browser-media-images",
|
||||
"jazz-expo",
|
||||
"jazz-inspector",
|
||||
"jazz-inspector-element",
|
||||
"jazz-nodejs",
|
||||
"jazz-react",
|
||||
"jazz-react-core",
|
||||
"jazz-react-auth-clerk",
|
||||
"jazz-react-native-core",
|
||||
"jazz-react-native",
|
||||
"jazz-react-native-media-images",
|
||||
"jazz-run",
|
||||
"jazz-svelte",
|
||||
"jazz-tools",
|
||||
"jazz-vue"
|
||||
"jazz-tools"
|
||||
]
|
||||
],
|
||||
"access": "public",
|
||||
|
||||
37
.github/workflows/build-examples.yaml
vendored
37
.github/workflows/build-examples.yaml
vendored
@@ -1,37 +0,0 @@
|
||||
name: Build Examples
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
|
||||
jobs:
|
||||
build-examples:
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
strategy:
|
||||
matrix:
|
||||
example: [
|
||||
"chat",
|
||||
"clerk",
|
||||
"passkey",
|
||||
"inspector",
|
||||
"music-player",
|
||||
"password-manager",
|
||||
"pets",
|
||||
"reactions",
|
||||
"todo",
|
||||
]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup Source Code
|
||||
uses: ./.github/actions/source-code/
|
||||
|
||||
- name: Pnpm Build
|
||||
run: |
|
||||
pnpm install
|
||||
pnpm turbo build;
|
||||
working-directory: ./examples/${{ matrix.example }}
|
||||
26
.github/workflows/build-starters.yaml
vendored
26
.github/workflows/build-starters.yaml
vendored
@@ -1,26 +0,0 @@
|
||||
name: Build Starters
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
jobs:
|
||||
build-starters:
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
strategy:
|
||||
matrix:
|
||||
starter: ["react-passkey-auth"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup Source Code
|
||||
uses: ./.github/actions/source-code/
|
||||
|
||||
- name: Pnpm Build
|
||||
run: |
|
||||
pnpm install
|
||||
pnpm turbo build;
|
||||
working-directory: ./starters/${{ matrix.starter }}
|
||||
2
.github/workflows/code-quality.yml
vendored
2
.github/workflows/code-quality.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
- name: Setup Biome
|
||||
uses: biomejs/setup-biome@v2
|
||||
with:
|
||||
version: latest
|
||||
version: 1.9.4
|
||||
- name: Run Biome
|
||||
run: biome ci .
|
||||
|
||||
|
||||
4
.github/workflows/e2e-rn-test.yml
vendored
4
.github/workflows/e2e-rn-test.yml
vendored
@@ -38,7 +38,6 @@ jobs:
|
||||
- name: chat-rn-expo App Pre Build
|
||||
working-directory: ./examples/chat-rn-expo
|
||||
run: |
|
||||
pnpm build
|
||||
pnpm expo prebuild --clean
|
||||
|
||||
- name: Install Maestro
|
||||
@@ -61,7 +60,8 @@ jobs:
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -no-metrics
|
||||
disable-animations: true
|
||||
working-directory: ./examples/chat-rn-expo/
|
||||
script: ./test/e2e/run.sh
|
||||
# killall due to this issue: https://github.com/ReactiveCircus/android-emulator-runner/issues/385
|
||||
script: ./test/e2e/run.sh && killall -INT crashpad_handler || true
|
||||
|
||||
- name: Copy Maestro Output
|
||||
if: steps.e2e_test.outcome != 'success'
|
||||
|
||||
46
.github/workflows/playwright-homepage.yml
vendored
Normal file
46
.github/workflows/playwright-homepage.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Playwright Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 60
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup Source Code
|
||||
uses: ./.github/actions/source-code/
|
||||
|
||||
- name: Install root dependencies
|
||||
run: pnpm install && pnpm exec turbo build --filter="./packages/*"
|
||||
|
||||
- name: Install project dependencies
|
||||
run: pnpm install
|
||||
working-directory: ./homepage/homepage
|
||||
|
||||
- name: Pnpm Build
|
||||
run: pnpm exec turbo build
|
||||
working-directory: ./homepage/homepage
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: pnpm exec playwright install
|
||||
working-directory: ./homepage/homepage
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: pnpm exec playwright test
|
||||
working-directory: ./homepage/homepage
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: homepage-playwright-report
|
||||
path: ./homepage/homepage/playwright-report/
|
||||
retention-days: 30
|
||||
22
.github/workflows/playwright.yml
vendored
22
.github/workflows/playwright.yml
vendored
@@ -13,7 +13,21 @@ jobs:
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
project: ["tests/e2e", "examples/chat", "examples/clerk", "examples/betterauth", "examples/file-share-svelte", "examples/form", "examples/music-player", "examples/organization", "examples/pets", "starters/react-passkey-auth"]
|
||||
project: [
|
||||
"tests/e2e",
|
||||
"examples/chat",
|
||||
"examples/chat-svelte",
|
||||
"examples/clerk",
|
||||
"examples/betterauth",
|
||||
"examples/file-share-svelte",
|
||||
"examples/form",
|
||||
"examples/inspector",
|
||||
"examples/music-player",
|
||||
"examples/organization",
|
||||
"starters/react-passkey-auth",
|
||||
"starters/svelte-passkey-auth",
|
||||
"tests/jazz-svelte"
|
||||
]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -24,7 +38,11 @@ jobs:
|
||||
uses: ./.github/actions/source-code/
|
||||
|
||||
- name: Pnpm Build
|
||||
run: pnpm turbo build
|
||||
run: |
|
||||
if [ -f .env.test ]; then
|
||||
cp .env.test .env
|
||||
fi
|
||||
pnpm turbo build
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -20,6 +20,9 @@ __screenshots__
|
||||
# Playwright
|
||||
test-results
|
||||
|
||||
# Java
|
||||
.java-version
|
||||
|
||||
.husky
|
||||
|
||||
.vscode/*
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
"jazz-tools.json",
|
||||
"**/ios/**",
|
||||
"**/android/**",
|
||||
"packages/jazz-svelte/**",
|
||||
"tests/jazz-svelte/src/**",
|
||||
"examples/*svelte*/**",
|
||||
"starters/*svelte*/**",
|
||||
"examples/jazz-paper-scissors/src/routeTree.gen.ts",
|
||||
"homepage/homepage/**",
|
||||
"**/package.json"
|
||||
@@ -64,7 +65,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"include": ["packages/**/src/tests/**"],
|
||||
"include": ["**/tests/**"],
|
||||
"linter": {
|
||||
"rules": {
|
||||
"correctness": {
|
||||
|
||||
6
examples/betterauth/.gitignore
vendored
6
examples/betterauth/.gitignore
vendored
@@ -36,8 +36,10 @@ yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# env files (can opt-in for committing if needed)
|
||||
.env*
|
||||
!.env
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
@@ -1,5 +1,70 @@
|
||||
# betterauth
|
||||
|
||||
## 0.1.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [048ac1d]
|
||||
- jazz-tools@0.14.22
|
||||
- jazz-betterauth-server-plugin@0.14.22
|
||||
- jazz-inspector@0.14.22
|
||||
- jazz-react@0.14.22
|
||||
- jazz-react-auth-betterauth@0.14.22
|
||||
- jazz-betterauth-client-plugin@0.14.22
|
||||
|
||||
## 0.1.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [e7e505e]
|
||||
- Updated dependencies [13b57aa]
|
||||
- Updated dependencies [5662faa]
|
||||
- Updated dependencies [2116a59]
|
||||
- jazz-tools@0.14.21
|
||||
- jazz-betterauth-server-plugin@0.14.21
|
||||
- jazz-inspector@0.14.21
|
||||
- jazz-react@0.14.21
|
||||
- jazz-react-auth-betterauth@0.14.21
|
||||
- jazz-betterauth-client-plugin@0.14.21
|
||||
|
||||
## 0.1.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6f72419]
|
||||
- Updated dependencies [04b20c2]
|
||||
- jazz-tools@0.14.20
|
||||
- jazz-betterauth-server-plugin@0.14.20
|
||||
- jazz-inspector@0.14.20
|
||||
- jazz-react@0.14.20
|
||||
- jazz-react-auth-betterauth@0.14.20
|
||||
- jazz-betterauth-client-plugin@0.14.20
|
||||
|
||||
## 0.1.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-betterauth-client-plugin@0.14.19
|
||||
- jazz-betterauth-server-plugin@0.14.19
|
||||
- jazz-react-auth-betterauth@0.14.19
|
||||
- jazz-inspector@0.14.19
|
||||
- jazz-react@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 0.1.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4b950bc]
|
||||
- Updated dependencies [d6d9c0a]
|
||||
- Updated dependencies [c559054]
|
||||
- jazz-tools@0.14.18
|
||||
- jazz-betterauth-server-plugin@0.14.18
|
||||
- jazz-inspector@0.14.18
|
||||
- jazz-react@0.14.18
|
||||
- jazz-react-auth-betterauth@0.14.18
|
||||
- jazz-betterauth-client-plugin@0.14.18
|
||||
|
||||
## 0.1.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -5,10 +5,12 @@ This example demonstrates how to integrate [Better Auth](https://www.better-auth
|
||||
## Getting started
|
||||
|
||||
To run this example, you may either:
|
||||
* Clone the Jazz monorepo and run this example from within.
|
||||
* Create a new Jazz project using this example as a template, and run that new project.
|
||||
|
||||
- Clone the Jazz monorepo and run this example from within.
|
||||
- Create a new Jazz project using this example as a template, and run that new project.
|
||||
|
||||
### Setting environment variables
|
||||
|
||||
- `NEXT_PUBLIC_AUTH_BASE_URL`: A URL to a Better Auth server. If undefined, the example will self-host a Better Auth server.
|
||||
- `BETTER_AUTH_SECRET`: The encryption secret used by the self-hosted Better Auth server (required only if `NEXT_PUBLIC_AUTH_BASE_URL` is undefined)
|
||||
- `GITHUB_CLIENT_ID`: The client ID for the GitHub OAuth provider used by the self-hosted Better Auth server (required only if `NEXT_PUBLIC_AUTH_BASE_URL` is undefined)
|
||||
@@ -17,38 +19,64 @@ To run this example, you may either:
|
||||
### Using this example as a template
|
||||
|
||||
1. Create a new Jazz project, and use this example as a template.
|
||||
|
||||
```sh
|
||||
npx create-jazz-app@latest betterauth-app --example betterauth
|
||||
```
|
||||
2. Navigate to the new project and start the development server.
|
||||
|
||||
2. Navigate to the new project and install dependencies.
|
||||
|
||||
```sh
|
||||
cd betterauth-app
|
||||
pnpm install
|
||||
```
|
||||
|
||||
3. Create a .env file (don't forget to set your [BETTER_AUTH_SECRET](https://www.better-auth.com/docs/installation#set-environment-variables)!)
|
||||
|
||||
```sh
|
||||
mv .env.example .env
|
||||
```
|
||||
|
||||
4. Start the development server
|
||||
|
||||
```sh
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
https://www.better-auth.com/docs/installation#set-environment-variables
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Go to the example directory.
|
||||
|
||||
```bash
|
||||
cd jazz/examples/betterauth/
|
||||
```
|
||||
|
||||
Create a .env file (don't forget to set your [BETTER_AUTH_SECRET](https://www.better-auth.com/docs/installation#set-environment-variables)!)
|
||||
|
||||
```sh
|
||||
mv .env.example .env
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"name": "betterauth",
|
||||
"version": "0.1.20",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -22,11 +21,9 @@
|
||||
"better-sqlite3": "^11.9.1",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"jazz-react-auth-betterauth": "workspace:*",
|
||||
"jazz-betterauth-client-plugin": "workspace:*",
|
||||
"jazz-betterauth-server-plugin": "workspace:*",
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-react-auth-betterauth": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"lucide-react": "^0.510.0",
|
||||
"next": "15.3.2",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useAccount } from "jazz-react";
|
||||
import { Account } from "jazz-tools";
|
||||
import { useAccount } from "jazz-tools/react";
|
||||
import {
|
||||
AppWindowMacIcon,
|
||||
FileTextIcon,
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
"use client";
|
||||
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { AuthProvider } from "jazz-react-auth-betterauth";
|
||||
import { JazzReactProvider } from "jazz-tools/react";
|
||||
import { type ReactNode, lazy } from "react";
|
||||
|
||||
const JazzDevTools =
|
||||
process.env.NODE_ENV === "production"
|
||||
? () => null
|
||||
: lazy(() =>
|
||||
import("jazz-inspector").then((res) => ({
|
||||
import("jazz-tools/inspector").then((res) => ({
|
||||
default: res.JazzInspector,
|
||||
})),
|
||||
);
|
||||
|
||||
export function JazzAndAuth({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<JazzProvider
|
||||
<JazzReactProvider
|
||||
sync={{
|
||||
peer: "wss://cloud.jazz.tools/?key=betterauth-example@garden.co",
|
||||
}}
|
||||
@@ -28,6 +28,6 @@ export function JazzAndAuth({ children }: { children: ReactNode }) {
|
||||
{children}
|
||||
</AuthProvider>
|
||||
<JazzDevTools />
|
||||
</JazzProvider>
|
||||
</JazzReactProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useAccount, useIsAuthenticated } from "jazz-react";
|
||||
import { useAuth } from "jazz-react-auth-betterauth";
|
||||
import { Account } from "jazz-tools";
|
||||
import { useAccount, useIsAuthenticated } from "jazz-tools/react";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useCallback } from "react";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useAccount, useIsAuthenticated } from "jazz-react";
|
||||
import { useAuth } from "jazz-react-auth-betterauth";
|
||||
import { useAccount, useIsAuthenticated } from "jazz-tools/react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { toast } from "sonner";
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_ZXZpZGVudC1kYW5lLTg5LmNsZXJrLmFjY291bnRzLmRldiQ
|
||||
1
examples/chat-rn-expo-clerk/.env.example
Normal file
1
examples/chat-rn-expo-clerk/.env.example
Normal file
@@ -0,0 +1 @@
|
||||
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=
|
||||
6
examples/chat-rn-expo-clerk/.gitignore
vendored
6
examples/chat-rn-expo-clerk/.gitignore
vendored
@@ -15,3 +15,9 @@ web-build/
|
||||
|
||||
ios
|
||||
android
|
||||
|
||||
# Env
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -1,5 +1,57 @@
|
||||
# chat-rn-expo-clerk
|
||||
|
||||
## 1.0.145
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [048ac1d]
|
||||
- jazz-tools@0.14.22
|
||||
- jazz-expo@0.14.22
|
||||
- jazz-react-native-media-images@0.14.22
|
||||
|
||||
## 1.0.144
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [e7e505e]
|
||||
- Updated dependencies [cfb6786]
|
||||
- Updated dependencies [13b57aa]
|
||||
- Updated dependencies [5662faa]
|
||||
- Updated dependencies [2116a59]
|
||||
- jazz-tools@0.14.21
|
||||
- jazz-expo@0.14.21
|
||||
- jazz-react-native-media-images@0.14.21
|
||||
|
||||
## 1.0.143
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6f72419]
|
||||
- Updated dependencies [04b20c2]
|
||||
- jazz-tools@0.14.20
|
||||
- jazz-expo@0.14.20
|
||||
- jazz-react-native-media-images@0.14.20
|
||||
|
||||
## 1.0.142
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [061ec99]
|
||||
- jazz-expo@0.14.19
|
||||
- jazz-react-native-media-images@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 1.0.141
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4b950bc]
|
||||
- Updated dependencies [d6d9c0a]
|
||||
- Updated dependencies [c559054]
|
||||
- jazz-tools@0.14.18
|
||||
- jazz-expo@0.14.18
|
||||
- jazz-react-native-media-images@0.14.18
|
||||
|
||||
## 1.0.140
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -8,9 +8,12 @@ First, install dependencies and build the project:
|
||||
|
||||
```bash
|
||||
pnpm i
|
||||
mv .env.example .env
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
Don't forget to update `VITE_CLERK_PUBLISHABLE_KEY` in `.env` with your [Publishable Key](https://clerk.com/docs/deployments/clerk-environment-variables#clerk-publishable-and-secret-keys) from Clerk.
|
||||
|
||||
### 2. Inside the `examples/chat-rn-expo-clerk` Directory
|
||||
|
||||
Next, navigate to the specific example project and run the following commands:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Redirect, Stack } from "expo-router";
|
||||
import { useIsAuthenticated } from "jazz-expo";
|
||||
import { useIsAuthenticated } from "jazz-tools/expo";
|
||||
import React from "react";
|
||||
|
||||
export default function HomeLayout() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Redirect, Stack } from "expo-router";
|
||||
import { useIsAuthenticated } from "jazz-expo";
|
||||
import { useIsAuthenticated } from "jazz-tools/expo";
|
||||
|
||||
export default function UnAuthenticatedLayout() {
|
||||
const isAuthenticated = useIsAuthenticated();
|
||||
|
||||
@@ -4,7 +4,7 @@ import { secureStore } from "@clerk/clerk-expo/secure-store";
|
||||
import { useFonts } from "expo-font";
|
||||
import { Slot, useRouter, useSegments } from "expo-router";
|
||||
import * as SplashScreen from "expo-splash-screen";
|
||||
import { useIsAuthenticated, useJazzContext } from "jazz-expo";
|
||||
import { useIsAuthenticated, useJazzContext } from "jazz-tools/expo";
|
||||
import React, { useEffect } from "react";
|
||||
import { tokenCache } from "../cache";
|
||||
import { JazzAndAuth } from "../src/auth-context";
|
||||
|
||||
@@ -4,10 +4,10 @@ import clsx from "clsx";
|
||||
import * as Clipboard from "expo-clipboard";
|
||||
import * as ImagePicker from "expo-image-picker";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useAccount, useCoState } from "jazz-expo";
|
||||
import { ProgressiveImg } from "jazz-expo";
|
||||
import { createImage } from "jazz-react-native-media-images";
|
||||
import { CoPlainText, Group, Loaded } from "jazz-tools";
|
||||
import { useAccount, useCoState } from "jazz-tools/expo";
|
||||
import { ProgressiveImgNative } from "jazz-tools/expo";
|
||||
import { createImageNative } from "jazz-tools/react-native-media-images";
|
||||
import { useEffect, useLayoutEffect, useState } from "react";
|
||||
import React, {
|
||||
SafeAreaView,
|
||||
@@ -104,7 +104,7 @@ export default function Conversation() {
|
||||
setIsUploading(true);
|
||||
const base64Uri = `data:image/jpeg;base64,${result.assets[0].base64}`;
|
||||
|
||||
const image = await createImage(base64Uri, {
|
||||
const image = await createImageNative(base64Uri, {
|
||||
owner: chat._owner,
|
||||
maxSize: 2048,
|
||||
});
|
||||
@@ -149,15 +149,17 @@ export default function Conversation() {
|
||||
)}
|
||||
>
|
||||
{item.image && (
|
||||
<ProgressiveImg image={item.image} maxWidth={1024}>
|
||||
{({ src, res, originalSize }) => (
|
||||
<ProgressiveImgNative
|
||||
image={item.image}
|
||||
maxWidth={1024}
|
||||
children={({ src }) => (
|
||||
<Image
|
||||
source={{ uri: src }}
|
||||
className="w-48 h-48 rounded-lg mb-2"
|
||||
resizeMode="cover"
|
||||
/>
|
||||
)}
|
||||
</ProgressiveImg>
|
||||
/>
|
||||
)}
|
||||
{item.text && (
|
||||
<Text
|
||||
|
||||
@@ -11,7 +11,7 @@ import React, {
|
||||
} from "react-native";
|
||||
|
||||
import { useUser } from "@clerk/clerk-expo";
|
||||
import { useAccount } from "jazz-expo";
|
||||
import { useAccount } from "jazz-tools/expo";
|
||||
import { Chat } from "../../src/schema";
|
||||
|
||||
export default function ChatScreen() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"name": "chat-rn-expo-clerk",
|
||||
"main": "index.js",
|
||||
"version": "1.0.140",
|
||||
"scripts": {
|
||||
"build": "expo export -p ios",
|
||||
"start": "expo start",
|
||||
@@ -17,7 +16,6 @@
|
||||
"@bacons/text-decoder": "0.0.0",
|
||||
"@bam.tech/react-native-image-resizer": "^3.0.11",
|
||||
"@clerk/clerk-expo": "^2.2.21",
|
||||
"@craftzdog/react-native-buffer": "6.0.5",
|
||||
"@expo/vector-icons": "^14.1.0",
|
||||
"@react-native-community/netinfo": "11.4.1",
|
||||
"@react-navigation/native": "7.0.19",
|
||||
@@ -39,8 +37,6 @@
|
||||
"expo-sqlite": "15.2.9",
|
||||
"expo-status-bar": "~2.2.3",
|
||||
"expo-web-browser": "~14.1.6",
|
||||
"jazz-expo": "workspace:*",
|
||||
"jazz-react-native-media-images": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"nativewind": "^4.1.21",
|
||||
"react": "19.0.0",
|
||||
@@ -58,8 +54,6 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@types/react": "~19.0.14",
|
||||
"@types/react-test-renderer": "^19.0.0",
|
||||
"react-test-renderer": "18.3.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.8.3"
|
||||
},
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
// @ts-expect-error - @types/react-native doesn't cover this file
|
||||
import { polyfillGlobal } from "react-native/Libraries/Utilities/PolyfillFunctions";
|
||||
|
||||
import { Buffer } from "@craftzdog/react-native-buffer";
|
||||
polyfillGlobal("Buffer", () => Buffer);
|
||||
|
||||
// @ts-expect-error - @types/readable-stream doesn't have ReadableStream type
|
||||
import { ReadableStream } from "readable-stream";
|
||||
polyfillGlobal("ReadableStream", () => ReadableStream);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useClerk } from "@clerk/clerk-expo";
|
||||
import { JazzProviderWithClerk } from "jazz-expo/auth/clerk";
|
||||
import { JazzExpoProviderWithClerk } from "jazz-tools/expo";
|
||||
import React, { PropsWithChildren } from "react";
|
||||
import { apiKey } from "./apiKey";
|
||||
|
||||
@@ -7,13 +7,13 @@ export function JazzAndAuth({ children }: PropsWithChildren) {
|
||||
const clerk = useClerk();
|
||||
|
||||
return (
|
||||
<JazzProviderWithClerk
|
||||
<JazzExpoProviderWithClerk
|
||||
clerk={clerk}
|
||||
sync={{
|
||||
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</JazzProviderWithClerk>
|
||||
</JazzExpoProviderWithClerk>
|
||||
);
|
||||
}
|
||||
|
||||
7
examples/chat-rn-expo/.gitignore
vendored
7
examples/chat-rn-expo/.gitignore
vendored
@@ -36,4 +36,9 @@ yarn-error.*
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
android/
|
||||
ios/
|
||||
ios/
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -1,5 +1,52 @@
|
||||
# chat-rn-expo
|
||||
|
||||
## 1.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [048ac1d]
|
||||
- jazz-tools@0.14.22
|
||||
- jazz-expo@0.14.22
|
||||
|
||||
## 1.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [e7e505e]
|
||||
- Updated dependencies [cfb6786]
|
||||
- Updated dependencies [13b57aa]
|
||||
- Updated dependencies [5662faa]
|
||||
- Updated dependencies [2116a59]
|
||||
- jazz-tools@0.14.21
|
||||
- jazz-expo@0.14.21
|
||||
|
||||
## 1.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6f72419]
|
||||
- Updated dependencies [04b20c2]
|
||||
- jazz-tools@0.14.20
|
||||
- jazz-expo@0.14.20
|
||||
|
||||
## 1.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [061ec99]
|
||||
- jazz-expo@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 1.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4b950bc]
|
||||
- Updated dependencies [d6d9c0a]
|
||||
- Updated dependencies [c559054]
|
||||
- jazz-tools@0.14.18
|
||||
- jazz-expo@0.14.18
|
||||
|
||||
## 1.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"ios": {
|
||||
"supportsTablet": true,
|
||||
"bundleIdentifier": "com.anonymous.chatrnexpo"
|
||||
"bundleIdentifier": "tools.jazz.chatrnexpo"
|
||||
},
|
||||
"android": {
|
||||
"adaptiveIcon": {
|
||||
@@ -22,7 +22,7 @@
|
||||
"backgroundColor": "#ffffff"
|
||||
},
|
||||
"edgeToEdgeEnabled": true,
|
||||
"package": "com.anonymous.chatrnexpo"
|
||||
"package": "tools.jazz.chatrnexpo"
|
||||
},
|
||||
"web": {
|
||||
"favicon": "./assets/favicon.png"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"name": "chat-rn-expo",
|
||||
"version": "1.0.8",
|
||||
"main": "index.ts",
|
||||
"scripts": {
|
||||
"build": "expo prebuild",
|
||||
@@ -12,14 +11,13 @@
|
||||
"dependencies": {
|
||||
"@azure/core-asynciterator-polyfill": "^1.0.2",
|
||||
"@bacons/text-decoder": "^0.0.0",
|
||||
"@craftzdog/react-native-buffer": "^6.0.5",
|
||||
"@bam.tech/react-native-image-resizer": "^3.0.11",
|
||||
"@react-native-community/netinfo": "11.4.1",
|
||||
"expo": "~53.0.9",
|
||||
"expo-clipboard": "^7.1.4",
|
||||
"expo-secure-store": "~14.2.3",
|
||||
"expo-sqlite": "~15.2.10",
|
||||
"expo-status-bar": "~2.2.3",
|
||||
"jazz-expo": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-native": "0.79.2",
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
// @ts-expect-error - @types/react-native doesn't cover this file
|
||||
import { polyfillGlobal } from "react-native/Libraries/Utilities/PolyfillFunctions";
|
||||
|
||||
import { Buffer } from "@craftzdog/react-native-buffer";
|
||||
polyfillGlobal("Buffer", () => Buffer);
|
||||
|
||||
// @ts-expect-error - @types/readable-stream doesn't have ReadableStream type
|
||||
import { ReadableStream } from "readable-stream";
|
||||
polyfillGlobal("ReadableStream", () => ReadableStream);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { JazzProvider } from "jazz-expo";
|
||||
import { JazzExpoProvider } from "jazz-tools/expo";
|
||||
import React, { StrictMode } from "react";
|
||||
import { apiKey } from "./apiKey";
|
||||
import ChatScreen from "./chat";
|
||||
@@ -6,13 +6,13 @@ import ChatScreen from "./chat";
|
||||
export default function App() {
|
||||
return (
|
||||
<StrictMode>
|
||||
<JazzProvider
|
||||
<JazzExpoProvider
|
||||
sync={{
|
||||
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||
}}
|
||||
>
|
||||
<ChatScreen />
|
||||
</JazzProvider>
|
||||
</JazzExpoProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import React, {
|
||||
StyleSheet,
|
||||
} from "react-native";
|
||||
|
||||
import { useAccount, useCoState } from "jazz-expo";
|
||||
import { useAccount, useCoState } from "jazz-tools/expo";
|
||||
import { Chat, Message } from "./schema";
|
||||
|
||||
export default function ChatScreen() {
|
||||
@@ -128,7 +128,11 @@ export default function ChatScreen() {
|
||||
}}
|
||||
testID="chat-id-input"
|
||||
/>
|
||||
<TouchableOpacity onPress={joinChat} style={styles.joinChatButton}>
|
||||
<TouchableOpacity
|
||||
testID="join-chat-button"
|
||||
onPress={joinChat}
|
||||
style={styles.joinChatButton}
|
||||
>
|
||||
<Text style={styles.newChatButtonText}>Join chat</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# fully erased. The tap into the input field hits the middle, and clears all
|
||||
# text to the left. If there's more to the right, it slides left, and thus we
|
||||
# repeat this step. https://maestro.mobile.dev/api-reference/commands/erasetext
|
||||
appId: com.jazz.chatrn
|
||||
appId: tools.jazz.chatrnexpo
|
||||
---
|
||||
- copyTextFrom:
|
||||
id: ${id}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
appId: com.jazz.chatrn
|
||||
appId: tools.jazz.chatrnexpo
|
||||
---
|
||||
- launchApp
|
||||
|
||||
@@ -41,12 +41,17 @@ appId: com.jazz.chatrn
|
||||
# logout
|
||||
- tapOn: "Logout"
|
||||
- assertVisible: "Username"
|
||||
- assertVisible: "Anonymous user"
|
||||
|
||||
# join chat
|
||||
- extendedWaitUntil:
|
||||
visible: "Anonymous user"
|
||||
timeout: 10000
|
||||
# join chat
|
||||
|
||||
## Commented because it fails on CI
|
||||
# - tapOn:
|
||||
# id: "chat-id-input"
|
||||
# - inputText: "co_zFs6KFyhxPw4xtw83tcEMzeHUNv" # Use a static id because maestro doesn't have access to the system clipboard
|
||||
# - tapOn: "Join chat"
|
||||
# - tapOn:
|
||||
# id: "join-chat-button"
|
||||
# - assertVisible: "boorad"
|
||||
# - assertVisible: "bro, low key, it do be like that tho"
|
||||
|
||||
@@ -3,14 +3,18 @@
|
||||
# This script is necessary, because unlike ios, the android emulator action
|
||||
# accepts a script, runs it as your tests, then terminates.
|
||||
|
||||
# set -e
|
||||
set -e
|
||||
|
||||
# # build and install the app
|
||||
# echo "Building and installing Android app."
|
||||
# echo "If it fails, its output will be in artifact: android-install.log..."
|
||||
# cd ./android/
|
||||
# ./gradlew installRelease >> ~/output/android-install.log 2>&1
|
||||
# cd ..
|
||||
OUTPUT_FILE=~/output/android-install.log
|
||||
mkdir -p ~/output
|
||||
touch $OUTPUT_FILE
|
||||
|
||||
# build and install the app
|
||||
echo "Building and installing Android app."
|
||||
echo "If it fails, its output will be in artifact: android-install.log..."
|
||||
cd ./android/
|
||||
./gradlew installRelease >> $OUTPUT_FILE 2>&1
|
||||
cd ..
|
||||
|
||||
# run the e2e tests
|
||||
export PATH="$PATH":"$HOME/.maestro/bin"
|
||||
|
||||
13
examples/chat-rn-expo/test/e2e/runLocal.sh
Executable file
13
examples/chat-rn-expo/test/e2e/runLocal.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script is necessary, because unlike ios, the android emulator action
|
||||
# accepts a script, runs it as your tests, then terminates.
|
||||
|
||||
set -e
|
||||
|
||||
# run the e2e tests
|
||||
export PATH="$PATH":"$HOME/.maestro/bin"
|
||||
export MAESTRO_DRIVER_STARTUP_TIMEOUT=300000 # setting to 5 mins 👀
|
||||
export MAESTRO_CLI_NO_ANALYTICS=1
|
||||
export MAESTRO_CLI_ANALYSIS_NOTIFICATION_DISABLED=true
|
||||
maestro test test/e2e/flow.yml
|
||||
6
examples/chat-rn/.gitignore
vendored
6
examples/chat-rn/.gitignore
vendored
@@ -73,3 +73,9 @@ yarn-error.log
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -1,5 +1,64 @@
|
||||
# chat-rn
|
||||
|
||||
## 1.0.140
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [57fb69f]
|
||||
- Updated dependencies [048ac1d]
|
||||
- cojson@0.14.22
|
||||
- jazz-tools@0.14.22
|
||||
- cojson-transport-ws@0.14.22
|
||||
- jazz-react-native@0.14.22
|
||||
|
||||
## 1.0.139
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [e7e505e]
|
||||
- Updated dependencies [c3d8779]
|
||||
- Updated dependencies [13b57aa]
|
||||
- Updated dependencies [5662faa]
|
||||
- Updated dependencies [2116a59]
|
||||
- jazz-tools@0.14.21
|
||||
- cojson@0.14.21
|
||||
- jazz-react-native@0.14.21
|
||||
- cojson-transport-ws@0.14.21
|
||||
|
||||
## 1.0.138
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [6f72419]
|
||||
- Updated dependencies [04b20c2]
|
||||
- jazz-tools@0.14.20
|
||||
- jazz-react-native@0.14.20
|
||||
- cojson@0.14.20
|
||||
- cojson-transport-ws@0.14.20
|
||||
|
||||
## 1.0.137
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [061ec99]
|
||||
- jazz-react-native@0.14.19
|
||||
- cojson@0.14.19
|
||||
- cojson-transport-ws@0.14.19
|
||||
- jazz-tools@0.14.19
|
||||
|
||||
## 1.0.136
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4b950bc]
|
||||
- Updated dependencies [0d5ee3e]
|
||||
- Updated dependencies [d6d9c0a]
|
||||
- Updated dependencies [c559054]
|
||||
- jazz-tools@0.14.18
|
||||
- cojson@0.14.18
|
||||
- jazz-react-native@0.14.18
|
||||
- cojson-transport-ws@0.14.18
|
||||
|
||||
## 1.0.135
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -26,7 +26,7 @@ This will set up and launch the app on iOS. For Android, you can skip `pnpm pods
|
||||
This was created using the following command:
|
||||
|
||||
```bash
|
||||
pnpx @react-native-community/cli init chat-rn --version 0.76.7 --install-pods true --skip-git-init true --package-name com.chatrn --directory chat-rn
|
||||
pnpx @react-native-community/cli init chat-rn --version 0.76.9 --install-pods true --skip-git-init true --package-name com.chatrn --directory chat-rn
|
||||
```
|
||||
|
||||
Then change package name in `package.json`, and begin build instructions above.
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
"name": "ChatRN",
|
||||
"displayName": "ChatRN",
|
||||
"android": {
|
||||
"package": "com.anonymous.ChatRN"
|
||||
"package": "tools.jazz.chatrn"
|
||||
},
|
||||
"ios": {
|
||||
"bundleIdentifier": "com.anonymous.ChatRN"
|
||||
"bundleIdentifier": "tools.jazz.chatrn"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,7 @@ module.exports = makeMetroConfig({
|
||||
resolveRequest: MetroSymlinksResolver(),
|
||||
extraNodeModules,
|
||||
nodeModulesPaths,
|
||||
sourceExts: ["mjs", "js", "json", "ts", "tsx"],
|
||||
},
|
||||
sourceExts: ["mjs", "js", "json", "ts", "tsx"],
|
||||
watchFolders,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-rn",
|
||||
"version": "1.0.135",
|
||||
"private": true,
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"android": "react-native run-android",
|
||||
@@ -12,7 +12,6 @@
|
||||
"dependencies": {
|
||||
"@azure/core-asynciterator-polyfill": "^1.0.2",
|
||||
"@bacons/text-decoder": "0.0.0",
|
||||
"@craftzdog/react-native-buffer": "6.0.5",
|
||||
"@op-engineering/op-sqlite": "^11.4.8",
|
||||
"@react-native-clipboard/clipboard": "1.16.1",
|
||||
"@react-native-community/netinfo": "11.4.1",
|
||||
@@ -21,7 +20,6 @@
|
||||
"clsx": "^2.0.0",
|
||||
"cojson": "workspace:*",
|
||||
"cojson-transport-ws": "workspace:*",
|
||||
"jazz-react-native": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-native": "0.79.2",
|
||||
@@ -40,18 +38,16 @@
|
||||
"@react-native-community/cli": "15.0.1",
|
||||
"@react-native-community/cli-platform-android": "15.0.1",
|
||||
"@react-native-community/cli-platform-ios": "15.0.1",
|
||||
"@react-native/babel-preset": "0.76.7",
|
||||
"@react-native/eslint-config": "0.76.7",
|
||||
"@react-native/metro-config": "0.76.7",
|
||||
"@react-native/typescript-config": "0.76.7",
|
||||
"@react-native/babel-preset": "0.76.9",
|
||||
"@react-native/eslint-config": "0.76.9",
|
||||
"@react-native/metro-config": "0.76.9",
|
||||
"@react-native/typescript-config": "0.76.9",
|
||||
"@rnx-kit/metro-config": "^2.0.1",
|
||||
"@rnx-kit/metro-resolver-symlinks": "^0.2.1",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-test-renderer": "^18.0.0",
|
||||
"eslint": "^8.19.0",
|
||||
"pod-install": "^0.3.5",
|
||||
"prettier": "2.8.8",
|
||||
"react-test-renderer": "18.3.1",
|
||||
"typescript": "5.6.2"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
useNavigationContainerRef,
|
||||
} from "@react-navigation/native";
|
||||
import { createNativeStackNavigator } from "@react-navigation/native-stack";
|
||||
import { JazzProvider } from "jazz-react-native";
|
||||
import { JazzReactNativeProvider } from "jazz-tools/react-native";
|
||||
import React, { StrictMode, useEffect, useState } from "react";
|
||||
import { Linking } from "react-native";
|
||||
import { apiKey } from "./apiKey";
|
||||
@@ -49,7 +49,7 @@ function App() {
|
||||
|
||||
return (
|
||||
<StrictMode>
|
||||
<JazzProvider
|
||||
<JazzReactNativeProvider
|
||||
sync={{
|
||||
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||
}}
|
||||
@@ -67,7 +67,7 @@ function App() {
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
</NavigationContainer>
|
||||
</JazzProvider>
|
||||
</JazzReactNativeProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import Clipboard from "@react-native-clipboard/clipboard";
|
||||
import { useAccount, useCoState } from "jazz-react-native";
|
||||
import { CoPlainText, Group, ID, Loaded, Profile } from "jazz-tools";
|
||||
import { useAccount, useCoState } from "jazz-tools/react-native";
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
Alert,
|
||||
Button,
|
||||
FlatList,
|
||||
KeyboardAvoidingView,
|
||||
@@ -19,6 +18,7 @@ import { Chat, Message } from "./schema";
|
||||
export function ChatScreen({ navigation }: { navigation: any }) {
|
||||
const { me, logOut } = useAccount();
|
||||
const [chatId, setChatId] = useState<string>();
|
||||
const [chatIdInput, setChatIdInput] = useState<string>();
|
||||
const loadedChat = useCoState(Chat, chatId, { resolve: { $each: true } });
|
||||
const [message, setMessage] = useState("");
|
||||
const profile = useCoState(Profile, me._refs.profile?.id, {});
|
||||
@@ -36,10 +36,8 @@ export function ChatScreen({ navigation }: { navigation: any }) {
|
||||
<Button
|
||||
onPress={() => {
|
||||
if (loadedChat?.id) {
|
||||
Clipboard.setString(
|
||||
`https://chat.jazz.tools/#/chat/${loadedChat.id}`,
|
||||
);
|
||||
Alert.alert("Copied to clipboard", `Chat ID: ${loadedChat.id}`);
|
||||
Clipboard.setString(loadedChat.id);
|
||||
console.log("Copied to clipboard", `Chat ID: ${loadedChat.id}`);
|
||||
}
|
||||
}}
|
||||
title="Share"
|
||||
@@ -56,27 +54,11 @@ export function ChatScreen({ navigation }: { navigation: any }) {
|
||||
};
|
||||
|
||||
const joinChat = () => {
|
||||
Alert.prompt(
|
||||
"Join Chat",
|
||||
"Enter the Chat ID (example: co_zBGEHYvRfGuT2YSBraY3njGjnde)",
|
||||
[
|
||||
{
|
||||
text: "Cancel",
|
||||
style: "cancel",
|
||||
},
|
||||
{
|
||||
text: "Join",
|
||||
onPress: (chatId) => {
|
||||
if (chatId) {
|
||||
setChatId(chatId);
|
||||
} else {
|
||||
Alert.alert("Error", "Chat ID cannot be empty.");
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
"plain-text",
|
||||
);
|
||||
if (chatIdInput) {
|
||||
setChatId(chatIdInput as ID<Chat>);
|
||||
} else {
|
||||
console.warn("Error: Chat ID cannot be empty.");
|
||||
}
|
||||
};
|
||||
|
||||
const sendMessage = () => {
|
||||
@@ -153,6 +135,16 @@ export function ChatScreen({ navigation }: { navigation: any }) {
|
||||
<TouchableOpacity onPress={createChat} style={styles.newChatButton}>
|
||||
<Text style={styles.buttonText}>Start new chat</Text>
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.usernameLabel}>Join existing chat</Text>
|
||||
<TextInput
|
||||
style={styles.chatIdInput}
|
||||
placeholder="Chat ID"
|
||||
value={chatIdInput ?? ""}
|
||||
onChangeText={setChatIdInput}
|
||||
textAlignVertical="center"
|
||||
onSubmitEditing={joinChat}
|
||||
testID="chat-id-input"
|
||||
/>
|
||||
<TouchableOpacity onPress={joinChat} style={styles.joinChatButton}>
|
||||
<Text style={styles.buttonText}>Join chat</Text>
|
||||
</TouchableOpacity>
|
||||
@@ -205,27 +197,91 @@ export function ChatScreen({ navigation }: { navigation: any }) {
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
flexDirection: "column",
|
||||
height: "100%",
|
||||
},
|
||||
welcomeContainer: {
|
||||
flex: 1,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
padding: 16,
|
||||
},
|
||||
usernameLabel: {
|
||||
fontSize: 16,
|
||||
fontWeight: "bold",
|
||||
marginBottom: 16,
|
||||
},
|
||||
usernameInput: {
|
||||
width: 160,
|
||||
height: 48,
|
||||
borderWidth: 1,
|
||||
borderColor: "#ddd",
|
||||
borderRadius: 8,
|
||||
paddingHorizontal: 8,
|
||||
marginBottom: 24,
|
||||
},
|
||||
chatIdInput: {
|
||||
width: 320,
|
||||
height: 48,
|
||||
borderWidth: 1,
|
||||
borderColor: "#ddd",
|
||||
borderRadius: 8,
|
||||
paddingHorizontal: 8,
|
||||
marginBottom: 24,
|
||||
marginTop: 8,
|
||||
},
|
||||
newChatButton: {
|
||||
backgroundColor: "#3B82F6",
|
||||
padding: 16,
|
||||
borderRadius: 8,
|
||||
marginBottom: 24,
|
||||
},
|
||||
joinChatButton: {
|
||||
backgroundColor: "#10B981",
|
||||
padding: 16,
|
||||
borderRadius: 8,
|
||||
},
|
||||
buttonText: {
|
||||
color: "white",
|
||||
fontSize: 16,
|
||||
fontWeight: "bold",
|
||||
textAlign: "center",
|
||||
},
|
||||
messageList: {
|
||||
flex: 1,
|
||||
},
|
||||
inputContainer: {
|
||||
padding: 12,
|
||||
},
|
||||
inputWrapper: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
borderWidth: 1,
|
||||
borderColor: "#ddd",
|
||||
borderRadius: 8,
|
||||
paddingHorizontal: 12,
|
||||
},
|
||||
messageInput: {
|
||||
flex: 1,
|
||||
height: 32,
|
||||
paddingHorizontal: 8,
|
||||
},
|
||||
sendButton: {
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
messageContainer: {
|
||||
borderRadius: 8,
|
||||
paddingVertical: 4,
|
||||
paddingHorizontal: 6,
|
||||
maxWidth: "80%",
|
||||
flexDirection: "column",
|
||||
alignItems: "flex-start",
|
||||
marginBottom: 8,
|
||||
},
|
||||
myMessage: {
|
||||
backgroundColor: "#e5e7eb", // gray-200
|
||||
alignSelf: "flex-end",
|
||||
textAlign: "right",
|
||||
},
|
||||
otherMessage: {
|
||||
backgroundColor: "#d1d5db", // gray-300
|
||||
alignSelf: "flex-start",
|
||||
},
|
||||
senderName: {
|
||||
fontSize: 12,
|
||||
color: "#6b7280", // gray-500
|
||||
color: "#666",
|
||||
marginBottom: 4,
|
||||
},
|
||||
textRight: {
|
||||
textAlign: "right",
|
||||
@@ -234,92 +290,27 @@ const styles = StyleSheet.create({
|
||||
textAlign: "left",
|
||||
},
|
||||
messageContent: {
|
||||
position: "relative",
|
||||
flexDirection: "row",
|
||||
alignItems: "flex-end",
|
||||
justifyContent: "space-between",
|
||||
backgroundColor: "#f0f0f0",
|
||||
borderRadius: 8,
|
||||
padding: 8,
|
||||
},
|
||||
messageText: {
|
||||
color: "#000000",
|
||||
fontSize: 16,
|
||||
maxWidth: "85%",
|
||||
},
|
||||
timestamp: {
|
||||
fontSize: 10,
|
||||
color: "#6b7280", // gray-500
|
||||
textAlign: "right",
|
||||
marginLeft: 8,
|
||||
color: "#666",
|
||||
marginTop: 4,
|
||||
},
|
||||
timestampOther: {
|
||||
textAlign: "left",
|
||||
marginTop: 8,
|
||||
},
|
||||
timestampMy: {
|
||||
textAlign: "right",
|
||||
marginTop: 4,
|
||||
},
|
||||
welcomeContainer: {
|
||||
flex: 1,
|
||||
flexDirection: "column",
|
||||
height: "100%",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
usernameLabel: {
|
||||
fontSize: 16,
|
||||
fontWeight: "bold",
|
||||
marginBottom: 24,
|
||||
},
|
||||
usernameInput: {
|
||||
borderRadius: 4,
|
||||
height: 48,
|
||||
padding: 8,
|
||||
marginBottom: 48,
|
||||
width: 160,
|
||||
borderWidth: 1,
|
||||
borderColor: "#e5e7eb", // gray-200
|
||||
},
|
||||
newChatButton: {
|
||||
backgroundColor: "#3b82f6", // blue-500
|
||||
padding: 16,
|
||||
borderRadius: 6,
|
||||
},
|
||||
joinChatButton: {
|
||||
backgroundColor: "#10b981", // green-500
|
||||
padding: 16,
|
||||
borderRadius: 6,
|
||||
marginTop: 16,
|
||||
},
|
||||
buttonText: {
|
||||
color: "white",
|
||||
fontWeight: "600",
|
||||
},
|
||||
messageList: {
|
||||
flex: 1,
|
||||
},
|
||||
inputContainer: {
|
||||
paddingVertical: 16,
|
||||
paddingHorizontal: 10,
|
||||
backgroundColor: "white",
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: "#d1d5db", // gray-300
|
||||
},
|
||||
inputWrapper: {
|
||||
flex: 1,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
margin: 5,
|
||||
},
|
||||
messageInput: {
|
||||
borderRadius: 20,
|
||||
height: 32,
|
||||
paddingVertical: 0,
|
||||
paddingHorizontal: 8,
|
||||
borderWidth: 1,
|
||||
borderColor: "#e5e7eb", // gray-200
|
||||
flex: 1,
|
||||
},
|
||||
sendButton: {
|
||||
marginLeft: 10,
|
||||
backgroundColor: "#d1d5db", // gray-300
|
||||
avatar: {
|
||||
borderRadius: 16,
|
||||
height: 32,
|
||||
width: 32,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useAcceptInvite } from "jazz-react-native";
|
||||
import { useAcceptInviteNative } from "jazz-tools/react-native";
|
||||
import React from "react";
|
||||
import { Text } from "react-native";
|
||||
import { Chat } from "./schema";
|
||||
@@ -8,7 +8,7 @@ export function HandleInviteScreen({
|
||||
}: {
|
||||
navigation: any;
|
||||
}) {
|
||||
useAcceptInvite({
|
||||
useAcceptInviteNative({
|
||||
invitedObjectSchema: Chat,
|
||||
onAccept: async (chatId) => {
|
||||
navigation.navigate("ChatScreen", { chatId });
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
import { polyfillGlobal } from "react-native/Libraries/Utilities/PolyfillFunctions";
|
||||
// import 'react-native-polyfill-globals/auto';
|
||||
|
||||
import { Buffer } from "@craftzdog/react-native-buffer";
|
||||
polyfillGlobal("Buffer", () => Buffer);
|
||||
|
||||
// @ts-expect-error - @types/readable-stream doesn't have ReadableStream type
|
||||
import { ReadableStream } from "readable-stream";
|
||||
polyfillGlobal("ReadableStream", () => ReadableStream);
|
||||
|
||||
@@ -1,140 +1,48 @@
|
||||
# passkey-svelte
|
||||
|
||||
## 0.0.101
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [e512df4]
|
||||
- jazz-tools@0.14.17
|
||||
- jazz-svelte@0.14.17
|
||||
|
||||
## 0.0.100
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.14.16
|
||||
- jazz-tools@0.14.16
|
||||
|
||||
## 0.0.99
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.14.15
|
||||
- jazz-tools@0.14.15
|
||||
|
||||
## 0.0.98
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [e32a1f7]
|
||||
- jazz-tools@0.14.14
|
||||
- jazz-svelte@0.14.14
|
||||
|
||||
## 0.0.97
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [dc746a2]
|
||||
- Updated dependencies [f869d9a]
|
||||
- Updated dependencies [3fe6832]
|
||||
- jazz-tools@0.14.10
|
||||
- jazz-svelte@0.14.10
|
||||
|
||||
## 0.0.96
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [22c2600]
|
||||
- jazz-tools@0.14.9
|
||||
- jazz-svelte@0.14.9
|
||||
|
||||
## 0.0.95
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [637ae13]
|
||||
- jazz-tools@0.14.8
|
||||
- jazz-svelte@0.14.8
|
||||
|
||||
## 0.0.94
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [365b0ea]
|
||||
- jazz-tools@0.14.7
|
||||
- jazz-svelte@0.14.7
|
||||
|
||||
## 0.0.93
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [9d6d9fe]
|
||||
- Updated dependencies [9d6d9fe]
|
||||
- jazz-tools@0.14.6
|
||||
- jazz-svelte@0.14.6
|
||||
|
||||
## 0.0.92
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [91cbb2f]
|
||||
- Updated dependencies [20b3d88]
|
||||
- jazz-tools@0.14.5
|
||||
- jazz-svelte@0.14.5
|
||||
|
||||
## 0.0.91
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [011af55]
|
||||
- jazz-tools@0.14.4
|
||||
- jazz-svelte@0.14.4
|
||||
|
||||
## 0.0.90
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b2ee306]
|
||||
- jazz-svelte@0.14.3
|
||||
|
||||
## 0.0.89
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3d1027f]
|
||||
- Updated dependencies [c240eed]
|
||||
- jazz-tools@0.14.2
|
||||
- jazz-svelte@0.14.2
|
||||
- Updated dependencies [1378a1f]
|
||||
- Updated dependencies [0fa051a]
|
||||
- jazz-tools@0.15.0
|
||||
|
||||
## 0.0.88
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [cdfc105]
|
||||
- jazz-tools@0.14.1
|
||||
- jazz-svelte@0.14.1
|
||||
- Updated dependencies [06c5a1c]
|
||||
- jazz-tools@0.14.28
|
||||
- jazz-browser-media-images@0.14.28
|
||||
- jazz-svelte@0.14.28
|
||||
|
||||
## 0.0.87
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [5835ed1]
|
||||
- jazz-tools@0.14.0
|
||||
- jazz-svelte@0.14.0
|
||||
- Updated dependencies [a026073]
|
||||
- jazz-tools@0.14.27
|
||||
- jazz-browser-media-images@0.14.27
|
||||
- jazz-svelte@0.14.27
|
||||
|
||||
## 0.0.86
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-svelte@0.13.32
|
||||
- Updated dependencies [e35a380]
|
||||
- jazz-svelte@0.14.26
|
||||
- jazz-tools@0.14.26
|
||||
- jazz-browser-media-images@0.14.26
|
||||
|
||||
## 0.0.85
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [e5b170f]
|
||||
- jazz-tools@0.13.31
|
||||
- jazz-svelte@0.13.31
|
||||
- Updated dependencies [99a2d9b]
|
||||
- jazz-tools@0.14.25
|
||||
- jazz-browser-media-images@0.14.25
|
||||
- jazz-svelte@0.14.25
|
||||
|
||||
## 0.0.84
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
# Chat example with Jazz and Vue
|
||||
# Chat example with Jazz and Svelte
|
||||
|
||||
## Getting started
|
||||
|
||||
You can either
|
||||
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
|
||||
```bash
|
||||
npx create-jazz-app@latest chat-vue-app --example chat-vue
|
||||
npx create-jazz-app@latest chat-app --example chat-svelte
|
||||
```
|
||||
|
||||
Go to the new project directory.
|
||||
|
||||
```bash
|
||||
cd chat-vue-app
|
||||
cd chat-app
|
||||
```
|
||||
|
||||
Run the dev server.
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
@@ -29,21 +32,25 @@ npm run dev
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Go to the example directory.
|
||||
|
||||
```bash
|
||||
cd jazz/examples/chat-vue/
|
||||
cd jazz/examples/chat-svelte/
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
@@ -58,4 +65,4 @@ If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or
|
||||
|
||||
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
|
||||
|
||||
You can also run a local sync server by running `npx jazz-run sync` and adding the query param `?sync=ws://localhost:4200` to the URL of the example app (for example: `http://localhost:5173/?peer=ws://localhost:4200`), or by setting the `sync` parameter of `JazzProvider` in [./src/main.ts](./src/main.ts).
|
||||
You can also run a local sync server by running `npx jazz-run sync`, and setting the `sync` parameter of `JazzSvelteProvider` in [./src/routes/+layout.svelte](./src/routes/+layout.svelte) to `{ peer: "ws://localhost:4200" }`.
|
||||
41
examples/chat-svelte/package.json
Normal file
41
examples/chat-svelte/package.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "chat-svelte",
|
||||
"version": "0.0.89",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"format": "prettier --write .",
|
||||
"lint": "prettier --check . && eslint .",
|
||||
"format-and-lint": "pnpm run format && pnpm run lint",
|
||||
"format-and-lint:fix": "pnpm run format --write && pnpm run lint --fix",
|
||||
"test:e2e": "playwright test",
|
||||
"test:e2e:ui": "playwright test --ui"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^3.3.1",
|
||||
"@sveltejs/kit": "^2.21.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||
"@types/eslint": "^9.6.1",
|
||||
"eslint": "^9.27.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-svelte": "^2.46.1",
|
||||
"globals": "^15.15.0",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-svelte": "^3.4.0",
|
||||
"svelte": "^5.31.1",
|
||||
"svelte-check": "^4.2.1",
|
||||
"typescript": "5.6.2",
|
||||
"typescript-eslint": "^8.32.1",
|
||||
"vite": "6.0.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.7",
|
||||
"jazz-tools": "workspace:*",
|
||||
"tailwindcss": "^4.1.7"
|
||||
}
|
||||
}
|
||||
54
examples/chat-svelte/playwright.config.ts
Normal file
54
examples/chat-svelte/playwright.config.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
import isCI from 'is-ci';
|
||||
|
||||
/**
|
||||
* Read environment variables from file.
|
||||
* https://github.com/motdotla/dotenv
|
||||
*/
|
||||
// import dotenv from 'dotenv';
|
||||
// dotenv.config({ path: path.resolve(__dirname, '.env') });
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: './tests',
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: isCI,
|
||||
/* Retry on CI only */
|
||||
retries: isCI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: isCI ? 1 : undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: 'html',
|
||||
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
baseURL: 'http://localhost:5173/',
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: 'on-first-retry',
|
||||
permissions: ['clipboard-read', 'clipboard-write']
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] }
|
||||
}
|
||||
],
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: [
|
||||
{
|
||||
command: 'pnpm preview --port 5173',
|
||||
url: 'http://localhost:5173/',
|
||||
reuseExistingServer: !isCI
|
||||
}
|
||||
]
|
||||
});
|
||||
1
examples/chat-svelte/src/apiKey.ts
Normal file
1
examples/chat-svelte/src/apiKey.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const apiKey = 'svelte-chat-example@garden.co';
|
||||
21
examples/chat-svelte/src/app.css
Normal file
21
examples/chat-svelte/src/app.css
Normal file
@@ -0,0 +1,21 @@
|
||||
@import 'tailwindcss';
|
||||
@theme {
|
||||
--color-stone-50: oklch(0.988281 0.002 75);
|
||||
--color-stone-75: oklch(0.980563 0.002 75);
|
||||
--color-stone-100: oklch(0.964844 0.002 75);
|
||||
--color-stone-200: oklch(0.917969 0.002 75);
|
||||
--color-stone-300: oklch(0.853516 0.002 75);
|
||||
--color-stone-400: oklch(0.789063 0.002 75);
|
||||
--color-stone-500: oklch(0.726563 0.002 75);
|
||||
--color-stone-600: oklch(0.613281 0.002 75);
|
||||
--color-stone-700: oklch(0.523438 0.002 75);
|
||||
--color-stone-800: oklch(0.412109 0.002 75);
|
||||
--color-stone-900: oklch(0.302734 0.002 75);
|
||||
--color-stone-925: oklch(0.22 0.002 75);
|
||||
--color-stone-950: oklch(0.193359 0.002 75);
|
||||
--color-blue: oklch(0.57 0.2346 261.2);
|
||||
}
|
||||
|
||||
:focus {
|
||||
@apply outline-hidden;
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="%sveltekit.assets%/jazz-icon.png" type="image/png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
@@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="flex flex-col justify-between w-screen h-screen bg-stone-50 dark:bg-stone-925 dark:text-white"
|
||||
>
|
||||
{@render children()}
|
||||
</div>
|
||||
13
examples/chat-svelte/src/lib/components/BubbleBody.svelte
Normal file
13
examples/chat-svelte/src/lib/components/BubbleBody.svelte
Normal file
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
let { children, fromMe }: { children: Snippet; fromMe: boolean | undefined } = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="line-clamp-10 text-ellipsis rounded-2xl overflow-hidden max-w-[calc(100%-5rem)] shadow-sm p-1 {fromMe
|
||||
? 'bg-white dark:bg-stone-900 dark:text-white'
|
||||
: 'bg-blue text-white'}"
|
||||
>
|
||||
{@render children()}
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
let { children, fromMe }: { children: Snippet; fromMe: boolean | undefined } = $props();
|
||||
const align = fromMe ? 'items-end' : 'items-start';
|
||||
</script>
|
||||
|
||||
<div class="{align} flex flex-col m-3" role="row">
|
||||
{@render children()}
|
||||
</div>
|
||||
12
examples/chat-svelte/src/lib/components/BubbleImage.svelte
Normal file
12
examples/chat-svelte/src/lib/components/BubbleImage.svelte
Normal file
@@ -0,0 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { ImageDefinition, type Loaded } from 'jazz-tools';
|
||||
import { useProgressiveImg } from '$lib/utils/useProgressiveImage.svelte';
|
||||
let { image }: { image: Loaded<typeof ImageDefinition> } = $props();
|
||||
const { src } = $derived(
|
||||
useProgressiveImg({
|
||||
image
|
||||
})
|
||||
);
|
||||
</script>
|
||||
|
||||
<img class="h-auto max-h-[20rem] max-w-full rounded-t-xl mb-1" {src} alt="" />
|
||||
@@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
let { by, madeAt }: { by: string | undefined; madeAt: Date } = $props();
|
||||
</script>
|
||||
|
||||
<div class="text-xs text-neutral-500 mt-1.5">
|
||||
{by} · {madeAt.toLocaleTimeString()}
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
import type { CoPlainText } from 'jazz-tools';
|
||||
|
||||
let { text, className }: { text: CoPlainText | string | null; className?: string } = $props();
|
||||
</script>
|
||||
|
||||
<div class="whitespace-pre-wrap"><p class="px-2 leading-relaxed {className}">{text}</p></div>
|
||||
7
examples/chat-svelte/src/lib/components/ChatBody.svelte
Normal file
7
examples/chat-svelte/src/lib/components/ChatBody.svelte
Normal file
@@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col-reverse flex-1 overflow-y-auto" role="application">
|
||||
{@render children()}
|
||||
</div>
|
||||
36
examples/chat-svelte/src/lib/components/ChatBubble.svelte
Normal file
36
examples/chat-svelte/src/lib/components/ChatBubble.svelte
Normal file
@@ -0,0 +1,36 @@
|
||||
<script lang="ts">
|
||||
import BubbleBody from '$lib/components/BubbleBody.svelte';
|
||||
import BubbleContainer from '$lib/components/BubbleContainer.svelte';
|
||||
import BubbleImage from '$lib/components/BubbleImage.svelte';
|
||||
import BubbleInfo from '$lib/components/BubbleInfo.svelte';
|
||||
import BubbleText from '$lib/components/BubbleText.svelte';
|
||||
import type { Message } from '$lib/schema';
|
||||
import type { Account, Loaded } from 'jazz-tools';
|
||||
let {
|
||||
me,
|
||||
msg
|
||||
}: {
|
||||
me: Loaded<typeof Account> | null | undefined;
|
||||
msg: Loaded<typeof Message>;
|
||||
} = $props();
|
||||
const lastEdit = $derived(msg._edits.text);
|
||||
const fromMe = $derived(lastEdit?.by?.isMe);
|
||||
const { text, image } = $derived(msg);
|
||||
</script>
|
||||
|
||||
{#if me && (!me.canRead(msg) || !msg.text?.toString())}
|
||||
<BubbleContainer fromMe={false}>
|
||||
<BubbleBody fromMe={false}>
|
||||
<BubbleText text="Message not readable" className="italic text-gray-500"></BubbleText>
|
||||
</BubbleBody>
|
||||
</BubbleContainer>
|
||||
{:else}
|
||||
<BubbleContainer {fromMe}>
|
||||
<BubbleBody {fromMe}>
|
||||
{#if image}
|
||||
<BubbleImage {image} />{/if}
|
||||
<BubbleText {text} />
|
||||
</BubbleBody>
|
||||
<BubbleInfo by={lastEdit?.by?.profile?.name} madeAt={lastEdit?.madeAt || new Date()} />
|
||||
</BubbleContainer>
|
||||
{/if}
|
||||
@@ -0,0 +1,3 @@
|
||||
<div class="flex items-center justify-center h-full px-3 text-base text-stone-500 md:text-2xl">
|
||||
Start a conversation below.
|
||||
</div>
|
||||
19
examples/chat-svelte/src/lib/components/ImageIcon.svelte
Normal file
19
examples/chat-svelte/src/lib/components/ImageIcon.svelte
Normal file
@@ -0,0 +1,19 @@
|
||||
<script lang="ts">
|
||||
let { size = 24, strokeWidth = 2 } = $props();
|
||||
</script>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width={strokeWidth}
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-image-icon lucide-image"
|
||||
><rect width="18" height="18" x="3" y="3" rx="2" ry="2" /><circle cx="9" cy="9" r="2" /><path
|
||||
d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"
|
||||
/></svg
|
||||
>
|
||||
32
examples/chat-svelte/src/lib/components/ImageInput.svelte
Normal file
32
examples/chat-svelte/src/lib/components/ImageInput.svelte
Normal file
@@ -0,0 +1,32 @@
|
||||
<script lang="ts">
|
||||
import type { ChangeEventHandler } from 'svelte/elements';
|
||||
|
||||
import ImageIcon from '$lib/components/ImageIcon.svelte';
|
||||
let { onImageChange }: { onImageChange?: ChangeEventHandler<HTMLInputElement> } = $props();
|
||||
|
||||
let input = $state<HTMLInputElement>();
|
||||
|
||||
const onUploadClick = () => {
|
||||
input?.click();
|
||||
};
|
||||
</script>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Send image"
|
||||
title="Send image"
|
||||
onclick={onUploadClick}
|
||||
class="text-stone-500 p-1.5 rounded-full hover:bg-stone-100 hover:text-stone-800 dark:hover:bg-stone-800 dark:hover:text-stone-200 transition-colors"
|
||||
>
|
||||
<ImageIcon size={24} strokeWidth={1.5} />
|
||||
</button>
|
||||
|
||||
<label class="sr-only">
|
||||
Image
|
||||
<input
|
||||
bind:this={input}
|
||||
type="file"
|
||||
accept="image/png, image/jpeg, image/gif"
|
||||
onchange={onImageChange}
|
||||
/>
|
||||
</label>
|
||||
9
examples/chat-svelte/src/lib/components/InputBar.svelte
Normal file
9
examples/chat-svelte/src/lib/components/InputBar.svelte
Normal file
@@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="flex gap-1 p-3 mt-auto bg-white border-t shadow-2xl border-stone-200 dark:bg-transparent dark:border-stone-900"
|
||||
>
|
||||
{@render children()}
|
||||
</div>
|
||||
20
examples/chat-svelte/src/lib/components/TextInput.svelte
Normal file
20
examples/chat-svelte/src/lib/components/TextInput.svelte
Normal file
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
let { onSubmit }: { onSubmit: (text: string) => void } = $props();
|
||||
const inputId = $props.id();
|
||||
</script>
|
||||
|
||||
<div class="flex-1">
|
||||
<label class="sr-only" for={inputId}> Type a message and press Enter </label>
|
||||
<input
|
||||
id={inputId}
|
||||
class="block w-full px-3 py-1 border rounded-full border-stone-200 placeholder:text-stone-500 dark:bg-stone-925 dark:text-white dark:border-stone-900"
|
||||
placeholder="Type a message and press Enter"
|
||||
maxLength={2048}
|
||||
type="text"
|
||||
onkeydown={({ key, currentTarget: input }) => {
|
||||
if (key !== 'Enter' || !input.value) return;
|
||||
onSubmit(input.value);
|
||||
input.value = '';
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
9
examples/chat-svelte/src/lib/components/TopBar.svelte
Normal file
9
examples/chat-svelte/src/lib/components/TopBar.svelte
Normal file
@@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="flex justify-between w-full gap-2 p-3 bg-white border-b border-stone-200 dark:bg-transparent dark:border-stone-900"
|
||||
>
|
||||
{@render children()}
|
||||
</div>
|
||||
8
examples/chat-svelte/src/lib/schema.ts
Normal file
8
examples/chat-svelte/src/lib/schema.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { co, z } from 'jazz-tools';
|
||||
|
||||
export const Message = co.map({
|
||||
text: co.plainText(),
|
||||
image: z.optional(co.image())
|
||||
});
|
||||
|
||||
export const Chat = co.list(Message);
|
||||
16
examples/chat-svelte/src/lib/utils.ts
Normal file
16
examples/chat-svelte/src/lib/utils.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
const animals = [
|
||||
'elephant',
|
||||
'penguin',
|
||||
'giraffe',
|
||||
'octopus',
|
||||
'kangaroo',
|
||||
'dolphin',
|
||||
'cheetah',
|
||||
'koala',
|
||||
'platypus',
|
||||
'pangolin'
|
||||
];
|
||||
|
||||
export function getRandomUsername() {
|
||||
return `Anonymous ${animals[Math.floor(Math.random() * animals.length)]}`;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { ImageDefinition, type Loaded } from 'jazz-tools';
|
||||
import { onDestroy } from 'svelte';
|
||||
|
||||
export function useProgressiveImg({
|
||||
image,
|
||||
maxWidth,
|
||||
targetWidth
|
||||
}: {
|
||||
image: Loaded<typeof ImageDefinition> | null | undefined;
|
||||
maxWidth?: number;
|
||||
targetWidth?: number;
|
||||
}) {
|
||||
let current = $state<{
|
||||
src?: string;
|
||||
res?: `${number}x${number}` | 'placeholder';
|
||||
}>();
|
||||
const originalSize = $state(image?.originalSize);
|
||||
|
||||
const unsubscribe = image?.subscribe({}, (update: Loaded<typeof ImageDefinition>) => {
|
||||
const highestRes = ImageDefinition.highestResAvailable(update, { maxWidth, targetWidth });
|
||||
if (highestRes) {
|
||||
if (highestRes.res !== current?.res) {
|
||||
const blob = highestRes.stream.toBlob();
|
||||
if (blob) {
|
||||
const blobURI = URL.createObjectURL(blob);
|
||||
current = { src: blobURI, res: highestRes.res };
|
||||
|
||||
setTimeout(() => URL.revokeObjectURL(blobURI), 200);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
current = {
|
||||
src: update?.placeholderDataURL,
|
||||
res: 'placeholder'
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
onDestroy(() => () => {
|
||||
unsubscribe?.();
|
||||
});
|
||||
|
||||
return {
|
||||
get src() {
|
||||
return current?.src;
|
||||
},
|
||||
get res() {
|
||||
return current?.res;
|
||||
},
|
||||
|
||||
originalSize
|
||||
};
|
||||
}
|
||||
32
examples/chat-svelte/src/routes/+layout.svelte
Normal file
32
examples/chat-svelte/src/routes/+layout.svelte
Normal file
@@ -0,0 +1,32 @@
|
||||
<script lang="ts">
|
||||
import 'jazz-tools/inspector/register-custom-element';
|
||||
|
||||
import '../app.css';
|
||||
import { JazzSvelteProvider } from 'jazz-tools/svelte';
|
||||
import { apiKey } from '../apiKey';
|
||||
import { getRandomUsername } from '$lib/utils';
|
||||
let { children } = $props();
|
||||
const defaultProfileName = getRandomUsername();
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Jazz Chat Example</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="h-full bg-white text-stone-700 dark:text-stone-400 dark:bg-stone-925">
|
||||
<JazzSvelteProvider
|
||||
sync={{
|
||||
peer: `wss://cloud.jazz.tools/?key=${apiKey}`
|
||||
}}
|
||||
{defaultProfileName}
|
||||
>
|
||||
{@render children?.()}
|
||||
</JazzSvelteProvider>
|
||||
<jazz-inspector></jazz-inspector>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:global(html, body) {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
16
examples/chat-svelte/src/routes/+page.svelte
Normal file
16
examples/chat-svelte/src/routes/+page.svelte
Normal file
@@ -0,0 +1,16 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { Chat } from '$lib/schema';
|
||||
import { AccountCoState } from 'jazz-tools/svelte';
|
||||
import { Account, Group } from 'jazz-tools';
|
||||
|
||||
const account = new AccountCoState(Account);
|
||||
const me = $derived(account.current);
|
||||
$effect(() => {
|
||||
if (!me) return;
|
||||
const group = Group.create();
|
||||
group.addMember('everyone', 'writer');
|
||||
const chat = Chat.create([], group);
|
||||
goto(`/chat/${chat.id}`);
|
||||
});
|
||||
</script>
|
||||
116
examples/chat-svelte/src/routes/chat/[id]/+page.svelte
Normal file
116
examples/chat-svelte/src/routes/chat/[id]/+page.svelte
Normal file
@@ -0,0 +1,116 @@
|
||||
<script lang="ts">
|
||||
import { createImage } from 'jazz-tools/browser-media-images';
|
||||
import { AccountCoState, CoState } from 'jazz-tools/svelte';
|
||||
import { Account, CoPlainText, type ID } from 'jazz-tools';
|
||||
|
||||
import { page } from '$app/state';
|
||||
|
||||
import { Chat, Message } from '$lib/schema';
|
||||
|
||||
import AppContainer from '$lib/components/AppContainer.svelte';
|
||||
import ChatBody from '$lib/components/ChatBody.svelte';
|
||||
import ChatBubble from '$lib/components/ChatBubble.svelte';
|
||||
import EmptyChatMessage from '$lib/components/EmptyChatMessage.svelte';
|
||||
import ImageInput from '$lib/components/ImageInput.svelte';
|
||||
import InputBar from '$lib/components/InputBar.svelte';
|
||||
import TopBar from '$lib/components/TopBar.svelte';
|
||||
import TextInput from '$lib/components/TextInput.svelte';
|
||||
|
||||
const chatId = $derived(page.params.id) as ID<typeof Chat>;
|
||||
const chat = $derived(
|
||||
new CoState(Chat, chatId, {
|
||||
resolve: {
|
||||
$each: {
|
||||
text: true
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
const account = new AccountCoState(Account, {
|
||||
resolve: {
|
||||
profile: true
|
||||
}
|
||||
});
|
||||
const me = $derived(account.current);
|
||||
let showNLastMessages = $state(30);
|
||||
const sendImage = (event: Event & { currentTarget: HTMLInputElement }) => {
|
||||
const file = event.currentTarget.files?.[0];
|
||||
|
||||
if (!file || !chat.current) return;
|
||||
|
||||
if (file.size > 5000000) {
|
||||
alert('Please upload an image less than 5MB.');
|
||||
return;
|
||||
}
|
||||
|
||||
createImage(file, { owner: chat.current._owner }).then((image) => {
|
||||
if (!chat.current) return;
|
||||
chat.current.push(
|
||||
Message.create(
|
||||
{
|
||||
text: CoPlainText.create(file.name, chat.current._owner),
|
||||
image: image
|
||||
},
|
||||
chat.current._owner
|
||||
)
|
||||
);
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<AppContainer>
|
||||
<TopBar>
|
||||
<input
|
||||
type="text"
|
||||
value={me?.profile?.name ?? ''}
|
||||
class="bg-transparent"
|
||||
onchange={(e) => {
|
||||
if (!me?.profile) return;
|
||||
const target = e.target as HTMLInputElement;
|
||||
me.profile.name = target.value;
|
||||
}}
|
||||
placeholder="Set username"
|
||||
/>
|
||||
<button
|
||||
onclick={() => {
|
||||
account.logOut();
|
||||
window.location.reload(); // Otherwise the provider will not update with default profile name
|
||||
}}>Log out</button
|
||||
>
|
||||
</TopBar>
|
||||
{#if !chat}
|
||||
<div class="flex items-center justify-center flex-1">Loading...</div>
|
||||
{:else}
|
||||
<ChatBody>
|
||||
{#if chat.current && chat.current.length > 0}
|
||||
{#each chat.current.slice(-showNLastMessages).reverse() as msg (msg.id)}
|
||||
<ChatBubble {me} {msg} />
|
||||
{/each}
|
||||
{:else}
|
||||
<EmptyChatMessage />
|
||||
{/if}
|
||||
{#if chat.current && chat.current.length > showNLastMessages}
|
||||
<button
|
||||
class="block px-4 py-1 mx-auto my-2 border rounded"
|
||||
onclick={() => (showNLastMessages += 10)}
|
||||
>
|
||||
Show more
|
||||
</button>
|
||||
{/if}
|
||||
</ChatBody>
|
||||
<InputBar>
|
||||
<ImageInput onImageChange={sendImage} />
|
||||
<TextInput
|
||||
onSubmit={(text: string) => {
|
||||
if (!chat.current) return;
|
||||
chat.current.push(
|
||||
Message.create(
|
||||
{ text: CoPlainText.create(text, chat.current._owner) },
|
||||
chat.current._owner
|
||||
)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</InputBar>
|
||||
{/if}
|
||||
</AppContainer>
|
||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
39
examples/chat-svelte/tests/chat.spec.ts
Normal file
39
examples/chat-svelte/tests/chat.spec.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { ChatPage } from './pages/ChatPage';
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
test('chat works between two windows', async ({ page: marioPage, browser }) => {
|
||||
await marioPage.goto('/');
|
||||
const context = await browser.newContext();
|
||||
const luigiPage = await context.newPage();
|
||||
|
||||
await marioPage.waitForURL('/chat/**');
|
||||
const roomUrl = marioPage.url();
|
||||
await luigiPage.goto(roomUrl);
|
||||
|
||||
const marioChat = new ChatPage(marioPage);
|
||||
const luigiChat = new ChatPage(luigiPage);
|
||||
|
||||
|
||||
await marioChat.setUsername('Mario');
|
||||
|
||||
const message1ByMario = 'Hello Luigi, are you ready to save the princess?';
|
||||
|
||||
await marioChat.sendMessage(message1ByMario);
|
||||
await marioChat.expectMessageRow(message1ByMario);
|
||||
|
||||
const roomURL = marioPage.url();
|
||||
await luigiPage.goto(roomURL);
|
||||
|
||||
await luigiChat.setUsername('Luigi');
|
||||
|
||||
await luigiChat.expectMessageRow(message1ByMario);
|
||||
|
||||
const message2ByLuigi = "No, I'm not ready yet. I'm still trying to find the key to the castle.";
|
||||
|
||||
await luigiChat.sendMessage(message2ByLuigi);
|
||||
await luigiChat.expectMessageRow(message2ByLuigi);
|
||||
|
||||
await marioChat.expectMessageRow(message1ByMario);
|
||||
await luigiChat.expectMessageRow(message2ByLuigi);
|
||||
await context.close();
|
||||
});
|
||||
41
examples/chat-svelte/tests/pages/ChatPage.ts
Normal file
41
examples/chat-svelte/tests/pages/ChatPage.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { type Locator, type Page, expect } from '@playwright/test';
|
||||
|
||||
export class ChatPage {
|
||||
readonly page: Page;
|
||||
readonly messageInput: Locator;
|
||||
readonly logoutButton: Locator;
|
||||
readonly usernameInput: Locator;
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.messageInput = page.getByRole('textbox', {
|
||||
name: 'Type a message and press Enter'
|
||||
});
|
||||
this.logoutButton = page.getByRole('button', {
|
||||
name: 'Log out'
|
||||
});
|
||||
this.usernameInput = page.getByPlaceholder('Set username');
|
||||
}
|
||||
|
||||
async setUsername(username: string) {
|
||||
await this.usernameInput.fill(username);
|
||||
}
|
||||
|
||||
async sendMessage(message: string) {
|
||||
await this.messageInput.fill(message);
|
||||
await this.messageInput.press('Enter');
|
||||
}
|
||||
|
||||
async expectMessageRow(message: string) {
|
||||
await expect(this.page.getByText(message)).toBeVisible();
|
||||
}
|
||||
|
||||
async expectUserNameNotToBeAnonymousUser() {
|
||||
await expect(this.usernameInput).not.toHaveValue(/anonymous user/i);
|
||||
await expect(this.usernameInput).toHaveValue(/^Anonymous \w+/);
|
||||
}
|
||||
|
||||
async logout() {
|
||||
await this.logoutButton.click();
|
||||
await this.page.goto('/');
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig } from 'vite';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()]
|
||||
plugins: [tailwindcss(), sveltekit()]
|
||||
});
|
||||
1
examples/chat-vue/.gitignore
vendored
1
examples/chat-vue/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
dist
|
||||
File diff suppressed because it is too large
Load Diff
1
examples/chat-vue/env.d.ts
vendored
1
examples/chat-vue/env.d.ts
vendored
@@ -1 +0,0 @@
|
||||
/// <reference types="vite/client" />
|
||||
@@ -1,13 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="./public/favicon.ico" type="image/png">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Jazz Chat Vue Example</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"name": "chat-vue",
|
||||
"version": "0.0.115",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build-type-check": "run-p type-check \"build {@}\" --",
|
||||
"preview": "vite preview",
|
||||
"build": "vite build",
|
||||
"type-check": "vue-tsc --build --force",
|
||||
"format-and-lint": "biome check .",
|
||||
"format-and-lint:fix": "biome check . --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-browser": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"jazz-vue": "workspace:*",
|
||||
"vue": "^3.5.11",
|
||||
"vue-router": "^4.4.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node20": "^20.1.4",
|
||||
"@types/node": "^22.5.1",
|
||||
"@vitejs/plugin-vue": "^5.1.4",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^9.7.0",
|
||||
"eslint-plugin-vue": "^9.28.0",
|
||||
"npm-run-all2": "^6.2.3",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "6.0.11",
|
||||
"vite-plugin-vue-devtools": "^7.4.6",
|
||||
"vue-tsc": "^2.1.6"
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<AppContainer>
|
||||
<TopBar v-if="me">
|
||||
<p>{{ me.profile?.name }}</p>
|
||||
<button @click="logOut">Log out</button>
|
||||
</TopBar>
|
||||
<router-view />
|
||||
</AppContainer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAccount } from "jazz-vue";
|
||||
import AppContainer from "./components/AppContainer.vue";
|
||||
import TopBar from "./components/TopBar.vue";
|
||||
|
||||
const { me, logOut } = useAccount();
|
||||
</script>
|
||||
@@ -1 +0,0 @@
|
||||
export const apiKey = "chat-example-jazz@garden.co";
|
||||
@@ -1,74 +0,0 @@
|
||||
/* color palette from <https://github.com/vuejs/theme> */
|
||||
:root {
|
||||
--vt-c-white: #ffffff;
|
||||
--vt-c-white-soft: #f8f8f8;
|
||||
--vt-c-white-mute: #f2f2f2;
|
||||
|
||||
--vt-c-black: #181818;
|
||||
--vt-c-black-soft: #222222;
|
||||
--vt-c-black-mute: #282828;
|
||||
|
||||
--vt-c-indigo: #2c3e50;
|
||||
|
||||
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
|
||||
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
|
||||
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
|
||||
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
|
||||
|
||||
--vt-c-text-light-1: var(--vt-c-indigo);
|
||||
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
|
||||
--vt-c-text-dark-1: var(--vt-c-white);
|
||||
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
|
||||
}
|
||||
|
||||
/* semantic color variables for this project */
|
||||
:root {
|
||||
--color-background: var(--vt-c-white);
|
||||
--color-background-soft: var(--vt-c-white-soft);
|
||||
--color-background-mute: var(--vt-c-white-mute);
|
||||
|
||||
--color-border: var(--vt-c-divider-light-2);
|
||||
--color-border-hover: var(--vt-c-divider-light-1);
|
||||
|
||||
--color-heading: var(--vt-c-text-light-1);
|
||||
--color-text: var(--vt-c-text-light-1);
|
||||
|
||||
--section-gap: 160px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--color-background: var(--vt-c-black);
|
||||
--color-background-soft: var(--vt-c-black-soft);
|
||||
--color-background-mute: var(--vt-c-black-mute);
|
||||
|
||||
--color-border: var(--vt-c-divider-dark-2);
|
||||
--color-border-hover: var(--vt-c-divider-dark-1);
|
||||
|
||||
--color-heading: var(--vt-c-text-dark-1);
|
||||
--color-text: var(--vt-c-text-dark-2);
|
||||
}
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
color: var(--color-text);
|
||||
background: var(--color-background);
|
||||
transition: color 0.5s, background-color 0.5s;
|
||||
line-height: 1.6;
|
||||
font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||
Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
font-size: 15px;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user