Compare commits

..

430 Commits

Author SHA1 Message Date
Anselm Eickhoff
1baf60d660 Tighter slogan supported by kicker 2025-01-08 17:33:05 +00:00
Anselm
cad1b0ea43 Add connection between CoValues and local-first state 2025-01-08 16:02:42 +00:00
Anselm
473da86cca hermo improvements and start adding git comparison to narrative 2025-01-08 11:37:19 +00:00
Guido D'Orsi
5669e346f8 test: remove flaky tests 2025-01-07 14:05:45 +01:00
Guido D'Orsi
97e7c7ce13 Merge pull request #1077 from garden-co/perf-bulk-operations
feat: add the assign method to RawCoMap to create bulk transactions and optimize RawCoMap init
2025-01-07 14:03:52 +01:00
Guido D'Orsi
7fea37b0a3 Merge pull request #1081 from garden-co/coList-appendItems
feat: add the appendItems method to CoList to add many items in a single transaction
2025-01-07 14:03:37 +01:00
Guido D'Orsi
b97a0954b2 Merge pull request #1143 from garden-co/fix/rn-key-username
fix(DemoAuth): fix username key serialization
2025-01-07 13:33:12 +01:00
github-actions[bot]
459eafccd0 Version Packages 2025-01-07 12:21:13 +00:00
Guido D'Orsi
816333a4a8 fix: handle re-login after an auth failure 2025-01-07 13:20:56 +01:00
Guido D'Orsi
b6345ac469 fix: Fix the double context creation in React development mode 2025-01-07 13:12:39 +01:00
Guido D'Orsi
9f01d9c73a fix: improve error management when loading existing accounts 2025-01-07 13:08:52 +01:00
Guido D'Orsi
1da4d558b1 fix(DemoAuth): fix username key serialization 2025-01-07 12:56:21 +01:00
Anselm Eickhoff
559e3360a4 Merge pull request #1141 from garden-co/jazz-626-move-book-shelf-example-into-personal-repo
Remove book shelf app
2025-01-07 11:48:07 +00:00
Guido D'Orsi
be922788f6 Merge pull request #1140 from garden-co/fix/react-starter
Fix: missing dependencies in react starter
2025-01-07 12:36:44 +01:00
Trisha Lim
09d32ee5f2 Add changeset 2025-01-07 11:17:12 +00:00
Trisha Lim
0547ea823d Remove book shelf app 2025-01-07 11:16:53 +00:00
Trisha Lim
a7aa70bd8f Fix: missing dependencies in react starter 2025-01-07 11:04:37 +00:00
Guido D'Orsi
ee9f868bb4 chore: use pnpm to run the prepublishOnly hook 2025-01-07 11:59:07 +01:00
Guido D'Orsi
133abd5d8f Merge pull request #1125 from garden-co/changeset-release/main
Version Packages
2025-01-07 11:47:02 +01:00
github-actions[bot]
1a789717f0 Version Packages 2025-01-07 10:15:13 +00:00
Trisha Lim
d4d98c4b48 Create react starter app for create-jazz-app (#1112) 2025-01-07 10:14:02 +00:00
Guido D'Orsi
51d8fb7e77 Merge pull request #1127 from tobiaslins/fix-chat-rn-example
[react native] Fix permissions of messages and fix chat loading
2025-01-03 18:03:16 +01:00
Tobias Lins
315a00bcb5 Update chat.tsx 2025-01-03 14:42:17 +01:00
Tobias Lins
ed4ee686b5 Fix permissions of messages and fix chat loading 2025-01-03 14:38:44 +01:00
Anselm Eickhoff
b4dc466526 Merge pull request #1120 from garden-co/jazz-608-add-version-history-example-app
Add version history example app
2025-01-03 11:27:10 +00:00
Trisha Lim
af9ea3dc4b Change key type to string 2025-01-03 11:21:44 +00:00
Guido D'Orsi
67abc0e437 Merge pull request #1103 from garden-co/jazz-616-simplify-the-create-calls-by-accepting-account-group-as
feat: simplify the .create calls by accepting Account | Group as second param
2025-01-03 11:54:07 +01:00
Guido D'Orsi
2034ef2dcb Merge pull request #1123 from garden-co/changeset-release/main
Version Packages
2025-01-02 22:31:49 +01:00
github-actions[bot]
343b4c0c80 Version Packages 2025-01-02 21:30:25 +00:00
Guido D'Orsi
41e4083f97 Merge pull request #1124 from garden-co/fix-range-error-flatMap
fix: handle circular references in group inheritance
2025-01-02 22:29:16 +01:00
Guido D'Orsi
15f81e889f fix: handle circular references in group inheritance 2025-01-02 22:18:12 +01:00
Guido D'Orsi
8d7fb18a08 Merge pull request #1122 from garden-co/fix-range-error-flatMap
fix(permissions): fix group self-extension
2025-01-02 21:24:40 +01:00
Guido D'Orsi
43378ef2b7 fix(permissions): fix group self-extension 2025-01-02 21:20:35 +01:00
Trisha Lim
1ca1d15639 Update readme 2025-01-02 18:04:34 +00:00
Trisha Lim
bdd67ef34d Add version history example to examples page 2025-01-02 17:55:10 +00:00
Trisha Lim
dc62b9569b Add changeset 2025-01-02 17:55:10 +00:00
Trisha Lim
6fd920face Add verstion history example app 2025-01-02 17:55:10 +00:00
Guido D'Orsi
0689ed3767 Merge pull request #1121 from garden-co/changeset-release/main
Version Packages
2025-01-02 18:35:58 +01:00
github-actions[bot]
a4e1aa7f56 Version Packages 2025-01-02 17:35:18 +00:00
Guido D'Orsi
ca5d7cb2ee Merge pull request #1119 from garden-co/fix-range-error-flatMap
fix(permissions): fixes the transactions collection to avoid RangeError issues
2025-01-02 18:34:10 +01:00
Guido D'Orsi
25dfd90c5a fix(permissions): fixes the transactions collection to avoid RangeError issues 2025-01-02 18:25:53 +01:00
Guido D'Orsi
66badc061e Merge pull request #1099 from garden-co/changeset-release/main
Version Packages
2025-01-02 16:31:02 +01:00
github-actions[bot]
eecdd5215e Version Packages 2025-01-02 13:48:31 +00:00
Guido D'Orsi
99b9605579 Merge pull request #1094 from garden-co/jazz-612-give-the-ability-to-reader-writer-and-writeonly-roles-to-set
feat: give the ability to extend a group to users that have any access to the parent
2025-01-02 14:47:13 +01:00
Guido D'Orsi
830f0c00ca Merge pull request #1116 from garden-co/fix/load-with-empty-schema
fix(CoMap): fix loading of CoMaps with an empty schema
2025-01-02 14:17:41 +01:00
Guido D'Orsi
635e824eb0 fix(CoMap): fix loading of CoMaps with an empty schema 2025-01-02 14:14:25 +01:00
Trisha Lim
c2a55c09e0 Fix indention 2025-01-02 12:59:50 +00:00
Trisha Lim
33b64743ed Make preview interactive in react guide 2025-01-02 12:59:50 +00:00
Trisha Lim
74a419e2df Add comment 2025-01-02 12:59:12 +00:00
Trisha Lim
170e135c79 Remove render-code-samples from turbo.json 2025-01-02 12:59:12 +00:00
Trisha Lim
305917236e Exclude h1 from table of contents 2025-01-02 12:59:12 +00:00
Guido D'Orsi
71e881afcb Merge pull request #1109 from garden-co/fix/missing-titles
Add titles to doc pages
2025-01-02 10:44:17 +01:00
Trisha Lim
f32af158f0 Add titles to doc pages 2024-12-31 15:13:47 +00:00
Anselm Eickhoff
e0d9bb3db3 Merge pull request #1105 from garden-co/jazz-615-remove-demo-and-code-from-examples 2024-12-30 15:24:22 +00:00
Guido D'Orsi
93f73b3b86 Merge pull request #1069 from garden-co/jazz-598-add-form-design-pattern-to-docs
Add form design pattern to docs
2024-12-30 16:10:59 +01:00
Guido D'Orsi
7e96af0602 Merge pull request #1106 from garden-co/jazz-613-add-docs-for-create-jazz-app
Mention create-jazz-app in docs
2024-12-30 16:10:11 +01:00
Trisha Lim
3a5d8d1ff4 Remove example demos 2024-12-30 14:55:19 +00:00
Trisha Lim
d558c085e6 Mention create-jazz-app in docs 2024-12-30 14:53:14 +00:00
Trisha Lim
07e52f50b3 Remove sentence about list of orders 2024-12-30 14:40:19 +00:00
Trisha Lim
9a775c67d5 Link to docs from example readme 2024-12-30 14:35:25 +00:00
Trisha Lim
a64d05f9a5 Simplify form design pattern docs 2024-12-30 14:30:10 +00:00
Trisha Lim
e43a6d4418 Address feedback 2024-12-30 11:56:34 +00:00
Trisha Lim
70182c5b28 Add form design pattern to docs 2024-12-30 11:56:34 +00:00
Guido D'Orsi
1de26f8be9 feat: simplify the .create calls by accepting Account | Group as second param 2024-12-30 12:11:51 +01:00
Anselm Eickhoff
af6c0878c3 Merge pull request #1101 from garden-co/gcmp-hp-fixes
More blog fixes
2024-12-30 11:01:45 +00:00
Anselm
579384a6df Update socials 2024-12-30 10:50:08 +00:00
Anselm
3376a02fde Fix OG pictures 2024-12-30 10:09:33 +00:00
Anselm Eickhoff
8440699193 Merge pull request #1091 from garden-co/jazz-611-missing-inbox-error 2024-12-29 15:12:04 +00:00
Anselm Eickhoff
d7f4ba5b9e Merge pull request #1098 from garden-co/docs/collapse-auth-items 2024-12-29 12:38:03 +00:00
Anselm Eickhoff
58a785db40 Merge pull request #1097 from garden-co/explode-docs-nav 2024-12-29 12:37:51 +00:00
Trisha Lim
7546e8bffc Docs side nav: move examples higher, collapse auth items 2024-12-29 11:03:41 +00:00
Trisha Lim
ad57ac21e0 Fix mock button alignment 2024-12-29 10:54:02 +00:00
Trisha Lim
f8b9854286 Move examples and api nav items to top level 2024-12-29 10:53:27 +00:00
Guido D'Orsi
10ea7332e6 feat: give the ability to extend a group to users that have any access to the parent 2024-12-27 21:16:50 +01:00
Guido D'Orsi
0a859821bc feat(Account): remove the requirement of calling super.migrate when defining the account migration 2024-12-27 11:35:14 +01:00
Anselm
b9408c6119 Fix OG some more 2024-12-26 16:25:10 +00:00
Anselm
c6c26b0ad1 Fix metadata 2024-12-26 16:23:31 +00:00
Anselm Eickhoff
9527c8a019 Merge pull request #1090 from garden-co/gcmp-hp-fixes
Soft-launch first blog post
2024-12-26 16:18:51 +00:00
Anselm
69bdcc0273 Fix type errors 2024-12-26 16:15:33 +00:00
Anselm
62cfd3bce4 Soft-launch first blog post 2024-12-26 16:09:22 +00:00
Guido D'Orsi
edf6328905 Merge pull request #1085 from garden-co/jazz-602-theme-doesnt-update-when-system-theme-changes
Fix: Theme doesn't update when system theme changes
2024-12-24 21:12:05 +01:00
Guido D'Orsi
1d2b8d92d7 Merge pull request #1088 from garden-co/changeset-release/main
Version Packages
2024-12-24 20:33:14 +01:00
github-actions[bot]
697dd370ee Version Packages 2024-12-24 17:52:12 +00:00
Guido D'Orsi
33ef9c43d0 chore: changeset 2024-12-24 18:51:02 +01:00
Guido D'Orsi
f74134164b Merge pull request #1087 from boorad/feat/demo-auth-byo-store
feat: Bring Your Own Store to demo auth
2024-12-24 18:49:12 +01:00
Brad Anderson
50939729e5 feat: Bring Your Own Store to demo auth 2024-12-24 09:56:15 -05:00
Trisha Lim
dcf945b514 Fix: Theme doesn't update when system theme changes 2024-12-24 14:54:25 +01:00
Anselm
0b8425d9b4 Blog prep 2024-12-24 09:31:10 +00:00
Guido D'Orsi
986805dcba Merge pull request #1079 from garden-co/jazz-606-chat-demo-dark-mode-doesnt-enable
Fix chat app dark mode
2024-12-24 10:17:48 +01:00
Trisha Lim
89dae1d889 Fix dark bg color 2024-12-24 09:49:58 +01:00
Trisha Lim
c3418f6bed Fix tailwind styles in chat app 2024-12-24 09:41:20 +01:00
Trisha Lim
f5a63d13c1 Remove unused packages 2024-12-24 09:39:47 +01:00
Trisha Lim
e9778cc4ca Remove commas 2024-12-24 09:36:46 +01:00
Trisha Lim
7d955d053e Fix chat app dark mode 2024-12-24 09:36:46 +01:00
Guido D'Orsi
ae6d2c6daf Merge pull request #1084 from garden-co/changeset-release/main
Version Packages
2024-12-24 00:48:08 +01:00
github-actions[bot]
44aa86978f Version Packages 2024-12-23 23:44:15 +00:00
Guido D'Orsi
eedb208e4c Merge pull request #1056 from garden-co/changeset-release/main
Version Packages
2024-12-24 00:42:41 +01:00
github-actions[bot]
454fbbfc17 Version Packages 2024-12-23 23:41:44 +00:00
Guido D'Orsi
686e3e998c Merge pull request #1070 from garden-co/fix/move-account-data-to-root
Form example: move account data to root
2024-12-24 00:41:30 +01:00
Guido D'Orsi
7a2f249614 Merge pull request #1078 from garden-co/fix-rn-demo-auth-ke
fix(demo-auth): fix the user credentials storage when the username contains non aplhanumeric characters
2024-12-24 00:41:01 +01:00
Guido D'Orsi
59a0c86dd1 Merge pull request #1083 from garden-co/quick-crypto-as-opt-in
fix: restore PureJSCrypto as default and make RNQuickCrypto an opt-in import
2024-12-24 00:40:44 +01:00
Guido D'Orsi
7701307ab7 fix: restore PureJSCrypto as default and make RNQuickCrypto an opt-in import 2024-12-24 00:40:03 +01:00
Guido D'Orsi
1e7dadd31b Merge pull request #917 from boorad/feat/quick-crypto
feat: add `react-native-quick-crypto` for `ed25519`
2024-12-23 23:34:27 +01:00
Brad Anderson
b57bb88328 feat: add react-native-quick-crypto for ed25519 2024-12-23 17:28:17 -05:00
Guido D'Orsi
afd25d766f chore: remove comment 2024-12-23 19:12:21 +01:00
Guido D'Orsi
222f8c5063 test(chat): uncomment test code 2024-12-23 19:11:58 +01:00
Guido D'Orsi
857e0d5c48 Merge pull request #1045 from garden-co/jazz-596-add-organization-design-pattern-to-docs
Add Organization example app
2024-12-23 19:05:22 +01:00
Guido D'Orsi
be903ede57 Merge remote-tracking branch 'origin/main' into jazz-596-add-organization-design-pattern-to-docs 2024-12-23 19:02:11 +01:00
Guido D'Orsi
9b654ad1fb Merge pull request #1010 from garden-co/jazz-93-inbox-abstraction
feat: Inbox, a new experimental API to simplfy the communication with Workers
2024-12-23 18:59:18 +01:00
Guido D'Orsi
a7bc15fdf2 fix(DemoAuth): serialize username with base64 and handle key migrations 2024-12-23 18:55:57 +01:00
Guido D'Orsi
0489d4a894 feat: add the appendItems method to CoList to add many items in a single transaction 2024-12-23 12:35:55 +01:00
Guido D'Orsi
1ef3226ed8 feat: add the assign method to RawCoMap to create bulk transactions and optimize RawCoMap init 2024-12-23 11:09:23 +01:00
Guido D'Orsi
e14a2c0a5d Merge pull request #1071 from garden-co/fix/create-invite-from-account
fix: throw an error if an invite is create from an account owned CoValue
2024-12-23 11:04:54 +01:00
Guido D'Orsi
6a7ef2ba60 Merge pull request #1076 from garden-co/skipverify
perf: skip verify step when creating a new local transaction
2024-12-23 11:04:11 +01:00
Anselm
94d95ceeb6 Fix garden logo, planned dates 2024-12-23 08:55:17 +00:00
Guido D'Orsi
ab4ffbd130 fix(demo-auth): slugify the username when creating a storage key 2024-12-21 01:54:04 +01:00
Guido D'Orsi
e322e6034b fix: fix e2e rn login 2024-12-21 01:49:27 +01:00
Guido D'Orsi
bbf49ae7cd fix: fix chat-rn styles 2024-12-21 01:37:52 +01:00
Guido D'Orsi
04bcf94ae4 fix: fix chat-rn build 2024-12-21 01:21:01 +01:00
Guido D'Orsi
22ad297e4b Merge pull request #1067 from garden-co/fix/update-deps
fix: update lockfile to fix RN build
2024-12-21 01:16:17 +01:00
Guido D'Orsi
2ee58780a5 chore: remove console.log from tests 2024-12-21 01:14:13 +01:00
Guido D'Orsi
fca6a0bfc2 perf: skip verify step when creating a new local transaction 2024-12-21 00:19:24 +01:00
Guido D'Orsi
6f0bd7f5ea fix: throw an error if an invite is create from an account owned CoValue 2024-12-20 17:52:16 +01:00
Trisha Lim
4dea285879 Form example: move account data to root 2024-12-20 16:30:00 +00:00
Guido D'Orsi
0c68349a27 feat: added RPC style response management 2024-12-20 17:06:34 +01:00
Guido D'Orsi
e761a8e5d5 fix lockfile 2024-12-20 14:55:26 +01:00
Guido D'Orsi
45c1e113ea fix: update lockfile to fix RN build 2024-12-20 13:50:41 +01:00
Guido D'Orsi
88d7d9add0 feat: Inbox, a new experimental API to simplfy the initial handshake between accounts 2024-12-20 11:41:20 +01:00
Guido D'Orsi
36d3be25a1 Merge pull request #1061 from garden-co/fix/jazz-run-json
fix: fix --json option on the account create command
2024-12-19 18:23:53 +01:00
Guido D'Orsi
99e731d6f8 fix: fix --json option on the account create command 2024-12-19 18:22:37 +01:00
pax-k
0027bc73b5 fix: create-jazz-app correctly sets metro.config.js for expo starter 2024-12-19 18:41:01 +02:00
Anselm Eickhoff
2304412c20 Merge pull request #1057 from garden-co/docs/invite-link
Add docs for generating invite links and public sharing
2024-12-19 16:10:26 +00:00
Trisha Lim
b697b91f1d Address feedback 2024-12-19 16:03:33 +00:00
Trisha Lim
6694dbc53f Address feedback 2024-12-19 15:49:21 +00:00
Trisha Lim
af9eb02d46 Add docs for generating invite links and public sharing 2024-12-19 15:16:43 +00:00
Guido D'Orsi
4e8c70f8d9 Merge pull request #1055 from garden-co/fix/circular-deps
fix(jazz-tools): add a bundle step to fix the circular deps issue
2024-12-19 15:46:08 +01:00
Guido D'Orsi
fa41f8eec2 fix(jazz-tools): add a bundle step to not expose the circular deps to users 2024-12-19 15:42:02 +01:00
Guido D'Orsi
60e35eab71 fix(jazz-tools): reduce the amount of circular deps 2024-12-19 15:29:45 +01:00
Guido D'Orsi
80f563e4f0 Merge pull request #1053 from garden-co/changeset-release/main
Version Packages
2024-12-19 13:13:34 +01:00
github-actions[bot]
c321d99ec6 Version Packages 2024-12-19 12:13:04 +00:00
Guido D'Orsi
135fa2d164 Merge pull request #1052 from garden-co/fix/logging
feat: Add an internal API to disable the permission errors logs
2024-12-19 13:11:50 +01:00
Guido D'Orsi
5d20c81ed5 feat: Add an API to disable the permission errors logs 2024-12-19 13:08:03 +01:00
Trisha Lim
8ee6db5102 Add organization example to docs 2024-12-19 11:58:24 +00:00
Trisha Lim
a8e7f52700 Move css out of .css file 2024-12-19 11:17:01 +00:00
Trisha Lim
1e6f6fce53 Clean up 2024-12-19 11:17:01 +00:00
Trisha Lim
025dfaedc4 Reset url on logout 2024-12-19 11:17:01 +00:00
Trisha Lim
d681aa242a Set title 2024-12-19 11:17:01 +00:00
Trisha Lim
a4f0a0737e Home page UI improvements 2024-12-19 11:17:01 +00:00
Trisha Lim
4583401502 Dark mode 2024-12-19 11:17:00 +00:00
Trisha Lim
99a614038d Form styling 2024-12-19 11:17:00 +00:00
Trisha Lim
762d1fac23 Remove AddMember 2024-12-19 11:17:00 +00:00
Trisha Lim
9d7fabb1cf Remove draft project 2024-12-19 11:17:00 +00:00
Trisha Lim
7c9a872f50 Fix project permissions 2024-12-19 11:17:00 +00:00
Trisha Lim
9ed8dd509b UI improvements 2024-12-19 11:17:00 +00:00
Trisha Lim
0d771b9acc UI improvements 2024-12-19 11:17:00 +00:00
Trisha Lim
3e191685e4 UI improvements 2024-12-19 11:17:00 +00:00
Trisha Lim
7b2fd31a75 Organize directory structure 2024-12-19 11:17:00 +00:00
Trisha Lim
dda7c243d7 Add new org to list after invite accept 2024-12-19 11:17:00 +00:00
Trisha Lim
cce6a2f243 Invite org members through link 2024-12-19 11:17:00 +00:00
Trisha Lim
63001da65a Fix ownership bugs
modified:   src/schema.ts
2024-12-19 11:17:00 +00:00
Trisha Lim
b094605109 Adding members to org 2024-12-19 11:16:59 +00:00
Trisha Lim
e4bc39ed21 Change ownership to group 2024-12-19 11:16:59 +00:00
Trisha Lim
67d4f538ec Revert 2024-12-19 11:16:59 +00:00
Trisha Lim
f5b527886f Add "create org" dropdown option 2024-12-19 11:16:59 +00:00
Trisha Lim
dba767ae7b Change layout 2024-12-19 11:16:59 +00:00
Trisha Lim
bb39c0b7fa Add projects under an organization 2024-12-19 11:16:59 +00:00
Trisha Lim
57c846a904 Routing for organization page 2024-12-19 11:16:59 +00:00
Trisha Lim
4390d4b266 use react router 2024-12-19 11:16:59 +00:00
Trisha Lim
1427f071d4 Form for creating an org 2024-12-19 11:16:59 +00:00
Trisha Lim
2d31e8edce Create schema 2024-12-19 11:16:59 +00:00
Trisha Lim
09cad40565 Add project for organization example app 2024-12-19 11:16:58 +00:00
pax-k
3accbc06e2 chore: add build step to release workflow (debug) 2024-12-18 21:58:25 +02:00
pax-k
39ae4fc8c1 chore: enable tmate debugging on gh workflow failure 2024-12-18 21:13:01 +02:00
Guido D'Orsi
ae60eb0d01 Merge pull request #1050 from garden-co/fix/remove-local-server-e2e
test(e2e): run tests against our cloud
2024-12-18 17:09:29 +01:00
Guido D'Orsi
05eb330173 Merge pull request #1019 from garden-co/form-example-test
Add test for form example
2024-12-18 16:36:03 +01:00
Guido D'Orsi
5d1e192245 test(e2e): run tests against our cloud 2024-12-18 16:34:59 +01:00
Anselm Eickhoff
c5e059b3a9 Merge pull request #1048 from garden-co/docs/org-design-pattern
Add organization design pattern to docs
2024-12-18 15:24:37 +00:00
Trisha Lim
d1785c0178 Address feedback 2024-12-18 15:14:12 +00:00
pax
9b95c32edb Merge pull request #1049 from garden-co/changeset-release/main
Version Packages
2024-12-18 17:08:52 +02:00
github-actions[bot]
d87781d33f Version Packages 2024-12-18 15:04:52 +00:00
pax
ad50ec2d9d Merge pull request #1047 from garden-co/create-jazz-app
create-jazz-app
2024-12-18 17:03:50 +02:00
Trisha Lim
fef055b9fb Add organization design pattern to docs 2024-12-18 14:20:10 +00:00
pax-k
cdc7f9f841 chore: changeset 2024-12-18 14:56:28 +02:00
pax-k
ff6940de56 chore: bumped jazz-react-native-auth-clerk 2024-12-18 14:52:44 +02:00
pax-k
cad54e4018 chore: upgraded nativewind to 4.x 2024-12-18 14:52:31 +02:00
pax-k
c657880a22 chore: small adjustments 2024-12-18 14:51:54 +02:00
pax-k
79b02dee3c chore: added readme for create-jazz-app 2024-12-18 14:51:35 +02:00
pax-k
ee29cb300c chore: changeset 2024-12-18 13:38:20 +02:00
pax-k
36f0ab7571 Merge branch 'main' into create-jazz-app 2024-12-18 13:00:53 +02:00
pax-k
829be3cafa chore: cleanup 2024-12-18 13:00:32 +02:00
Guido D'Orsi
7c322796aa fix: exclude tests from build 2024-12-18 12:00:18 +01:00
pax-k
36d50d96dd feat: create-jazz-app command 2024-12-18 12:59:58 +02:00
Guido D'Orsi
1fd26b9d05 Merge pull request #1038 from garden-co/changeset-release/main
Version Packages
2024-12-18 11:54:35 +01:00
github-actions[bot]
40f161d4d0 Version Packages 2024-12-18 10:52:20 +00:00
Anselm Eickhoff
655a601a8e Merge pull request #991 from garden-co/jazz-91-writer-only-permission-kind
feat: add writeOnly role on groups
2024-12-18 10:50:04 +00:00
Anselm Eickhoff
c7a28e5003 Merge pull request #1029 from garden-co/feat/icon-component
Create Icon component for consistent icons
2024-12-18 10:49:28 +00:00
Anselm Eickhoff
ae429d0a1c Merge pull request #1034 from garden-co/feat/incremental-transactions
perf: incremental computation on transactions
2024-12-18 10:46:51 +00:00
Guido D'Orsi
26c390be66 fix(rn-e2e): fix app name 2024-12-18 11:40:46 +01:00
pax
a0a0962f28 Merge pull request #1044 from garden-co/ignore-homepage-build
Skip unnecessary Vercel builds if only docs are changed
2024-12-17 16:14:38 +02:00
Guido D'Orsi
32834ef9e3 chore: improve doc comment
Co-authored-by: Anselm Eickhoff <anselm.eickhoff@gmail.com>
2024-12-17 12:06:04 +01:00
Trisha Lim
13be2a3235 Use Icon component in onboarding example thumbnail 2024-12-17 09:39:42 +00:00
Trisha Lim
7fa6e4333d Create Icon component for consistent icon sizes 2024-12-17 09:35:44 +00:00
pax-k
093f08b5e0 chore: renamed vercel build checking script 2024-12-16 22:00:50 +02:00
pax-k
f374545692 chore: rename script 2024-12-16 21:58:54 +02:00
pax-k
9a8f2747fe chore: added vercel.json for example apps 2024-12-16 21:49:30 +02:00
pax-k
84b7c9ab89 chore: test script 2024-12-16 21:10:59 +02:00
pax-k
3863d834ce fix: added vercel.json for homepage 2024-12-16 21:09:56 +02:00
pax-k
4c860075ee fix: tweaked ignore-build.js 2024-12-16 21:01:57 +02:00
pax-k
79480ddf0c chore: moved ignore-build.js to root 2024-12-16 20:47:14 +02:00
pax-k
8d447b8725 chore: test ignore build script 2024-12-16 20:18:02 +02:00
pax-k
238fd47089 fix: use ES modules instead of CommonJS 2024-12-16 20:13:36 +02:00
pax-k
29ac1fbe88 feat: ignore homepage build if "docs" not found in branch name 2024-12-16 20:11:26 +02:00
Anselm
95fd27d3e3 Fix doc typo 2024-12-16 17:22:07 +00:00
Anselm Eickhoff
533d7684c9 Merge pull request #1042 from garden-co/docs-getting-group-of-covalues
Document Getting the Group of an existing CoValue
2024-12-16 17:14:14 +00:00
Anselm
798403a57d Document Getting the Group of an existing CoValue 2024-12-16 17:07:48 +00:00
Anselm
ddf060e64c Improve docs: talk about casting to ID<Account> 2024-12-16 16:58:38 +00:00
Anselm Eickhoff
51515f629c Merge pull request #1041 from garden-co/docs-adding-group-members-by-id
Document how to add Group members by ID
2024-12-16 16:43:13 +00:00
Anselm
65e012f401 Document how to add Group members by ID 2024-12-16 16:38:43 +00:00
Trisha Lim
a1ba29fd47 Add onboarding to examples page 2024-12-16 15:34:19 +00:00
Trisha Lim
b6b76ab2b9 Fix: form does not submit on Enter key press 2024-12-16 15:34:19 +00:00
Guido D'Orsi
77dbd4e205 fix: keep the cachedContent if processNewTransactions is supported 2024-12-16 12:50:03 +01:00
Guido D'Orsi
baa8aff33f Merge pull request #1037 from garden-co/gio/chore/otel-peer-dep
chore(cojson): add @opentlementry/api as a dependency
2024-12-16 10:57:24 +01:00
Giordano Ricci
63703489ab chore(cojson): add @opentlementry/api as a dependency 2024-12-16 09:48:10 +00:00
Guido D'Orsi
325250272b chore: changeset 2024-12-16 10:09:10 +01:00
Guido D'Orsi
219ba975a5 pref(CoMap): lazy computation of the values when doing time travel 2024-12-14 22:52:24 +01:00
Guido D'Orsi
f5a3394d40 perf: improve incemental computation 2024-12-14 21:25:55 +01:00
Guido D'Orsi
4a5209237f perf(coStream): process transactions incrementally 2024-12-14 21:25:55 +01:00
Guido D'Orsi
d7eb50abc1 perf(coMap): process transactions incrementally 2024-12-14 21:25:55 +01:00
Anselm Eickhoff
4908d7cfd3 Merge pull request #1033 from garden-co/changeset-release/main
Version Packages
2024-12-14 17:26:15 +00:00
github-actions[bot]
38b19ab980 Version Packages 2024-12-14 17:22:26 +00:00
Anselm Eickhoff
9e2486c332 Merge pull request #1032 from garden-co/jazz-594-send-content-from-storage-peers-in-one-message-instead-of
Send content from storage peers in one message instead of streaming it
2024-12-14 17:20:46 +00:00
Anselm
e905c84a34 Send content from storage peers in one message instead of streaming it 2024-12-14 17:14:04 +00:00
Trisha Lim
b097c38617 Test draft indicator 2024-12-13 18:20:59 +00:00
Trisha Lim
385dfc89ff Add test to CI 2024-12-13 18:08:31 +00:00
Trisha Lim
d89e4c3412 Test order editing 2024-12-13 18:05:12 +00:00
Trisha Lim
bbeee086ce Test order creation 2024-12-13 17:59:05 +00:00
Trisha Lim
718e9418e2 Set up playwright on form example 2024-12-13 17:34:48 +00:00
Guido D'Orsi
507a00fe6a Merge pull request #1016 from garden-co/fix-depencencies
fix: run sherif to align all the packages/examples dependencies
2024-12-13 15:13:09 +01:00
Guido D'Orsi
8e940130d2 fix: run sherif to aling all the packages/examples dependencies 2024-12-13 15:05:23 +01:00
Guido D'Orsi
ac216b9f2e chore: changeset 2024-12-13 13:19:24 +01:00
Guido D'Orsi
93230df2cb test: add some tests for the writeOnly role and the inheritance 2024-12-13 13:19:24 +01:00
Guido D'Orsi
c13daa140b chore: add comments 2024-12-13 13:19:24 +01:00
Guido D'Orsi
3c9439d0cc chore: rename getCurrentKeyReadId into getCurrentReadKeyId 2024-12-13 13:19:24 +01:00
Guido D'Orsi
d38d4928c7 test: add e2e tests for the writeOnly role 2024-12-13 13:19:24 +01:00
Guido D'Orsi
596901cba6 fix: add writeOnly to createInvite types 2024-12-13 13:19:24 +01:00
Guido D'Orsi
2a1fda3758 feat: add writeOnly role on groups 2024-12-13 13:19:24 +01:00
Trisha Lim
f3581d1086 Fix form example build 2024-12-13 12:17:25 +00:00
Guido D'Orsi
4ac2b75194 Merge pull request #1014 from garden-co/migrate-taiwind-config
fix: migrate tailwind configs to typescript
2024-12-13 13:17:15 +01:00
Guido D'Orsi
cfa78ed628 fix(form): restore palette and add ts-ignore to the vite config 2024-12-13 13:12:49 +01:00
Guido D'Orsi
94095aff28 fix(ci): build only packages on the unit test workflow 2024-12-13 13:09:57 +01:00
Guido D'Orsi
a70f7a4c49 fix: migrate tailwind configs to typescript 2024-12-13 13:09:20 +01:00
Trisha Lim
2270ae113e Fix link typo 2024-12-13 11:54:32 +00:00
Benjamin S. Leveritt
92b64e05ca Add comment about public visibility on profile content 2024-12-13 11:54:32 +00:00
Benjamin S. Leveritt
cb6b9af57d Improve guide 2024-12-13 11:54:32 +00:00
Benjamin S. Leveritt
fc00369d87 Add initial project guide 2024-12-13 11:54:32 +00:00
Anselm Eickhoff
0b260f339d Merge pull request #993 from garden-co/jazz-549-add-forms-example
Add form example for creating and updating
2024-12-13 11:54:11 +00:00
Trisha Lim
8f50dd48f6 Show errors on page 2024-12-13 11:50:43 +00:00
Anselm Eickhoff
d3af4fecd1 Merge pull request #1012 from garden-co/jazz-582-officially-support-svelte
Officially support svelte
2024-12-13 11:32:07 +00:00
Guido D'Orsi
4ec13a9515 Merge pull request #999 from garden-co/changeset-release/main
Version Packages
2024-12-13 12:22:40 +01:00
Trisha Lim
79262351fa Icon stroke width 2024-12-13 11:05:43 +00:00
Trisha Lim
01292230e8 Add validation 2024-12-13 10:49:26 +00:00
github-actions[bot]
9b31d3241d Version Packages 2024-12-12 17:37:39 +00:00
Anselm Eickhoff
77dfd4f883 Merge pull request #1011 from garden-co/fix/import-extensions-linting
fix: enable linting for import extensions on packages
2024-12-12 17:36:16 +00:00
Trisha Lim
9150c238e4 Add feature tags to file share example 2024-12-12 17:33:35 +00:00
Trisha Lim
67bd5ab07f Update file share icon 2024-12-12 17:25:04 +00:00
Trisha Lim
2678c83a99 Add Svelte passkey example app to examples page 2024-12-12 17:22:03 +00:00
Trisha Lim
4c1364a5cb Add Svelte file share example app to examples page 2024-12-12 17:20:16 +00:00
Trisha Lim
f546811a23 Add Svelte under supported environments 2024-12-12 17:10:32 +00:00
Guido D'Orsi
eb9164633c fix: enable linting for import extensions on packages 2024-12-12 18:02:02 +01:00
Trisha Lim
db5e5d8392 Add form example to examples page 2024-12-12 16:26:56 +00:00
Trisha Lim
a18d870faa Update lock file 2024-12-12 15:16:02 +00:00
Trisha Lim
d434b23a34 Layout fix 2024-12-12 15:14:18 +00:00
Trisha Lim
dd363d613f Add readme description 2024-12-12 15:14:18 +00:00
Trisha Lim
9d41f7a16a Orders empty screen 2024-12-12 15:14:18 +00:00
Trisha Lim
dfddc3603a Set default values 2024-12-12 15:14:18 +00:00
Trisha Lim
5c09f0f41a Style strong tag 2024-12-12 15:12:59 +00:00
Trisha Lim
139fcbe172 Add draft indicator 2024-12-12 15:12:59 +00:00
Trisha Lim
507b3b890a Form styling 2024-12-12 15:11:08 +00:00
Trisha Lim
06ad39c418 Order thumbnail styling 2024-12-12 15:10:59 +00:00
Trisha Lim
7077a41c2d Make addons checkbox work 2024-12-12 15:10:59 +00:00
Trisha Lim
9572729cc9 Remove unused 2024-12-12 15:10:59 +00:00
Trisha Lim
9f08ca8cd8 Save draft as an order 2024-12-12 15:10:59 +00:00
Trisha Lim
8e0bf8a8d8 Replace drafts array with a single draft 2024-12-12 15:10:59 +00:00
Trisha Lim
5b72d1f89b Show drafts in home 2024-12-12 15:10:59 +00:00
Trisha Lim
e10d09e6ab Add order draft to schema 2024-12-12 15:10:59 +00:00
Trisha Lim
2007815745 Do not use react-hook-form 2024-12-12 15:10:59 +00:00
Trisha Lim
1f826734d4 Create Order form using react-form-hook 2024-12-12 15:10:59 +00:00
Trisha Lim
80383dac3b Create form example project 2024-12-12 15:09:20 +00:00
Guido D'Orsi
b9ed9e3f13 Merge pull request #994 from garden-co/jazz-493-wait-for-stuff-to-sync-in-ephemeral-contexts-before-quitting
fix(jazz-nodejs): wait for sync before closing and fix the reconnection
2024-12-12 14:52:19 +01:00
Guido D'Orsi
96f844af5e chore: changeset 2024-12-12 11:07:32 +01:00
Guido D'Orsi
994fbf3524 test: add tests on startWorker 2024-12-12 11:04:28 +01:00
Guido D'Orsi
6eba301599 fix: wait for all coValues in sync before closing the Workers node 2024-12-12 10:16:50 +01:00
Guido D'Orsi
322438f361 fix(jazz-nodejs): fix the reconnection system 2024-12-12 10:16:50 +01:00
Guido D'Orsi
f2f3481773 Merge pull request #935 from garden-co/jazz-550-match-account-load-depth-fallback
Add depth fallback
2024-12-12 10:15:12 +01:00
Guido D'Orsi
b96bab59d0 Merge pull request #955 from garden-co/jzi-29-track-the-amount-of-connected-peers-in-cojson-syncmanager
chore: add an up-down counter to track the amount of connected peers
2024-12-12 10:13:34 +01:00
Benjamin S. Leveritt
aa21072ceb Chore: Add changeset 2024-12-11 23:32:39 +00:00
Benjamin S. Leveritt
01442948d0 Exclude Svelte 5 from coverage instrumentation (not supported) 2024-12-11 23:23:43 +00:00
Benjamin S. Leveritt
6c26902a73 Fix coverage picking up wrong files in Jazz-Svelte 2024-12-11 22:53:24 +00:00
Benjamin S. Leveritt
b12f9dc675 Fix downgrade vitest syntax 2024-12-11 22:28:19 +00:00
Benjamin S. Leveritt
bb6d9791dc Lower vitest version 2024-12-11 22:28:19 +00:00
Benjamin S. Leveritt
024b24f5fa Add tests for jazz.svelte 2024-12-11 22:28:19 +00:00
Benjamin S. Leveritt
facfc51e84 Add tests for passkey auth 2024-12-11 22:28:19 +00:00
Benjamin S. Leveritt
6e4a7411dd Add config 2024-12-11 22:28:19 +00:00
Benjamin S. Leveritt
a02b53cbe3 Add vitest coverage 2024-12-11 22:28:19 +00:00
Benjamin S. Leveritt
a0548ecb25 Add vitest 2024-12-11 22:28:19 +00:00
Benjamin S. Leveritt
970414c8c3 Add depth fallback 2024-12-11 22:27:28 +00:00
Anselm Eickhoff
d62a5c74f9 Merge pull request #1004 from garden-co/jazz-579-external-links-to-expo-are-broken
Fix broken links in docs
2024-12-11 18:20:12 +00:00
Guido D'Orsi
5d35469b91 fix: fix jazz-browser-media-images dependency on chat example 2024-12-11 18:49:04 +01:00
Trisha Lim
6cd79a0631 Fix broken links in docs 2024-12-11 16:52:13 +00:00
Trisha Lim
5122cd027b Fix external links in docs 2024-12-11 16:50:06 +00:00
Giordano Ricci
9d9bb97da3 add tests 2024-12-11 11:59:24 +00:00
Giordano Ricci
9db3f2120b add test metric reader utilities 2024-12-11 11:58:50 +00:00
Giordano Ricci
cb4ccd5d33 chore: add .direnv to ignore file 2024-12-11 11:54:27 +00:00
Giordano Ricci
3121551e8a chore: add an up-down counter to track the amount of connected peers 2024-12-11 11:54:27 +00:00
Anselm Eickhoff
1a65ffd913 Merge pull request #950 from garden-co/jazz-188-add-method-to-wait-until-a-covalue-is-synced
feat: add the APIs to wait for a sync state
2024-12-11 10:42:59 +00:00
Guido D'Orsi
80301e51bb Merge pull request #979 from garden-co/jazz-530-send-images-in-chat-example
Send image in chat example
2024-12-11 11:18:54 +01:00
Guido D'Orsi
5686db9b89 Merge pull request #996 from garden-co/jazz-576-fix-homepage-build
Move to use turbo build
2024-12-11 11:18:26 +01:00
Guido D'Orsi
21a56fc96b Merge remote-tracking branch 'origin/main' into jazz-530-send-images-in-chat-example 2024-12-11 11:17:02 +01:00
Guido D'Orsi
eb22a24f17 Merge pull request #990 from garden-co/jazz-574-bump-repo-to-node-22
Chore: Bump node version to 22
2024-12-11 10:56:02 +01:00
Guido D'Orsi
4f3de09154 Merge remote-tracking branch 'origin/main' into jazz-574-bump-repo-to-node-22 2024-12-11 10:53:39 +01:00
Guido D'Orsi
f2f865da50 Merge pull request #920 from garden-co/add-file-share-example-app
Add file share example app
2024-12-11 10:52:30 +01:00
Guido D'Orsi
c0d12dba26 Merge remote-tracking branch 'origin/main' into add-file-share-example-app 2024-12-11 10:51:26 +01:00
Guido D'Orsi
cd0717f35d Merge pull request #983 from garden-co/jazz-571-bug-the-ws-connection-isnt-restored-when-dropped-by-the
fix(react-native): reconnect automatically when the WebSocket is closed by the server
2024-12-11 10:49:23 +01:00
Guido D'Orsi
4515395bb9 Merge pull request #980 from garden-co/jazz-558-set-up-cryptography-tests-for-react-native
feat(react-native): setup a basic environment to test the crypto
2024-12-11 10:49:05 +01:00
Guido D'Orsi
7cee49f2b2 chore: fix typo 2024-12-11 10:32:18 +01:00
Guido D'Orsi
9414fbfb23 fix: fix e2e tests and initial account migration 2024-12-11 10:25:11 +01:00
Guido D'Orsi
9c6ea58ef5 feat(file-share-svelter): add the e2e test to the CI 2024-12-11 09:44:50 +01:00
Guido D'Orsi
0685436b0c Merge pull request #842 from garden-co/JAZZ-238/very-quick-way-to-open-up-inspector-as-current-user-in-an-app
feat: pressing cmd+j in a jazz app exports the jazz account to inspector
2024-12-11 09:33:48 +01:00
Guido D'Orsi
daa11aa915 chore: remove console.log 2024-12-11 09:33:05 +01:00
Benjamin S. Leveritt
bbdb1ef429 Improve build instructions in readme 2024-12-10 23:37:07 +00:00
Benjamin S. Leveritt
508537928f Update cloud key 2024-12-10 23:30:59 +00:00
Benjamin S. Leveritt
eaeeedc3a4 Update readmes 2024-12-10 23:30:59 +00:00
Benjamin S. Leveritt
15cdfd406c Add svelte output to turbo for better caching 2024-12-10 23:30:59 +00:00
Benjamin S. Leveritt
76262c1a03 Replace svelte auto adapter with vercel 2024-12-10 23:30:59 +00:00
Benjamin S. Leveritt
fc43a2384b Remove the special example exception 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
d1698eed6f Add Readmes 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
6d68dc1bbf Rename file-share app 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
1fb49b266a Remove ownerId from url
As it's not used
2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
49f0ab1545 Exclude file-share from biome checking for now 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
641bbddd64 Add file name to page title 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
7e22f53718 Chore: fix formatting 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
4c44468129 Fix Ownership to be determined by admin role 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
b0c5ecd7b6 Add guest access to files 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
5bf9d69e9f Add loading check 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
3ecf11ded9 Replace messages with toasts 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
709d60b365 Add download error handler 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
f135babcb8 Add page title 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
36a85d4313 Add file detail page for sharing 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
7316379247 Add lucide icons 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
0cf59b6549 Tweak UI layout 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
bcaff2f24a Improve layout of uploader 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
d2a5087e65 Animate uploading files 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
8627d47afc Show uploading files 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
47f625cbd4 Add file size 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
34b65ef67a Add shared files page 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
51209d5314 Fix root re-initialising on reload 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
309dffcc67 Wrap auth and provider around app 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
716b87da0a Initialise Jazz app 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
3c58879a10 Add schema 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
ed16031f12 Add jazz deps 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
90d9e1ca91 Format files 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
95828596f8 Add sv created file share app 2024-12-10 23:28:56 +00:00
Benjamin S. Leveritt
d794a555dc Merge pull request #942 from garden-co/jazz-560-fix-linting-in-cojson-storage-indexeddb
Add linting to cojson-storage-indexeddb
2024-12-10 23:27:15 +00:00
Benjamin S. Leveritt
a6c143f33f Add build instructions 2024-12-10 23:02:06 +00:00
Benjamin S. Leveritt
1db615d1b1 Formatting 2024-12-10 21:28:44 +00:00
Benjamin S. Leveritt
9b45c44b29 Move to use turbo build 2024-12-10 21:27:42 +00:00
Benjamin S. Leveritt
ecc7c9672d Chore: Add changeset 2024-12-10 20:24:59 +00:00
Benjamin S. Leveritt
d645970cb0 Bump dockerfile node version 2024-12-10 20:24:59 +00:00
Benjamin S. Leveritt
e9864cda9d Chore: Bump better-sqlite3 version 2024-12-10 20:24:59 +00:00
Benjamin S. Leveritt
d4e9afc4e2 Chore: Bump node version to 22 2024-12-10 20:21:36 +00:00
pax
4fc4f029a2 Merge pull request #977 from garden-co/changeset-release/main
Version Packages
2024-12-10 20:39:58 +02:00
Guido D'Orsi
fb06319dae chore: simplify createAccount relying on waitForAllCoValuesSync 2024-12-10 18:29:54 +01:00
Guido D'Orsi
a4886fede8 test: fix test after merge 2024-12-10 18:16:30 +01:00
Trisha Lim
b2ca4ec52e Change owner of image 2024-12-10 16:59:56 +00:00
Trisha Lim
b2c8a1a27d Add hover styling to Upload Image button 2024-12-10 16:58:29 +00:00
github-actions[bot]
5469c1f347 Version Packages 2024-12-10 14:55:06 +00:00
Anselm Eickhoff
d36e7cd55a Merge pull request #987 from garden-co/jazz-573-improve-turbo-caching-on-homepage
Adds caching to homepage
2024-12-10 14:53:43 +00:00
Giordano Ricci
03ccdb93af Merge pull request #988 from garden-co/gio/add-queue-metrics-tests
chore: adds message queue size metrics tests
2024-12-10 13:36:00 +00:00
Giordano Ricci
eb8bd20931 teardown meter provider 2024-12-10 13:28:29 +00:00
Giordano Ricci
9819811c91 chore: adds message queue size metrics tests 2024-12-10 12:35:24 +00:00
Benjamin S. Leveritt
350e59b187 Adds caching to homepage 2024-12-10 11:42:57 +00:00
Guido D'Orsi
c2cad4b68c Merge remote-tracking branch 'origin/main' into jazz-188-add-method-to-wait-until-a-covalue-is-synced 2024-12-10 11:23:29 +01:00
Guido D'Orsi
0c6b0f37ed fix(react-native): reconnect automatically when the WebSocket is closed by the server 2024-12-10 11:17:56 +01:00
Anselm Eickhoff
a3541f24ee Merge pull request #975 from garden-co/jzi-28-track-the-message-queue-size-of-each-peerstate-on-cojson
chore: Add message queue size metric
2024-12-10 09:59:17 +00:00
Anselm Eickhoff
f8be4e8bc0 Merge pull request #978 from garden-co/fix/sqlite-scheduling
fix(sqlite): improve the work scheduling when under pressure
2024-12-10 09:52:40 +00:00
Guido D'Orsi
c8015ddee1 feat(react-native): setup a basic environment to test the crypto 2024-12-10 10:24:30 +01:00
Guido D'Orsi
44227bd6e8 Merge pull request #970 from garden-co/fix/sync-server-console
fix(jazz-run): fix console output to log the server address when running the local sync
2024-12-10 10:02:10 +01:00
Trisha Lim
d582429488 Set file size limit to 5MB 2024-12-09 18:45:00 +00:00
Trisha Lim
3db0639636 Update demo section copy 2024-12-09 18:29:10 +00:00
Trisha Lim
c75cd9da37 Send image in chat example 2024-12-09 16:12:05 +00:00
Guido D'Orsi
da13ecac5c fix(sqlite): improve the work scheduling when under pressure 2024-12-09 16:44:34 +01:00
Giordano Ricci
c4af72e1ca mark @opentelemetry/api as a peer dependency 2024-12-09 14:48:10 +00:00
Trisha Lim
e43ca2bc98 Fix broken links 2024-12-09 11:46:28 +00:00
Trisha Lim
bcdd8e9125 Change "updating" to "writing" 2024-12-09 11:46:28 +00:00
Trisha Lim
2d6352a2dc Match side nav links with content links 2024-12-09 11:46:28 +00:00
Trisha Lim
749350cb59 Docs: return coming soon page on routes with no content 2024-12-09 11:46:28 +00:00
Trisha Lim
07e9a73c52 Fix clerk example readme title 2024-12-09 11:28:47 +00:00
Anselm Eickhoff
1ef9998b23 Merge pull request #973 from garden-co/fix/parent-group-role-resolution
fix(role): apply time traveling when resolving role from parents
2024-12-09 11:12:12 +00:00
Guido D'Orsi
b00ee914c3 fix(role): apply time traveling when resolving role from parents 2024-12-09 12:03:18 +01:00
Giordano Ricci
f488c09545 add changeset 2024-12-09 10:17:31 +00:00
Giordano Ricci
0d6ea25e56 chore: Add message queue size metric 2024-12-09 10:09:20 +00:00
Guido D'Orsi
9ffe6d0c63 test(e2e): use waitForSync to improve the test stability 2024-12-08 12:53:23 +01:00
Guido D'Orsi
249eecb68f chore: changeset 2024-12-08 12:46:05 +01:00
Guido D'Orsi
cdbde2970d fix(PeerState): keep optimistic and knownState the same when the role is storage 2024-12-08 12:46:05 +01:00
Guido D'Orsi
24a1b045d3 test(e2e): move synced check up 2024-12-08 12:46:05 +01:00
Guido D'Orsi
a21c3068cd feat(waitForSync): add API docs and some more tests 2024-12-08 12:46:05 +01:00
Guido D'Orsi
55ab4844d6 feat: add the APIs to wait for a sync state 2024-12-08 12:46:05 +01:00
Guido D'Orsi
6e131eb0dc Merge pull request #971 from garden-co/fix/e2e-test-sharing
test(e2e): use the local server to reduce the flakyiness
2024-12-08 11:47:00 +01:00
Guido D'Orsi
8a0cb69c72 test(e2e): fix flakyiness on the Sharing test suit 2024-12-08 11:40:56 +01:00
Guido D'Orsi
d01286b723 test(e2e): use the local server to reduce the flakyiness 2024-12-08 11:32:49 +01:00
Guido D'Orsi
0b636d26f3 Merge pull request #968 from garden-co/playwright-cache
chore(ci): optimize playwright browsers install
2024-12-08 11:22:25 +01:00
Guido D'Orsi
f41a1b0d1d Merge pull request #969 from garden-co/upgrade-pnpm-changeset
chore: update pnpm and changeset to fix release
2024-12-08 11:18:03 +01:00
Guido D'Orsi
0a8753dfe0 chore: align pnpm-lock with main 2024-12-08 11:06:39 +01:00
Guido D'Orsi
3ca8b13f6c fix: fix type error on test file 2024-12-08 11:01:40 +01:00
Guido D'Orsi
e06c18150a chore(ci): remove --with-deps 2024-12-08 10:57:35 +01:00
Guido D'Orsi
4c4499ce86 Merge remote-tracking branch 'origin/main' into upgrade-pnpm-changeset 2024-12-08 10:56:11 +01:00
Guido D'Orsi
afa4c825ca chore: update pnpm and changeset to fix release 2024-12-08 10:53:04 +01:00
Guido D'Orsi
60e04cb193 chore(ci): cache playwright browsers 2024-12-08 10:51:30 +01:00
Benjamin S. Leveritt
0d6853bbdd Fix imports 2024-12-08 07:36:35 +00:00
Benjamin S. Leveritt
a238dde78a Fix test 2024-12-08 07:36:35 +00:00
Benjamin S. Leveritt
59997fbf71 Add linting 2024-12-08 07:36:35 +00:00
pax-k
ab7c899a9e Merge branch 'main' into JAZZ-238/very-quick-way-to-open-up-inspector-as-current-user-in-an-app 2024-12-04 12:18:36 +02:00
pax-k
81c470e9fa fix: comment out createCoValueObservable.test.ts until cirular imports are fixed 2024-12-03 14:31:50 +02:00
pax-k
52d5a14fdf fix: comment out createCoValueObservable.test.ts until cirular imports are fixed 2024-12-03 14:24:49 +02:00
pax-k
fca6be8da0 Merge branch 'main' into JAZZ-238/very-quick-way-to-open-up-inspector-as-current-user-in-an-app 2024-12-03 14:07:17 +02:00
pax-k
e386f2ba8d chore: changeset 2024-12-03 13:56:41 +02:00
pax-k
c2d292effc chore: moved export-account-inspector.ts to jazz-browser 2024-12-03 13:52:09 +02:00
pax-k
a107e17c44 fix: cmd+j now registered only if allowJazzInspector is found in window.location.href 2024-11-25 17:28:46 +02:00
pax
d2d2801537 Update packages/jazz-tools/src/utils/export-account-inspector.ts
Co-authored-by: Anselm Eickhoff <anselm.eickhoff@gmail.com>
2024-11-25 17:04:45 +02:00
pax-k
d5af8df158 feat: pressing cmd+j in a jazz app exports the jazz account to inspector 2024-11-21 17:30:50 +02:00
528 changed files with 23797 additions and 12516 deletions

View File

@@ -1,5 +0,0 @@
---
"jazz-run": patch
---
Log the server address when running the local sync server

View File

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

View File

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

52
.github/workflows/build-starters.yaml vendored Normal file
View File

@@ -0,0 +1,52 @@
name: Build Starters
on:
push:
branches: [ "main" ]
jobs:
build-starters:
runs-on: ubuntu-latest
strategy:
matrix:
starter: [
"react-demo-auth-tailwind",
]
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Enable corepack
run: corepack enable
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.node-version'
cache: 'pnpm'
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Pnpm Build
run: |
pnpm install
pnpm turbo build;
working-directory: ./starters/${{ matrix.starter }}

View File

@@ -13,7 +13,7 @@ jobs:
continue-on-error: true continue-on-error: true
strategy: strategy:
matrix: matrix:
project: ["tests/e2e", "examples/chat", "examples/music-player", "examples/pets", "examples/onboarding"] project: ["tests/e2e", "examples/chat", "examples/file-share-svelte", "examples/form", "examples/music-player", "examples/pets", "examples/onboarding"]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@@ -41,20 +41,16 @@ jobs:
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: | restore-keys: |
${{ runner.os }}-pnpm-store- ${{ runner.os }}-pnpm-store-
- name: Install dependencies - name: Install dependencies
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
- name: Pnpm Build - name: Pnpm Build
run: pnpm turbo build run: pnpm turbo build
working-directory: ./${{ matrix.project }} working-directory: ./${{ matrix.project }}
- name: Build jazz-run
run: pnpm exec turbo build && chmod +x dist/index.js;
working-directory: ./packages/jazz-run
- name: Install Playwright Browsers - name: Install Playwright Browsers
run: pnpm exec playwright install --with-deps run: pnpm exec playwright install
working-directory: ./${{ matrix.project }} working-directory: ./${{ matrix.project }}
- name: Run Playwright tests - name: Run Playwright tests

View File

@@ -4,6 +4,13 @@ on:
push: push:
branches: branches:
- main - main
workflow_dispatch:
inputs:
debug_enabled:
type: boolean
description: "Run tmate session for debugging"
required: false
default: false
concurrency: ${{ github.workflow }}-${{ github.ref }} concurrency: ${{ github.workflow }}-${{ github.ref }}
@@ -48,4 +55,11 @@ jobs:
publish: pnpm release publish: pnpm release
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# Enable tmate debugging only if the workflow is manually triggered, debug_enabled is true, and the workflow failed
- name: Setup tmate session for debugging
if: ${{ failure() && github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
uses: mxschmitt/action-tmate@v3
with:
timeout-minutes: 15

View File

@@ -41,7 +41,7 @@ jobs:
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
- name: Pnpm Build - name: Pnpm Build
run: pnpm turbo build run: pnpm turbo build --filter="./packages/*"
- name: Unit Tests - name: Unit Tests
run: pnpm test:ci run: pnpm test:ci

1
.gitignore vendored
View File

@@ -5,6 +5,7 @@ docsTmp
.DS_Store .DS_Store
.turbo .turbo
coverage coverage
.direnv
# Next.js # Next.js
**/.next **/.next

View File

@@ -1 +1 @@
20 22

1
.nvmrc Normal file
View File

@@ -0,0 +1 @@
22

View File

@@ -25,7 +25,53 @@
"linter": { "linter": {
"enabled": false, "enabled": false,
"rules": { "rules": {
"recommended": true "recommended": true,
"correctness": {
"useImportExtensions": {
"level": "error",
"options": {
"suggestedExtensions": {
"ts": {
"module": "js",
"component": "jsx"
}
}
}
}
}
} }
} },
"overrides": [
{
"include": ["packages/**/src/**"],
"linter": {
"enabled": true,
"rules": {
"recommended": false
}
}
},
{
"include": ["packages/**/src/tests/**", "packages/**/src/test/**"],
"linter": {
"rules": {
"correctness": {
"useImportExtensions": "off"
}
}
}
},
{
"include": ["packages/cojson-storage-indexeddb/**"],
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"suspicious": {
"noExplicitAny": "info"
}
}
}
}
]
} }

View File

@@ -1,36 +0,0 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

View File

@@ -1,246 +0,0 @@
# jazz-example-book-shelf
## 0.1.29
### Patch Changes
- jazz-react@0.8.37
- jazz-tools@0.8.37
- jazz-browser-media-images@0.8.37
## 0.1.28
### Patch Changes
- Updated dependencies [441fe27]
- jazz-tools@0.8.36
- jazz-react@0.8.36
- jazz-browser-media-images@0.8.36
## 0.1.27
### Patch Changes
- Updated dependencies [9212ab8]
- Updated dependencies [8b87117]
- jazz-react@0.8.35
- jazz-tools@0.8.35
- jazz-browser-media-images@0.8.35
## 0.1.26
### Patch Changes
- jazz-react@0.8.34
- jazz-tools@0.8.34
- jazz-browser-media-images@0.8.34
## 0.1.25
### Patch Changes
- jazz-browser-media-images@0.8.33
- jazz-react@0.8.33
## 0.1.24
### Patch Changes
- Updated dependencies [df42b2b]
- jazz-tools@0.8.32
- jazz-react@0.8.32
- jazz-browser-media-images@0.8.32
## 0.1.23
### Patch Changes
- jazz-react@0.8.31
- jazz-tools@0.8.31
- jazz-browser-media-images@0.8.31
## 0.1.22
### Patch Changes
- jazz-react@0.8.30
- jazz-tools@0.8.30
- jazz-browser-media-images@0.8.30
## 0.1.21
### Patch Changes
- jazz-react@0.8.29
- jazz-tools@0.8.29
- jazz-browser-media-images@0.8.29
## 0.1.20
### Patch Changes
- jazz-react@0.8.28
- jazz-tools@0.8.28
- jazz-browser-media-images@0.8.28
## 0.1.19
### Patch Changes
- jazz-react@0.8.27
- jazz-tools@0.8.27
- jazz-browser-media-images@0.8.27
## 0.1.18
### Patch Changes
- Updated dependencies [59d37df]
- jazz-react@0.8.26
## 0.1.17
### Patch Changes
- jazz-browser-media-images@0.8.24
- jazz-react@0.8.24
## 0.1.16
### Patch Changes
- Updated dependencies [d348c2d]
- Updated dependencies [6902b5b]
- Updated dependencies [1a0cd3d]
- jazz-tools@0.8.23
- jazz-react@0.8.23
- jazz-browser-media-images@0.8.23
## 0.1.15
### Patch Changes
- Updated dependencies [59cc64d]
- jazz-react@0.8.22
- jazz-browser-media-images@0.8.22
## 0.1.14
### Patch Changes
- Updated dependencies [149ca97]
- jazz-tools@0.8.21
- jazz-react@0.8.21
- jazz-browser-media-images@0.8.21
## 0.1.13
### Patch Changes
- Updated dependencies [dd9b13f]
- Updated dependencies [a69ed0b]
- Updated dependencies [3ef3ff3]
- Updated dependencies [c6931b8]
- jazz-react@0.8.20
- jazz-browser-media-images@0.8.20
## 0.1.12
### Patch Changes
- jazz-react@0.8.19
- jazz-tools@0.8.19
- jazz-browser-media-images@0.8.19
## 0.1.11
### Patch Changes
- jazz-react@0.8.18
- jazz-tools@0.8.18
- jazz-browser-media-images@0.8.18
## 0.1.10
### Patch Changes
- jazz-react@0.8.17
- jazz-tools@0.8.17
- jazz-browser-media-images@0.8.17
## 0.1.9
### Patch Changes
- Updated dependencies [2af107c]
- jazz-react@0.8.16
- jazz-browser-media-images@0.8.16
- jazz-tools@0.8.16
## 0.1.8
### Patch Changes
- Updated dependencies [cce679b]
- jazz-tools@0.8.15
- jazz-browser-media-images@0.8.15
- jazz-react@0.8.15
## 0.1.7
### Patch Changes
- Updated dependencies [36273b3]
- jazz-tools@0.8.14
- jazz-browser-media-images@0.8.14
- jazz-react@0.8.14
## 0.1.6
### Patch Changes
- Updated dependencies [fd011d7]
- jazz-tools@0.8.13
- jazz-browser-media-images@0.8.13
- jazz-react@0.8.13
## 0.1.5
### Patch Changes
- Updated dependencies [3cc6aee]
- jazz-react@0.8.12
- jazz-tools@0.8.12
- jazz-browser-media-images@0.8.12
## 0.1.4
### Patch Changes
- jazz-react@0.8.11
- jazz-tools@0.8.11
- jazz-browser-media-images@0.8.11
## 0.1.3
### Patch Changes
- jazz-browser-media-images@0.8.7
- jazz-react@0.8.7
## 0.1.2
### Patch Changes
- jazz-browser-media-images@0.8.6
- jazz-react@0.8.6
## 0.1.1
### Patch Changes
- Updated dependencies [c3f4e6b]
- Updated dependencies [d9152ed]
- jazz-tools@0.8.5
- jazz-browser-media-images@0.8.5
- jazz-react@0.8.5

View File

@@ -1,4 +0,0 @@
FROM caddy:2.7.3-alpine
LABEL org.opencontainers.image.source="https://github.com/garden-co/jazz"
COPY ./dist /usr/share/caddy/

View File

@@ -1,56 +0,0 @@
job "example-bookShelf$BRANCH_SUFFIX" {
region = "global"
datacenters = ["*"]
group "static" {
count = 4
network {
port "http" {
to = 80
}
}
constraint {
attribute = "${node.class}"
operator = "="
value = "cloud"
}
spread {
attribute = "${node.datacenter}"
weight = 100
}
constraint {
distinct_hosts = true
}
task "server" {
driver = "docker"
config {
image = "$DOCKER_TAG"
ports = ["http"]
auth = {
username = "$DOCKER_USER"
password = "$DOCKER_PASSWORD"
}
}
service {
tags = ["public"]
name = "example-bookShelf$BRANCH_SUFFIX"
port = "http"
provider = "consul"
}
resources {
cpu = 50 # MHz
memory = 50 # MB
}
}
}
}
# deploy bump 4

View File

@@ -1,5 +0,0 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

View File

@@ -1,4 +0,0 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
export default nextConfig;

View File

@@ -1,29 +0,0 @@
{
"name": "jazz-example-book-shelf",
"version": "0.1.29",
"private": true,
"scripts": {
"dev": "next dev",
"format-and-lint": "biome check .",
"format-and-lint:fix": "biome check . --write",
"build": "next build",
"start": "next start"
},
"dependencies": {
"clsx": "^2.0.0",
"jazz-browser-media-images": "workspace:0.8.37",
"jazz-react": "workspace:0.8.37",
"jazz-tools": "workspace:0.8.37",
"next": "14.2.5",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "^22.5.1",
"@types/react": "^18.2.19",
"@types/react-dom": "^18.2.7",
"postcss": "^8.4.27",
"tailwindcss": "3.3.2",
"typescript": "^5.3.3"
}
}

View File

@@ -1,8 +0,0 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
},
};
export default config;

View File

@@ -1,139 +0,0 @@
"use client";
import { Button } from "@/components/Button";
import { Container } from "@/components/Container";
import { useAccount } from "@/components/JazzAndAuth";
import RatingInput from "@/components/RatingInput";
import { BookReview, ListOfBookReviews } from "@/schema";
import { createImage } from "jazz-browser-media-images";
import { Group, ImageDefinition } from "jazz-tools";
import { useRouter } from "next/navigation";
import { ChangeEvent, useState } from "react";
export default function AddBookReview() {
const { me } = useAccount();
const [title, setTitle] = useState("");
const [author, setAuthor] = useState("");
const [review, setReview] = useState("");
const [rating, setRating] = useState(0);
const [dateRead, setDateRead] = useState(
new Date().toISOString().split("T")[0],
);
const [coverImage, setCoverImage] = useState<ImageDefinition | undefined>();
const router = useRouter();
const onDateChange = (event: ChangeEvent<HTMLInputElement>) => {
const date = new Date(event.currentTarget.value)
.toISOString()
.split("T")[0];
setDateRead(date);
};
const onImageChange = (event: ChangeEvent<HTMLInputElement>) => {
const file = event.currentTarget.files?.[0];
const group = Group.create({ owner: me });
group.addMember("everyone", "reader");
if (file) {
createImage(file, { owner: group }).then((image) => {
setCoverImage(image);
});
}
};
const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (!me?.profile) return;
const bookReview = BookReview.create(
{
title,
author,
review,
rating,
dateRead: new Date(dateRead),
cover: coverImage,
},
{
owner: me.profile._owner,
},
);
if (!me.profile.bookReviews) {
me.profile.bookReviews = ListOfBookReviews.create([], {
owner: me.profile._owner,
});
}
me.profile.bookReviews.push(bookReview);
router.push("/");
};
return (
<Container className="grid max-w-lg gap-8 py-8">
<h1 className="text-lg font-semibold text-black">Add book review</h1>
<form action="" className="grid gap-4" onSubmit={onSubmit}>
<label className="grid gap-1 text-sm text-gray-600">
Cover
<input type="file" onChange={onImageChange} />
</label>
<label className="grid gap-1 text-sm text-gray-600">
Title
<input
className="rounded border border-gray-300 px-2 py-1 shadow-sm"
type="text"
value={title}
required
onChange={(e) => setTitle(e.target.value)}
></input>
</label>
<label className="grid gap-1 text-sm text-gray-600">
Author
<input
className="rounded border border-gray-300 px-2 py-1 shadow-sm"
type="text"
value={author}
required
onChange={(e) => setAuthor(e.target.value)}
></input>
</label>
<label className="grid gap-1 text-sm text-gray-600">
Date read
<input
className="rounded border border-gray-300 px-2 py-1 shadow-sm"
type="date"
value={dateRead}
required
onChange={onDateChange}
/>
</label>
<div className="grid gap-1 text-sm text-gray-600">
Rating
<RatingInput
value={rating}
onChange={(rating) => setRating(rating)}
/>
</div>
<label className="grid gap-1 text-sm text-gray-600">
Review
<textarea
className="rounded border border-gray-300 px-2 py-1 shadow-sm"
value={review}
onChange={(e) => setReview(e.target.value)}
></textarea>
</label>
<Button variant="primary" type="submit">
Add
</Button>
</form>
</Container>
);
}

View File

@@ -1,172 +0,0 @@
"use client";
import { BookCover } from "@/components/BookCover";
import { Container } from "@/components/Container";
import { useCoState } from "@/components/JazzAndAuth";
import Rating from "@/components/Rating";
import RatingInput from "@/components/RatingInput";
import { BookReview } from "@/schema";
import clsx from "clsx";
import { Group, ID } from "jazz-tools";
const BookReviewTitle = ({
bookReview,
readOnly,
}: {
bookReview: BookReview;
readOnly: boolean;
}) => {
const className = "font-serif text-2xl font-bold lg:text-4xl";
if (readOnly) {
return <h1 className={className}>{bookReview.title}</h1>;
}
return (
<input
value={bookReview.title}
placeholder="Book title"
className={clsx(
className,
"w-full rounded border border-transparent px-2 py-1 hover:border-gray-300 hover:shadow-sm",
)}
onChange={(e) => (bookReview.title = e.target.value)}
></input>
);
};
const BookReviewAuthor = ({
bookReview,
readOnly,
}: {
bookReview: BookReview;
readOnly: boolean;
}) => {
const className = "text-gray-700";
if (readOnly) {
return <p className={className}>by {bookReview.author}</p>;
}
return (
<input
value={bookReview.author}
placeholder="Author"
className={clsx(
className,
"w-full rounded border border-transparent px-2 py-1 hover:border-gray-300 hover:shadow-sm",
)}
onChange={(e) => (bookReview.author = e.target.value)}
></input>
);
};
const BookReviewDateRead = ({
bookReview,
readOnly,
}: {
bookReview: BookReview;
readOnly: boolean;
}) => {
const className = "text-gray-700 max-w-[10rem]";
if (readOnly) {
return (
bookReview.dateRead && (
<p className={className}>{bookReview.dateRead.toLocaleDateString()}</p>
)
);
}
return (
<input
type="date"
value={bookReview.dateRead?.toISOString().split("T")[0]}
placeholder="Date read"
className={clsx(
className,
"w-full rounded border border-transparent px-2 py-1 hover:border-gray-300 hover:shadow-sm",
)}
onChange={(e) => {
const date = new Date(e.target.value);
bookReview.dateRead = date;
}}
></input>
);
};
const BookReviewReview = ({
bookReview,
readOnly,
}: {
bookReview: BookReview;
readOnly: boolean;
}) => {
const className = "text-sm leading-relaxed text-gray-600";
if (readOnly) {
if (bookReview.review) {
return <p className={className}>{bookReview.review}</p>;
}
}
return (
<textarea
value={bookReview.review}
placeholder="Write your review here..."
className={clsx(
className,
"w-full rounded border border-transparent px-2 py-1 hover:border-gray-300 hover:shadow-sm",
)}
onChange={(e) => (bookReview.review = e.target.value)}
></textarea>
);
};
const BookReviewRating = ({
bookReview,
readOnly,
}: {
bookReview: BookReview;
readOnly: boolean;
}) => {
const className = "text-2xl sm:mx-0";
if (readOnly) {
return <Rating className={className} rating={bookReview.rating} />;
}
return (
<RatingInput
className={clsx(className, "p-2")}
onChange={(rating) => (bookReview.rating = rating)}
value={bookReview.rating}
/>
);
};
export default function Page({ params }: { params: { slug: string } }) {
const bookReview = useCoState(BookReview, params.slug as ID<BookReview>);
if (!bookReview) return <></>;
const readOnly = !(bookReview._owner.castAs(Group).myRole() === "admin");
return (
<Container className="grid gap-12 py-8">
<div className="flex flex-col gap-6 sm:flex-row md:gap-10">
<div className="w-[180px]">
<BookCover bookReview={bookReview} readOnly={readOnly} />
</div>
<div className="-mx-2 grid max-w-lg flex-1 gap-3 sm:mx-0">
<BookReviewTitle bookReview={bookReview} readOnly={readOnly} />
<BookReviewAuthor bookReview={bookReview} readOnly={readOnly} />
<BookReviewDateRead bookReview={bookReview} readOnly={readOnly} />
<BookReviewRating bookReview={bookReview} readOnly={readOnly} />
<BookReviewReview bookReview={bookReview} readOnly={readOnly} />
</div>
</div>
</Container>
);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -1,13 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:focus {
@apply outline-none;
}
:focus-visible {
@apply ring-2 ring-purple-600/75 dark:ring-2 dark:ring-white/75;
}
}

View File

@@ -1,39 +0,0 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { JazzAndAuth } from "@/components/JazzAndAuth";
import { Nav } from "@/components/Nav";
import clsx from "clsx";
import { Fraunces } from "next/font/google";
const fraunces = Fraunces({
subsets: ["latin"],
display: "swap",
variable: "--font-fraunces",
});
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Jazz Book Shelf",
description: "Jazz Book Shelf",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={clsx(inter.className, fraunces.variable)}>
<JazzAndAuth>
<header>
<Nav />
</header>
<main>{children}</main>
</JazzAndAuth>
</body>
</html>
);
}

View File

@@ -1,27 +0,0 @@
"use client";
import { Container } from "@/components/Container";
import { useAccount } from "@/components/JazzAndAuth";
import UserProfile from "@/components/UserProfile";
import { JazzAccount } from "@/schema";
import { ID } from "jazz-tools";
export default function Home() {
const { me } = useAccount();
return (
<Container className="grid gap-12 py-8">
<UserProfile id={me?.id as ID<JazzAccount>} />
<label className="flex flex-wrap items-center gap-3">
Share your profile:
<input
type="text"
className="w-full rounded border p-1"
value={`${window.location.origin}/user/${me?.id}`}
readOnly
/>
</label>
</Container>
);
}

View File

@@ -1,14 +0,0 @@
import { Container } from "@/components/Container";
import UserProfile from "@/components/UserProfile";
import { JazzAccount } from "@/schema";
import { ID } from "jazz-tools";
export default function Page({ params }: { params: { slug: string } }) {
const { slug } = params;
return (
<Container className="py-8">
<UserProfile id={slug as ID<JazzAccount>} />
</Container>
);
}

View File

@@ -1,134 +0,0 @@
import { Button } from "@/components/Button";
import { useAccount } from "@/components/JazzAndAuth";
import PlusIcon from "@/components/icons/PlusIcon";
import { BookReview } from "@/schema";
import clsx from "clsx";
import { createImage } from "jazz-browser-media-images";
import { ProgressiveImg } from "jazz-react";
import { Group, ImageDefinition } from "jazz-tools";
import { ChangeEvent, useRef, useState } from "react";
const BookCoverContainer = ({
children,
className = "",
}: {
children: React.ReactNode;
className?: string;
}) => {
return (
<div className={clsx("h-[240px] lg:h-[260px]", className)}>{children}</div>
);
};
const MockCover = ({ bookReview }: { bookReview: BookReview }) => {
return (
<div className="flex h-full flex-col items-center justify-center gap-3 rounded-l-sm rounded-r-md bg-gray-100 px-3 text-center shadow-lg">
<p className="font-medium">{bookReview.title}</p>
<p className="text-xs">{bookReview.author}</p>
</div>
);
};
export function BookCoverReadOnly({
bookReview,
className,
}: {
bookReview: BookReview;
className?: string;
}) {
if (bookReview.cover) {
return (
<BookCoverContainer className={className}>
<ProgressiveImg image={bookReview.cover}>
{({ src }) => (
<img
className="max-h-full max-w-full rounded-l-sm rounded-r-md shadow-lg"
src={src}
/>
)}
</ProgressiveImg>
</BookCoverContainer>
);
}
return (
<BookCoverContainer className={className}>
<MockCover bookReview={bookReview} />
</BookCoverContainer>
);
}
export function BookCoverInput({ bookReview }: { bookReview: BookReview }) {
const { me } = useAccount();
const inputRef = useRef<HTMLInputElement>(null);
const onImageChange = (event: ChangeEvent<HTMLInputElement>) => {
if (!me?.profile) return;
const file = event.currentTarget.files?.[0];
if (file) {
createImage(file, { owner: me.profile._owner }).then((image) => {
bookReview.cover = image;
});
}
};
const onUploadClick = () => {
inputRef.current?.click();
};
const remove = () => {
bookReview.cover = null;
};
if (bookReview.cover) {
return (
<div className="group relative inline-block">
<BookCoverReadOnly
className="transition-opacity group-hover:opacity-40"
bookReview={bookReview}
/>
<div className="absolute left-0 top-0 hidden h-full w-full items-center justify-center rounded-l-sm rounded-r-md group-hover:flex">
<Button
variant="tertiary"
type="button"
className="shadow"
onClick={remove}
>
Remove
</Button>
</div>
</div>
);
}
return (
<BookCoverContainer className="flex w-[180px] flex-col justify-center rounded-l-sm rounded-r-md bg-gray-100 p-3 shadow-lg">
<button
className="flex h-full w-full flex-col items-center justify-center gap-3 text-gray-500 transition-colors hover:text-gray-600"
type="button"
onClick={onUploadClick}
>
<PlusIcon className="h-10 w-10" />
Upload book cover
</button>
<label className="sr-only">
Cover
<input ref={inputRef} type="file" onChange={onImageChange} />
</label>
</BookCoverContainer>
);
}
export function BookCover({
bookReview,
readOnly,
}: {
bookReview: BookReview;
readOnly?: boolean;
}) {
if (readOnly) return <BookCoverReadOnly bookReview={bookReview} />;
return <BookCoverInput bookReview={bookReview} />;
}

View File

@@ -1,30 +0,0 @@
import { BookCover } from "@/components/BookCover";
import Rating from "@/components/Rating";
import RatingInput from "@/components/RatingInput";
import { BookReview } from "@/schema";
import { Group } from "jazz-tools";
export function BookReviewHeader({ bookReview }: { bookReview: BookReview }) {
const { title, author, rating, review, dateRead } = bookReview;
return (
<div className="grid gap-5">
<div>
<h1 className="mb-1 font-serif text-2xl font-bold md:mb-3 lg:text-4xl">
{title}
</h1>
<p className="text-gray-500">by {author}</p>
</div>
{bookReview._owner.castAs(Group).myRole() === "admin" ? (
<RatingInput
onChange={(rating) => (bookReview.rating = rating)}
value={rating}
/>
) : (
<Rating className="mx-auto text-2xl sm:mx-0" rating={rating} />
)}
</div>
);
}

View File

@@ -1,35 +0,0 @@
"use client";
import { BookCover, BookCoverReadOnly } from "@/components/BookCover";
import { useCoState } from "@/components/JazzAndAuth";
import StarIcon from "@/components/icons/StarIcon";
import { ID } from "jazz-tools";
import Link from "next/link";
import { BookReview } from "../schema";
export function BookReviewThumbnail({ id }: { id: ID<BookReview> }) {
const bookReview = useCoState(BookReview, id);
if (!bookReview) return <></>;
return (
<div className="inline-flex shrink-0 gap-4 rounded border p-4 sm:block sm:space-y-6 sm:border-0 sm:p-0 md:w-[200px]">
<Link href={`/book/${bookReview.id}`} className="sm:block sm:flex-1">
<BookCoverReadOnly bookReview={bookReview} />
</Link>
<div className="flex-1">
<Link href={`/book/${bookReview.id}`}>
<h2 className="mb-1 text-sm font-medium">{bookReview.title}</h2>
</Link>
<div className="mb-2 flex flex-col gap-2 text-sm text-gray-500 sm:flex-row sm:items-center">
<p>{bookReview.author}</p>
<div className="flex items-center gap-0.5 text-xs font-semibold leading-none">
<StarIcon className="-mt-px text-base text-yellow-400" />
{bookReview.rating}
</div>
</div>
</div>
</div>
);
}

View File

@@ -1,65 +0,0 @@
import clsx from "clsx";
import Link from "next/link";
import type { ComponentProps } from "react";
interface Props {
variant?: "primary" | "secondary" | "tertiary";
className?: string;
size?: "sm" | "md" | "lg";
}
interface AnchorProps
extends Props,
React.AnchorHTMLAttributes<HTMLAnchorElement> {
href: string;
}
type ButtonProps = ComponentProps<"button"> & Props;
export function Button(props: AnchorProps | ButtonProps) {
const {
className: customClassName = "",
variant = "primary",
children,
size = "md",
} = props;
const variantClassNames = {
base: "inline-flex gap-2 items-center justify-center rounded-full overflow-hidden transition-colors",
primary:
"bg-purple-300 font-medium text-purple-950 px-4 py-2 rounded-full hover:bg-purple-200",
secondary:
"rounded-full bg-slate-100 font-medium text-slate-600 hover:bg-slate-200",
tertiary: "rounded-full bg-white text-purple-950 font-medium",
};
const sizeClassNames = {
sm: "py-1.5 px-3 text-sm",
md: "py-2 px-5",
lg: "py-2 md:py-2.5 px-6 md:text-lg",
};
const className = clsx(
customClassName,
variantClassNames.base,
variantClassNames[variant],
sizeClassNames[size],
);
if (!!(props as AnchorProps).href) {
const anchorProps = props as AnchorProps;
return (
<Link href={anchorProps.href} className={className}>
{children}
</Link>
);
}
const buttonProps = props as ButtonProps;
return (
<button {...buttonProps} className={className}>
{children}
</button>
);
}

View File

@@ -1,13 +0,0 @@
import clsx from "clsx";
export function Container({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) {
return (
<div className={clsx("mx-auto max-w-4xl px-4", className)}>{children}</div>
);
}

View File

@@ -1,29 +0,0 @@
"use client";
import { JazzAccount } from "@/schema";
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
const Jazz = createJazzReactApp({
AccountSchema: JazzAccount,
});
export const { useAccount, useCoState } = Jazz;
export function JazzAndAuth({ children }: { children: React.ReactNode }) {
const [auth, authState] = useDemoAuth();
return (
<>
<Jazz.Provider
auth={auth}
// replace `you@example.com` with your email as a temporary API key
peer="wss://cloud.jazz.tools/?key=you@example.com"
>
{children}
</Jazz.Provider>
{authState.state !== "signedIn" && (
<DemoAuthBasicUI appName="Jazz Book Shelf" state={authState} />
)}
</>
);
}

View File

@@ -1,26 +0,0 @@
"use client";
import { Button } from "@/components/Button";
import { Container } from "@/components/Container";
import { useAccount } from "@/components/JazzAndAuth";
import Link from "next/link";
export function Nav() {
const { me, logOut } = useAccount();
return (
<nav className="border-b py-3">
<Container className="flex items-center justify-between gap-12 text-sm">
<Link href="/" className="font-serif text-lg font-semibold">
Jazz Book Shelf
</Link>
<div className="flex items-center gap-4 text-sm">
<p>{me?.profile?.name}</p>
<Button variant="secondary" onClick={logOut}>
Log out
</Button>
</div>
</Container>
</nav>
);
}

View File

@@ -1,21 +0,0 @@
import StarIcon from "@/components/icons/StarIcon";
import StarOutlineIcon from "@/components/icons/StarOutlineIcon";
export default function Rating({
rating,
className = "",
}: {
rating?: number;
className?: string;
}) {
const max = 5;
const outline = max - (rating || 0);
return (
<div className={`inline-flex gap-0.5 text-yellow-400 ${className}`}>
{rating ? [...Array(rating)].map((x, i) => <StarIcon key={i} />) : <></>}
{[...Array(outline)].map((x, i) => (
<StarOutlineIcon key={i} />
))}
</div>
);
}

View File

@@ -1,47 +0,0 @@
"use client";
import StarIcon from "@/components/icons/StarIcon";
import StarOutlineIcon from "@/components/icons/StarOutlineIcon";
import clsx from "clsx";
interface RatingInputProps {
value?: number;
onChange: (value: number) => void;
className?: string;
}
export default function RatingInput({
value = 0,
onChange,
className,
}: RatingInputProps) {
const handleChange = (newRating: number) => {
onChange(newRating > 5 ? 5 : newRating);
};
return (
<div className={clsx(className, "flex gap-0.5 text-2xl text-yellow-400")}>
{[...Array(5)].map((_, i) => {
return i < value ? (
<button
type="button"
className="focus:outline-none"
onClick={() => handleChange(i + 1)}
key={i}
>
<StarIcon />
</button>
) : (
<button
type="button"
className="focus:outline-none"
onClick={() => handleChange(i + 1)}
key={i}
>
<StarOutlineIcon />
</button>
);
})}
</div>
);
}

View File

@@ -1,39 +0,0 @@
"use client";
import { BookReviewThumbnail } from "@/components/BookReviewThumbnail";
import { Button } from "@/components/Button";
import { useCoState } from "@/components/JazzAndAuth";
import { JazzAccount, JazzProfile, ListOfBookReviews } from "@/schema";
import { Group, ID } from "jazz-tools";
export default function UserProfile({ id }: { id: ID<JazzAccount> }) {
const user = useCoState(JazzAccount, id);
const profile = useCoState(JazzProfile, user?.profile?.id);
const bookReviews = useCoState(
ListOfBookReviews,
user?.profile?._refs.bookReviews?.id,
[{}],
);
return (
<div className="grid gap-4">
<div className="flex items-center justify-between">
<h1 className="font-serif text-lg font-medium sm:text-2xl">
{profile?.name}&apos;s book shelf
</h1>
{profile?._owner.castAs(Group).myRole() === "admin" && (
<Button href="/add" variant="primary">
Add book
</Button>
)}
</div>
<div className="grid gap-4 md:grid-cols-4">
{bookReviews?.map((bookReview) => (
<BookReviewThumbnail key={bookReview.id} id={bookReview.id} />
))}
</div>
</div>
);
}

View File

@@ -1,20 +0,0 @@
export default function PlusIcon({ className }: { className?: string }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className={className}
width="1em"
height="1em"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M12 4.5v15m7.5-7.5h-15"
/>
</svg>
);
}

View File

@@ -1,18 +0,0 @@
export default function StarIcon({ className }: { className?: string }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
className={className}
width="1em"
height="1em"
>
<path
fillRule="evenodd"
d="M10.788 3.21c.448-1.077 1.976-1.077 2.424 0l2.082 5.006 5.404.434c1.164.093 1.636 1.545.749 2.305l-4.117 3.527 1.257 5.273c.271 1.136-.964 2.033-1.96 1.425L12 18.354 7.373 21.18c-.996.608-2.231-.29-1.96-1.425l1.257-5.273-4.117-3.527c-.887-.76-.415-2.212.749-2.305l5.404-.434 2.082-5.005Z"
clipRule="evenodd"
/>
</svg>
);
}

View File

@@ -1,20 +0,0 @@
export default function StarOutlineIcon({ className }: { className?: string }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className={className}
width="1em"
height="1em"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M11.48 3.499a.562.562 0 0 1 1.04 0l2.125 5.111a.563.563 0 0 0 .475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 0 0-.182.557l1.285 5.385a.562.562 0 0 1-.84.61l-4.725-2.885a.562.562 0 0 0-.586 0L6.982 20.54a.562.562 0 0 1-.84-.61l1.285-5.386a.562.562 0 0 0-.182-.557l-4.204-3.602a.562.562 0 0 1 .321-.988l5.518-.442a.563.563 0 0 0 .475-.345L11.48 3.5Z"
/>
</svg>
);
}

View File

@@ -1,37 +0,0 @@
import {
Account,
CoList,
CoMap,
Encoders,
ImageDefinition,
Profile,
co,
} from "jazz-tools";
export class BookReview extends CoMap {
title = co.string;
author = co.string;
rating = co.number;
dateRead? = co.encoded(Encoders.Date);
review? = co.string;
cover? = co.ref(ImageDefinition, { optional: true });
}
export class ListOfBookReviews extends CoList.Of(co.ref(BookReview)) {}
/** The profile is an app-specific per-user public `CoMap`
* where you can store top-level objects for that user */
export class JazzProfile extends Profile {
bookReviews = co.ref(ListOfBookReviews);
}
export class JazzAccount extends Account {
profile = co.ref(JazzProfile);
/** The account migration is run on account creation and on every log-in.
* You can use it to set up the account root and any other initial CoValues you need.
*/
migrate(this: JazzAccount, creationProps?: { name: string }) {
super.migrate(creationProps);
}
}

View File

@@ -1,25 +0,0 @@
import type { Config } from "tailwindcss";
const colors = require("tailwindcss/colors");
const config: Config = {
content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
fontFamily: {
serif: ["var(--font-fraunces)"],
},
colors: {
purple: {
...colors.purple,
950: "#211f5a",
},
},
},
},
plugins: [],
};
export default config;

View File

@@ -1,5 +1,120 @@
# chat-rn-clerk # chat-rn-clerk
## 1.0.41
### Patch Changes
- Updated dependencies [dc62b95]
- Updated dependencies [1de26f8]
- jazz-tools@0.8.51
- jazz-react-native@0.8.51
- jazz-react-native-auth-clerk@0.8.51
- jazz-react-native-media-images@0.8.51
## 1.0.40
### Patch Changes
- jazz-react-native@0.8.50
- jazz-react-native-auth-clerk@0.8.50
- jazz-tools@0.8.50
- jazz-react-native-media-images@0.8.50
## 1.0.39
### Patch Changes
- jazz-react-native@0.8.49
- jazz-react-native-auth-clerk@0.8.49
- jazz-tools@0.8.49
- jazz-react-native-media-images@0.8.49
## 1.0.38
### Patch Changes
- Updated dependencies [635e824]
- Updated dependencies [0a85982]
- jazz-tools@0.8.48
- jazz-react-native@0.8.48
- jazz-react-native-auth-clerk@0.8.48
- jazz-react-native-media-images@0.8.48
## 1.0.37
### Patch Changes
- Updated dependencies [33ef9c4]
- jazz-react-native@0.8.47
- jazz-react-native-auth-clerk@0.8.47
## 1.0.36
### Patch Changes
- Updated dependencies [ab4ffbd]
- jazz-react-native@0.8.46
- jazz-react-native-auth-clerk@0.8.46
## 1.0.35
### Patch Changes
- Updated dependencies [7701307]
- Updated dependencies [fa41f8e]
- Updated dependencies [88d7d9a]
- Updated dependencies [60e35ea]
- jazz-react-native@0.8.45
- jazz-tools@0.8.45
- jazz-react-native-auth-clerk@0.8.45
- jazz-react-native-media-images@0.8.45
## 1.0.34
### Patch Changes
- jazz-react-native@0.8.44
- jazz-react-native-auth-clerk@0.8.44
- jazz-tools@0.8.44
- jazz-react-native-media-images@0.8.44
## 1.0.33
### Patch Changes
- cdc7f9f: Fixing react-native examples
- Updated dependencies [cdc7f9f]
- jazz-react-native-auth-clerk@0.8.43
## 1.0.32
### Patch Changes
- jazz-react-native@0.8.41
- jazz-react-native-auth-clerk@0.8.41
- jazz-tools@0.8.41
- jazz-react-native-media-images@0.8.41
## 1.0.31
### Patch Changes
- Updated dependencies [0c6b0f3]
- Updated dependencies [249eecb]
- jazz-react-native@0.8.39
- jazz-tools@0.8.39
- jazz-react-native-auth-clerk@0.8.39
- jazz-react-native-media-images@0.8.39
## 1.0.30
### Patch Changes
- jazz-react-native@0.8.38
- jazz-react-native-auth-clerk@0.8.38
- jazz-tools@0.8.38
- jazz-react-native-media-images@0.8.38
## 1.0.29 ## 1.0.29
### Patch Changes ### Patch Changes

View File

@@ -1,3 +1,4 @@
import "../global.css";
import { ClerkLoaded, ClerkProvider } from "@clerk/clerk-expo"; import { ClerkLoaded, ClerkProvider } from "@clerk/clerk-expo";
import { useFonts } from "expo-font"; import { useFonts } from "expo-font";
import { Slot } from "expo-router"; import { Slot } from "expo-router";

View File

@@ -1,7 +1,9 @@
module.exports = function (api) { module.exports = function (api) {
api.cache(true); api.cache(true);
return { return {
presets: ["babel-preset-expo"], presets: [
plugins: ["nativewind/babel"], ["babel-preset-expo", { jsxImportSource: "nativewind" }],
"nativewind/babel",
],
}; };
}; };

View File

@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -1,5 +1,6 @@
// Learn more https://docs.expo.dev/guides/monorepos // Learn more https://docs.expo.dev/guides/monorepos
const { getDefaultConfig } = require("expo/metro-config"); const { getDefaultConfig } = require("expo/metro-config");
const { withNativeWind } = require("nativewind/metro");
const { FileStore } = require("metro-cache"); const { FileStore } = require("metro-cache");
const path = require("path"); const path = require("path");
@@ -31,4 +32,5 @@ config.cacheStores = [
}), }),
]; ];
module.exports = config; // module.exports = config;
module.exports = withNativeWind(config, { input: "./global.css" });

View File

@@ -1,7 +1,7 @@
{ {
"name": "chat-rn-clerk", "name": "chat-rn-clerk",
"main": "index.js", "main": "index.js",
"version": "1.0.29", "version": "1.0.41",
"scripts": { "scripts": {
"build": "expo export -p ios", "build": "expo export -p ios",
"start": "expo start", "start": "expo start",
@@ -45,9 +45,9 @@
"jazz-react-native-auth-clerk": "workspace:*", "jazz-react-native-auth-clerk": "workspace:*",
"jazz-react-native-media-images": "workspace:*", "jazz-react-native-media-images": "workspace:*",
"jazz-tools": "workspace:*", "jazz-tools": "workspace:*",
"nativewind": "^2.0.11", "nativewind": "^4.1.21",
"react": "^18.2.0", "react": "^18.3.1",
"react-dom": "^18.2.0", "react-dom": "^18.3.1",
"react-native": "~0.76.3", "react-native": "~0.76.3",
"react-native-fetch-api": "^3.0.0", "react-native-fetch-api": "^3.0.0",
"react-native-gesture-handler": "~2.20.2", "react-native-gesture-handler": "~2.20.2",
@@ -70,8 +70,8 @@
"jest": "^29.2.1", "jest": "^29.2.1",
"jest-expo": "~52.0.2", "jest-expo": "~52.0.2",
"react-test-renderer": "18.2.0", "react-test-renderer": "18.2.0",
"tailwindcss": "3.3.2", "tailwindcss": "^3.4.15",
"typescript": "^5.3.3" "typescript": "~5.6.2"
}, },
"private": true "private": true
} }

View File

@@ -1,10 +1,12 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
// NOTE: Update this to include the paths to all of your component files.
content: [ content: [
"./app/**/*.{js,jsx,ts,tsx}", "./app/**/*.{js,jsx,ts,tsx}",
"./components/**/*.{js,jsx,ts,tsx}", "./components/**/*.{js,jsx,ts,tsx}",
"./src/**/*.{js,jsx,ts,tsx}", "./src/**/*.{js,jsx,ts,tsx}",
], ],
presets: [require("nativewind/preset")],
theme: { theme: {
extend: {}, extend: {},
}, },

View File

@@ -7,5 +7,5 @@
"@/*": ["./*"] "@/*": ["./*"]
} }
}, },
"include": ["**/*.ts", "**/*.tsx"] "include": ["**/*.ts", "**/*.tsx", "nativewind-env.d.ts"]
} }

View File

@@ -1,5 +1,92 @@
# chat-rn # chat-rn
## 1.0.38
### Patch Changes
- Updated dependencies [dc62b95]
- Updated dependencies [1de26f8]
- jazz-tools@0.8.51
- jazz-react-native@0.8.51
## 1.0.37
### Patch Changes
- jazz-react-native@0.8.50
- jazz-tools@0.8.50
## 1.0.36
### Patch Changes
- jazz-react-native@0.8.49
- jazz-tools@0.8.49
## 1.0.35
### Patch Changes
- Updated dependencies [635e824]
- Updated dependencies [0a85982]
- jazz-tools@0.8.48
- jazz-react-native@0.8.48
## 1.0.34
### Patch Changes
- Updated dependencies [33ef9c4]
- jazz-react-native@0.8.47
## 1.0.33
### Patch Changes
- Updated dependencies [ab4ffbd]
- jazz-react-native@0.8.46
## 1.0.32
### Patch Changes
- Updated dependencies [7701307]
- Updated dependencies [fa41f8e]
- Updated dependencies [88d7d9a]
- Updated dependencies [60e35ea]
- jazz-react-native@0.8.45
- jazz-tools@0.8.45
## 1.0.31
### Patch Changes
- jazz-react-native@0.8.44
- jazz-tools@0.8.44
## 1.0.30
### Patch Changes
- jazz-react-native@0.8.41
- jazz-tools@0.8.41
## 1.0.29
### Patch Changes
- Updated dependencies [0c6b0f3]
- Updated dependencies [249eecb]
- jazz-react-native@0.8.39
- jazz-tools@0.8.39
## 1.0.28
### Patch Changes
- jazz-react-native@0.8.38
- jazz-tools@0.8.38
## 1.0.27 ## 1.0.27
### Patch Changes ### Patch Changes

View File

@@ -1,7 +1,9 @@
module.exports = function (api) { module.exports = function (api) {
api.cache(true); api.cache(true);
return { return {
presets: ["babel-preset-expo"], presets: [
plugins: ["nativewind/babel"], ["babel-preset-expo", { jsxImportSource: "nativewind" }],
"nativewind/babel",
],
}; };
}; };

View File

@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -1,5 +1,6 @@
// Learn more https://docs.expo.dev/guides/monorepos // Learn more https://docs.expo.dev/guides/monorepos
const { getDefaultConfig } = require("expo/metro-config"); const { getDefaultConfig } = require("expo/metro-config");
const { withNativeWind } = require("nativewind/metro");
const { FileStore } = require("metro-cache"); const { FileStore } = require("metro-cache");
const path = require("path"); const path = require("path");
@@ -7,7 +8,7 @@ const path = require("path");
const projectRoot = __dirname; const projectRoot = __dirname;
const workspaceRoot = path.resolve(projectRoot, "../.."); const workspaceRoot = path.resolve(projectRoot, "../..");
const config = getDefaultConfig(projectRoot); const config = getDefaultConfig(projectRoot, { isCSSEnabled: true });
// Since we are using pnpm, we have to setup the monorepo manually for Metro // Since we are using pnpm, we have to setup the monorepo manually for Metro
// #1 - Watch all files in the monorepo // #1 - Watch all files in the monorepo
@@ -19,7 +20,10 @@ config.resolver.nodeModulesPaths = [
]; ];
config.resolver.sourceExts = ["mjs", "js", "json", "ts", "tsx"]; config.resolver.sourceExts = ["mjs", "js", "json", "ts", "tsx"];
config.resolver.unstable_enablePackageExports = true; config.resolver.unstable_enablePackageExports = true;
config.resolver.requireCycleIgnorePatterns = [/(^|\/|\\)node_modules($|\/|\\)/]; config.resolver.requireCycleIgnorePatterns = [
/(^|\/|\\)node_modules($|\/|\\)/,
/(^|\/|\\)packages($|\/|\\)/,
];
// Use turborepo to restore the cache when possible // Use turborepo to restore the cache when possible
config.cacheStores = [ config.cacheStores = [
@@ -28,4 +32,5 @@ config.cacheStores = [
}), }),
]; ];
module.exports = config; // module.exports = config;
module.exports = withNativeWind(config, { input: "./global.css" });

View File

@@ -1,6 +1,6 @@
{ {
"name": "chat-rn", "name": "chat-rn",
"version": "1.0.27", "version": "1.0.38",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"build": "expo export -p ios", "build": "expo export -p ios",
@@ -14,8 +14,8 @@
"dependencies": { "dependencies": {
"@azure/core-asynciterator-polyfill": "^1.0.2", "@azure/core-asynciterator-polyfill": "^1.0.2",
"@react-native-community/netinfo": "^11.4.1", "@react-native-community/netinfo": "^11.4.1",
"@react-navigation/native": "^6.1.18", "@react-navigation/native": "^7.0.13",
"@react-navigation/native-stack": "^6.11.0", "@react-navigation/native-stack": "^7.1.14",
"base-64": "^1.0.0", "base-64": "^1.0.0",
"clsx": "^2.0.0", "clsx": "^2.0.0",
"expo": "^52.0.0", "expo": "^52.0.0",
@@ -30,8 +30,8 @@
"expo-web-browser": "~14.0.1", "expo-web-browser": "~14.0.1",
"jazz-react-native": "workspace:*", "jazz-react-native": "workspace:*",
"jazz-tools": "workspace:*", "jazz-tools": "workspace:*",
"nativewind": "^2.0.11", "nativewind": "^4.1.21",
"react": "18.2.0", "react": "^18.3.1",
"react-native": "~0.76.3", "react-native": "~0.76.3",
"react-native-fetch-api": "^3.0.0", "react-native-fetch-api": "^3.0.0",
"react-native-get-random-values": "^1.11.0", "react-native-get-random-values": "^1.11.0",
@@ -45,8 +45,8 @@
"devDependencies": { "devDependencies": {
"@babel/core": "^7.20.0", "@babel/core": "^7.20.0",
"@types/react": "^18.3.12", "@types/react": "^18.3.12",
"tailwindcss": "3.3.2", "tailwindcss": "^3.4.15",
"typescript": "^5.3.3" "typescript": "~5.6.2"
}, },
"private": true "private": true
} }

View File

@@ -1,3 +1,5 @@
import "../global.css";
import { import {
NavigationContainer, NavigationContainer,
useNavigationContainerRef, useNavigationContainerRef,

View File

@@ -19,45 +19,35 @@ import { Chat, Message } from "./schema";
export default function ChatScreen({ navigation }: { navigation: any }) { export default function ChatScreen({ navigation }: { navigation: any }) {
const { me, logOut } = useAccount(); const { me, logOut } = useAccount();
const [chat, setChat] = useState<Chat>(); const [chatId, setChatId] = useState<ID<Chat>>();
const loadedChat = useCoState(Chat, chatId, [{}]);
const [message, setMessage] = useState(""); const [message, setMessage] = useState("");
const loadedChat = useCoState(Chat, chat?.id, [{}]);
useEffect(() => { useEffect(() => {
navigation.setOptions({ navigation.setOptions({
headerRight: () => <Button onPress={logOut} title="Logout" />, headerRight: () => <Button onPress={logOut} title="Logout" />,
headerLeft: () => headerLeft: () =>
chat ? ( loadedChat ? (
<Button <Button
onPress={() => { onPress={() => {
if (chat?.id) { if (loadedChat?.id) {
Clipboard.setStringAsync( Clipboard.setStringAsync(
`https://chat.jazz.tools/#/chat/${chat.id}`, `https://chat.jazz.tools/#/chat/${loadedChat.id}`,
); );
Alert.alert("Copied to clipboard", `Chat ID: ${chat.id}`); Alert.alert("Copied to clipboard", `Chat ID: ${loadedChat.id}`);
} }
}} }}
title="Share" title="Share"
/> />
) : null, ) : null,
}); });
}, [navigation, chat]); }, [navigation, loadedChat]);
const createChat = () => { const createChat = () => {
const group = Group.create({ owner: me }); const group = Group.create({ owner: me });
group.addMember("everyone", "writer"); group.addMember("everyone", "writer");
const chat = Chat.create([], { owner: group }); const chat = Chat.create([], { owner: group });
setChat(chat); setChatId(chat.id);
};
const loadChat = async (chatId: ID<Chat>) => {
try {
const chat = await Chat.load(chatId, me, []);
setChat(chat);
} catch (error) {
console.log("Error loading chat", error);
Alert.alert("Error", `Error loading chat: ${error}`);
}
}; };
const joinChat = () => { const joinChat = () => {
@@ -73,7 +63,7 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
text: "Join", text: "Join",
onPress: (chatId) => { onPress: (chatId) => {
if (chatId) { if (chatId) {
loadChat(chatId as ID<Chat>); setChatId(chatId as ID<Chat>);
} else { } else {
Alert.alert("Error", "Chat ID cannot be empty."); Alert.alert("Error", "Chat ID cannot be empty.");
} }
@@ -85,9 +75,11 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
}; };
const sendMessage = () => { const sendMessage = () => {
if (!chat) return; if (!loadedChat) return;
if (message.trim()) { if (message.trim()) {
chat.push(Message.create({ text: message }, { owner: chat._owner })); loadedChat.push(
Message.create({ text: message }, { owner: loadedChat?._owner }),
);
setMessage(""); setMessage("");
} }
}; };
@@ -137,7 +129,7 @@ export default function ChatScreen({ navigation }: { navigation: any }) {
return ( return (
<View className="flex flex-col h-full"> <View className="flex flex-col h-full">
{!chat ? ( {!loadedChat ? (
<View className="flex flex-col h-full items-center justify-center"> <View className="flex flex-col h-full items-center justify-center">
<TouchableOpacity <TouchableOpacity
onPress={createChat} onPress={createChat}

View File

@@ -1,10 +1,12 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
// NOTE: Update this to include the paths to all of your component files.
content: [ content: [
"./app/**/*.{js,jsx,ts,tsx}", "./app/**/*.{js,jsx,ts,tsx}",
"./components/**/*.{js,jsx,ts,tsx}", "./components/**/*.{js,jsx,ts,tsx}",
"./src/**/*.{js,jsx,ts,tsx}", "./src/**/*.{js,jsx,ts,tsx}",
], ],
presets: [require("nativewind/preset")],
theme: { theme: {
extend: {}, extend: {},
}, },

View File

@@ -1,5 +1,95 @@
# chat-vue # chat-vue
## 0.0.30
### Patch Changes
- Updated dependencies [dc62b95]
- Updated dependencies [1de26f8]
- jazz-tools@0.8.51
- jazz-browser@0.8.51
- jazz-vue@0.8.51
## 0.0.29
### Patch Changes
- jazz-browser@0.8.50
- jazz-tools@0.8.50
- jazz-vue@0.8.50
## 0.0.28
### Patch Changes
- jazz-browser@0.8.49
- jazz-tools@0.8.49
- jazz-vue@0.8.49
## 0.0.27
### Patch Changes
- Updated dependencies [635e824]
- Updated dependencies [0a85982]
- jazz-tools@0.8.48
- jazz-browser@0.8.48
- jazz-vue@0.8.48
## 0.0.26
### Patch Changes
- Updated dependencies [6f0bd7f]
- Updated dependencies [fa41f8e]
- Updated dependencies [88d7d9a]
- Updated dependencies [60e35ea]
- jazz-browser@0.8.45
- jazz-tools@0.8.45
- jazz-vue@0.8.45
## 0.0.25
### Patch Changes
- jazz-browser@0.8.44
- jazz-tools@0.8.44
- jazz-vue@0.8.44
## 0.0.24
### Patch Changes
- Updated dependencies [ac216b9]
- jazz-browser@0.8.41
- jazz-tools@0.8.41
- jazz-vue@0.8.41
## 0.0.23
### Patch Changes
- jazz-browser@0.8.40
- jazz-vue@0.8.40
## 0.0.22
### Patch Changes
- Updated dependencies [e386f2b]
- Updated dependencies [249eecb]
- jazz-browser@0.8.39
- jazz-tools@0.8.39
- jazz-vue@0.8.39
## 0.0.21
### Patch Changes
- jazz-browser@0.8.38
- jazz-tools@0.8.38
- jazz-vue@0.8.38
## 0.0.20 ## 0.0.20
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "chat-vue", "name": "chat-vue",
"version": "0.0.20", "version": "0.0.30",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
@@ -25,14 +25,14 @@
"@vitejs/plugin-vue": "^5.1.4", "@vitejs/plugin-vue": "^5.1.4",
"@vitejs/plugin-vue-jsx": "^4.0.1", "@vitejs/plugin-vue-jsx": "^4.0.1",
"@vue/tsconfig": "^0.5.1", "@vue/tsconfig": "^0.5.1",
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.20",
"eslint": "^8.46.0", "eslint": "^9.7.0",
"eslint-plugin-vue": "^9.28.0", "eslint-plugin-vue": "^9.28.0",
"npm-run-all2": "^6.2.3", "npm-run-all2": "^6.2.3",
"postcss": "^8.4.27", "postcss": "^8.4.27",
"tailwindcss": "3.3.2", "tailwindcss": "^3.4.15",
"typescript": "^5.3.3", "typescript": "~5.6.2",
"vite": "^5.0.10", "vite": "^5.4.10",
"vite-plugin-vue-devtools": "^7.4.6", "vite-plugin-vue-devtools": "^7.4.6",
"vue-tsc": "^2.1.6" "vue-tsc": "^2.1.6"
} }

View File

@@ -1,8 +0,0 @@
/** @type {import('tailwindcss').Config} */
export default {
purge: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
};

View File

@@ -0,0 +1,11 @@
import type { Config } from "tailwindcss";
const config: Config = {
content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
};
export default config;

View File

@@ -1,5 +1,105 @@
# jazz-example-chat # jazz-example-chat
## 0.0.125
### Patch Changes
- Updated dependencies [dc62b95]
- Updated dependencies [1de26f8]
- jazz-tools@0.8.51
- jazz-browser-media-images@0.8.51
- jazz-react@0.8.51
## 0.0.124
### Patch Changes
- jazz-react@0.8.50
- jazz-tools@0.8.50
- jazz-browser-media-images@0.8.50
## 0.0.123
### Patch Changes
- jazz-react@0.8.49
- jazz-tools@0.8.49
- jazz-browser-media-images@0.8.49
## 0.0.122
### Patch Changes
- Updated dependencies [635e824]
- Updated dependencies [0a85982]
- jazz-tools@0.8.48
- jazz-browser-media-images@0.8.48
- jazz-react@0.8.48
## 0.0.121
### Patch Changes
- Updated dependencies [6f0bd7f]
- Updated dependencies [fca6a0b]
- Updated dependencies [fa41f8e]
- Updated dependencies [88d7d9a]
- Updated dependencies [60e35ea]
- cojson@0.8.45
- jazz-tools@0.8.45
- jazz-react@0.8.45
- jazz-browser-media-images@0.8.45
## 0.0.120
### Patch Changes
- Updated dependencies [5d20c81]
- cojson@0.8.44
- jazz-react@0.8.44
- jazz-tools@0.8.44
- jazz-browser-media-images@0.8.44
## 0.0.119
### Patch Changes
- Updated dependencies [3252502]
- Updated dependencies [6370348]
- Updated dependencies [ac216b9]
- cojson@0.8.41
- jazz-react@0.8.41
- jazz-tools@0.8.41
- jazz-browser-media-images@0.8.41
## 0.0.118
### Patch Changes
- jazz-browser-media-images@0.8.40
- jazz-react@0.8.40
## 0.0.117
### Patch Changes
- Updated dependencies [249eecb]
- Updated dependencies [3121551]
- jazz-tools@0.8.39
- cojson@0.8.39
- jazz-browser-media-images@0.8.39
- jazz-react@0.8.39
## 0.0.116
### Patch Changes
- Updated dependencies [b00ee91]
- Updated dependencies [f488c09]
- cojson@0.8.38
- jazz-react@0.8.38
- jazz-tools@0.8.38
## 0.0.115 ## 0.0.115
### Patch Changes ### Patch Changes

View File

@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Jazz Chat Example</title> <title>Jazz Chat Example</title>
</head> </head>
<body class="h-full"> <body class="h-full bg-white text-stone-700 dark:text-stone-400 dark:bg-stone-925">
<div id="root" class="h-full"></div> <div id="root" class="h-full"></div>
<script type="module" src="/src/app.tsx"></script> <script type="module" src="/src/app.tsx"></script>
</body> </body>

View File

@@ -1,7 +1,7 @@
{ {
"name": "jazz-example-chat", "name": "jazz-example-chat",
"private": true, "private": true,
"version": "0.0.115", "version": "0.0.125",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
@@ -13,37 +13,25 @@
"test:ui": "playwright test --ui" "test:ui": "playwright test --ui"
}, },
"dependencies": { "dependencies": {
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-toast": "^1.1.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0", "clsx": "^2.0.0",
"cojson": "workspace:0.8.37", "hash-slash": "workspace:*",
"hash-slash": "workspace:0.2.1", "jazz-browser-media-images": "workspace:*",
"jazz-react": "workspace:0.8.37", "jazz-react": "workspace:*",
"jazz-tools": "workspace:0.8.37", "jazz-tools": "workspace:*",
"lucide-react": "^0.274.0", "lucide-react": "^0.274.0",
"qrcode": "^1.5.3", "react": "^18.3.1",
"react": "^18.2.0", "react-dom": "^18.3.1"
"react-dom": "^18.2.0",
"react-router": "^6.16.0",
"react-router-dom": "^6.16.0",
"react-use": "^17.4.0",
"tailwind-merge": "^1.14.0",
"tailwindcss-animate": "^1.0.7",
"uniqolor": "^1.1.0"
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.46.1", "@playwright/test": "^1.46.1",
"@types/qrcode": "^1.5.1", "@types/react": "^18.3.12",
"@types/react": "^18.2.19", "@types/react-dom": "^18.3.1",
"@types/react-dom": "^18.2.7",
"@vitejs/plugin-react-swc": "^3.3.2", "@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.20",
"is-ci": "^3.0.1", "is-ci": "^3.0.1",
"postcss": "^8.4.27", "postcss": "^8.4.27",
"tailwindcss": "3.3.2", "tailwindcss": "^3.4.15",
"typescript": "^5.3.3", "typescript": "~5.6.2",
"vite": "^5.0.10" "vite": "^5.4.10"
} }
} }

View File

@@ -18,7 +18,7 @@ export function App() {
router.navigate("/#/chat/" + chat.id); router.navigate("/#/chat/" + chat.id);
// for https://jazz.tools marketing site demo only // for https://jazz.tools marketing site demo only
onChatLoad(chat, me); onChatLoad(chat);
}; };
return ( return (

View File

@@ -1,21 +1,54 @@
import { createImage } from "jazz-browser-media-images";
import { ID } from "jazz-tools"; import { ID } from "jazz-tools";
import { useState } from "react"; import { useState } from "react";
import { useCoState } from "./main.tsx"; import { useAccount, useCoState } from "./main.tsx";
import { Chat, Message } from "./schema.ts"; import { Chat, Message } from "./schema.ts";
import { import {
BubbleBody, BubbleBody,
BubbleContainer, BubbleContainer,
BubbleImage,
BubbleInfo, BubbleInfo,
BubbleText,
ChatBody, ChatBody,
ChatInput,
EmptyChatMessage, EmptyChatMessage,
ImageInput,
InputBar,
TextInput,
} from "./ui.tsx"; } from "./ui.tsx";
export function ChatScreen(props: { chatID: ID<Chat> }) { export function ChatScreen(props: { chatID: ID<Chat> }) {
const chat = useCoState(Chat, props.chatID, [{}]); const chat = useCoState(Chat, props.chatID, [{}]);
const { me } = useAccount();
const [showNLastMessages, setShowNLastMessages] = useState(30); const [showNLastMessages, setShowNLastMessages] = useState(30);
return chat ? ( if (!chat)
return (
<div className="flex-1 flex justify-center items-center">Loading...</div>
);
const sendImage = (event: React.ChangeEvent<HTMLInputElement>) => {
if (!me?.profile) return;
const file = event.currentTarget.files?.[0];
if (!file) return;
if (file.size > 5000000) {
alert("Please upload an image less than 5MB.");
return;
}
createImage(file, { owner: chat._owner }).then((image) => {
chat.push(
Message.create(
{ text: file.name, image: image },
{ owner: chat._owner },
),
);
});
};
return (
<> <>
<ChatBody> <ChatBody>
{chat.length > 0 ? ( {chat.length > 0 ? (
@@ -35,24 +68,31 @@ export function ChatScreen(props: { chatID: ID<Chat> }) {
</button> </button>
)} )}
</ChatBody> </ChatBody>
<ChatInput
onSubmit={(text) => { <InputBar>
chat.push(Message.create({ text }, { owner: chat._owner })); <ImageInput onImageChange={sendImage} />
}}
/> <TextInput
onSubmit={(text) => {
chat.push(Message.create({ text }, { owner: chat._owner }));
}}
/>
</InputBar>
</> </>
) : (
<div className="flex-1 flex justify-center items-center">Loading...</div>
); );
} }
function ChatBubble(props: { msg: Message }) { function ChatBubble(props: { msg: Message }) {
const lastEdit = props.msg._edits.text; const lastEdit = props.msg._edits.text;
const fromMe = lastEdit.by?.isMe; const fromMe = lastEdit.by?.isMe;
const { text, image } = props.msg;
return ( return (
<BubbleContainer fromMe={fromMe}> <BubbleContainer fromMe={fromMe}>
<BubbleBody fromMe={fromMe}>{props.msg.text}</BubbleBody> <BubbleBody fromMe={fromMe}>
{image && <BubbleImage image={image} />}
<BubbleText text={text} />
</BubbleBody>
<BubbleInfo by={lastEdit.by?.profile?.name} madeAt={lastEdit.madeAt} /> <BubbleInfo by={lastEdit.by?.profile?.name} madeAt={lastEdit.madeAt} />
</BubbleContainer> </BubbleContainer>
); );

View File

@@ -1,78 +1,3 @@
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 20 14.3% 4.1%;
--card: 0 0% 100%;
--card-foreground: 20 14.3% 4.1%;
--popover: 0 0% 100%;
--popover-foreground: 20 14.3% 4.1%;
--primary: 24 9.8% 10%;
--primary-foreground: 60 9.1% 97.8%;
--secondary: 60 4.8% 95.9%;
--secondary-foreground: 24 9.8% 10%;
--muted: 60 4.8% 95.9%;
--muted-foreground: 25 5.3% 44.7%;
--accent: 60 4.8% 95.9%;
--accent-foreground: 24 9.8% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 60 9.1% 97.8%;
--border: 20 5.9% 90%;
--input: 20 5.9% 90%;
--ring: 20 14.3% 4.1%;
--radius: 0.5rem;
}
.dark {
--background: 20 14.3% 4.1%;
--foreground: 60 9.1% 97.8%;
--card: 20 14.3% 4.1%;
--card-foreground: 60 9.1% 97.8%;
--popover: 20 14.3% 4.1%;
--popover-foreground: 60 9.1% 97.8%;
--primary: 60 9.1% 97.8%;
--primary-foreground: 24 9.8% 10%;
--secondary: 12 6.5% 15.1%;
--secondary-foreground: 60 9.1% 97.8%;
--muted: 12 6.5% 15.1%;
--muted-foreground: 24 5.4% 63.9%;
--accent: 12 6.5% 15.1%;
--accent-foreground: 60 9.1% 97.8%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 60 9.1% 97.8%;
--border: 12 6.5% 15.1%;
--input: 12 6.5% 15.1%;
--ring: 24 5.7% 82.9%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
margin: 0;
padding: 0;
}
}

View File

@@ -1,3 +1,4 @@
import { ThemeProvider } from "@/themeProvider.tsx";
import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react"; import { DemoAuthBasicUI, createJazzReactApp, useDemoAuth } from "jazz-react";
import { StrictMode } from "react"; import { StrictMode } from "react";
import { createRoot } from "react-dom/client"; import { createRoot } from "react-dom/client";
@@ -25,9 +26,11 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
} }
createRoot(document.getElementById("root")!).render( createRoot(document.getElementById("root")!).render(
<StrictMode> <ThemeProvider>
<JazzAndAuth> <StrictMode>
<App /> <JazzAndAuth>
</JazzAndAuth> <App />
</StrictMode>, </JazzAndAuth>
</StrictMode>
</ThemeProvider>,
); );

View File

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

View File

@@ -0,0 +1,72 @@
import { createContext, useContext, useEffect, useState } from "react";
type ThemeProviderProps = {
children: React.ReactNode;
defaultTheme?: string;
storageKey?: string;
};
type ThemeProviderState = {
theme: string;
setTheme: (theme: string) => void;
};
const initialState = {
theme: "system",
setTheme: () => null,
};
const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
export function ThemeProvider({
children,
defaultTheme = "system",
storageKey = "vite-ui-theme",
...props
}: ThemeProviderProps) {
const [theme, setTheme] = useState(
() => localStorage.getItem(storageKey) || defaultTheme,
);
useEffect(() => {
const root = window.document.documentElement;
root.classList.remove("light", "dark");
if (theme === "system") {
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
.matches
? "dark"
: "light";
root.classList.add(systemTheme);
return;
}
root.classList.add(theme);
}, [theme]);
const value = {
theme,
setTheme: (theme: string) => {
localStorage.setItem(storageKey, theme);
setTheme(theme);
},
};
return (
<ThemeProviderContext.Provider {...props} value={value}>
{children}
</ThemeProviderContext.Provider>
);
}
// eslint-disable-next-line react-refresh/only-export-components
export const useTheme = () => {
const context = useContext(ThemeProviderContext);
if (context === undefined)
throw new Error("useTheme must be used within a ThemeProvider");
return context;
};

View File

@@ -1,5 +1,8 @@
import clsx from "clsx"; import clsx from "clsx";
import { useId } from "react"; import { ProgressiveImg } from "jazz-react";
import { ImageDefinition } from "jazz-tools";
import { ImageIcon } from "lucide-react";
import { useId, useRef } from "react";
export function AppContainer(props: { children: React.ReactNode }) { export function AppContainer(props: { children: React.ReactNode }) {
return ( return (
@@ -56,7 +59,7 @@ export function BubbleBody(props: {
<div <div
className={clsx( className={clsx(
"line-clamp-10 text-ellipsis whitespace-pre-wrap", "line-clamp-10 text-ellipsis whitespace-pre-wrap",
"rounded-2xl max-w-full py-1 px-3 shadow-sm", "rounded-2xl overflow-hidden max-w-[calc(100%-5rem)] shadow-sm p-1",
props.fromMe props.fromMe
? "bg-white dark:bg-stone-700 dark:text-white" ? "bg-white dark:bg-stone-700 dark:text-white"
: "bg-blue text-white", : "bg-blue text-white",
@@ -67,6 +70,23 @@ export function BubbleBody(props: {
); );
} }
export function BubbleText(props: { text: string }) {
return <p className="px-2 leading-relaxed">{props.text}</p>;
}
export function BubbleImage(props: { image: ImageDefinition }) {
return (
<ProgressiveImg image={props.image}>
{({ src }) => (
<img
className="h-auto max-h-[20rem] max-w-full rounded-t-xl mb-1"
src={src}
/>
)}
</ProgressiveImg>
);
}
export function BubbleInfo(props: { by: string | undefined; madeAt: Date }) { export function BubbleInfo(props: { by: string | undefined; madeAt: Date }) {
return ( return (
<div className="text-xs text-neutral-500 mt-1.5"> <div className="text-xs text-neutral-500 mt-1.5">
@@ -75,17 +95,59 @@ export function BubbleInfo(props: { by: string | undefined; madeAt: Date }) {
); );
} }
export function ChatInput(props: { onSubmit: (text: string) => void }) { export function InputBar(props: { children: React.ReactNode }) {
return (
<div className="p-3 bg-white border-t shadow-2xl mt-auto flex gap-1 dark:bg-transparent dark:border-stone-800">
{props.children}
</div>
);
}
export function ImageInput({
onImageChange,
}: { onImageChange?: (event: React.ChangeEvent<HTMLInputElement>) => void }) {
const inputRef = useRef<HTMLInputElement>(null);
const onUploadClick = () => {
inputRef.current?.click();
};
return (
<>
<button
type="button"
aria-label="Send image"
title="Send image"
onClick={onUploadClick}
className="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 className="sr-only">
Image
<input
ref={inputRef}
type="file"
accept="image/png, image/jpeg, image/gif"
onChange={onImageChange}
/>
</label>
</>
);
}
export function TextInput(props: { onSubmit: (text: string) => void }) {
const inputId = useId(); const inputId = useId();
return ( return (
<div className="p-3 bg-white border-t shadow-2xl mt-auto dark:bg-transparent dark:border-stone-800"> <div className="flex-1">
<label className="sr-only" htmlFor={inputId}> <label className="sr-only" htmlFor={inputId}>
Type a message and press Enter Type a message and press Enter
</label> </label>
<input <input
id={inputId} id={inputId}
className="rounded-full py-2 px-4 border block w-full dark:bg-black dark:text-white dark:border-stone-700" className="rounded-full py-1 px-3 border block w-full placeholder:text-stone-500 dark:bg-black dark:text-white dark:border-stone-700"
placeholder="Type a message and press Enter" placeholder="Type a message and press Enter"
maxLength={2048} maxLength={2048}
onKeyDown={({ key, currentTarget: input }) => { onKeyDown={({ key, currentTarget: input }) => {

View File

@@ -2,20 +2,10 @@
// This is NOT needed to make the chat work // This is NOT needed to make the chat work
import { Chat } from "@/schema.ts"; import { Chat } from "@/schema.ts";
import { Account, CoValue, ID } from "jazz-tools";
export function waitForUpload(id: ID<CoValue>, me: Account) { export function onChatLoad(chat: Chat) {
const syncManager = me._raw.core.node.syncManager;
const peers = syncManager.getPeers();
return Promise.all(
peers.map((peer) => syncManager.waitForUploadIntoPeer(peer.id, id)),
);
}
export function onChatLoad(chat: Chat, me: Account) {
if (window.parent) { if (window.parent) {
waitForUpload(chat.id, me).then(() => { chat.waitForSync().then(() => {
window.parent.postMessage( window.parent.postMessage(
{ type: "chat-load", id: "/chat/" + chat.id }, { type: "chat-load", id: "/chat/" + chat.id },
"*", "*",

View File

@@ -1,82 +0,0 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./pages/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./app/**/*.{ts,tsx}",
"./src/**/*.{ts,tsx}",
],
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
colors: {
blue: {
700: "#3313F7",
DEFAULT: "#3313F7",
},
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
},
keyframes: {
"accordion-down": {
from: { height: 0 },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: 0 },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
lineClamp: {
10: "10",
},
},
},
plugins: [require("tailwindcss-animate")],
};

View File

@@ -0,0 +1,79 @@
import type { Config } from "tailwindcss";
import plugin from "tailwindcss/plugin";
const colors = require("tailwindcss/colors");
const stonePalette = {
50: "oklch(0.988281 0.002 75)",
75: "oklch(0.980563 0.002 75)",
100: "oklch(0.964844 0.002 75)",
200: "oklch(0.917969 0.002 75)",
300: "oklch(0.853516 0.002 75)",
400: "oklch(0.789063 0.002 75)",
500: "oklch(0.726563 0.002 75)",
600: "oklch(0.613281 0.002 75)",
700: "oklch(0.523438 0.002 75)",
800: "oklch(0.412109 0.002 75)",
900: "oklch(0.302734 0.002 75)",
925: "oklch(0.220000 0.002 75)",
950: "oklch(0.193359 0.002 75)",
} as const;
const stonePaletteWithAlpha = { ...stonePalette };
Object.keys(stonePalette).forEach((key) => {
stonePaletteWithAlpha[key] = stonePaletteWithAlpha[key].replace(
")",
"/ <alpha-value>)",
);
});
const config: Config = {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {
colors: {
stone: stonePaletteWithAlpha,
blue: {
...colors.indigo,
500: "#5870F1",
DEFAULT: "#3313F7",
},
},
container: {
center: true,
padding: {
DEFAULT: "0.75rem",
sm: "1rem",
},
screens: {
md: "500px",
lg: "500px",
xl: "500px",
},
},
},
},
plugins: [
plugin(({ addBase }) =>
addBase({
":root": {
"--gcmp-border-color": stonePalette[200],
"--gcmp-invert-border-color": stonePalette[900],
},
"*": {
borderColor: "var(--gcmp-border-color)",
},
"@media (prefers-color-scheme: dark)": {
"*": {
borderColor: "var(--gcmp-invert-border-color)",
},
},
"*:focus": {
outline: "none",
},
}),
),
],
} as const;
export default config;

View File

@@ -38,14 +38,11 @@ test("chat between two users", async ({ page }) => {
await chatPage.sendMessage(message2ByLuigi); await chatPage.sendMessage(message2ByLuigi);
await chatPage.expectMessageRow(message2ByLuigi); await chatPage.expectMessageRow(message2ByLuigi);
// This breaks with (Error: Error reading from peer storage, handling msg) await chatPage.logout();
// await chatPage.logout(); await loginPage.loginAs(mario);
// await loginPage.loginAs(mario);
// await chatPage.expectLoaded(); await page.goto(roomURL);
// await page.goto(roomURL); await chatPage.expectMessageRow(message1ByMario);
await chatPage.expectMessageRow(message2ByLuigi);
// await chatPage.expectMessageRow(message1ByMario);
// await chatPage.expectMessageRow(message2ByLuigi);
}); });

View File

@@ -25,7 +25,7 @@ export class LoginPage {
async loginAs(value: string) { async loginAs(value: string) {
await this.page await this.page
.getByRole("button", { .getByRole("button", {
name: `Log in as "${value}"`, name: value,
}) })
.click(); .click();
} }

View File

@@ -0,0 +1,8 @@
{
"build": {
"env": {
"APP_NAME": "jazz-chat"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
}

View File

@@ -1,5 +1,92 @@
# minimal-auth-clerk # minimal-auth-clerk
## 0.0.24
### Patch Changes
- Updated dependencies [dc62b95]
- Updated dependencies [1de26f8]
- jazz-tools@0.8.51
- jazz-react@0.8.51
- jazz-react-auth-clerk@0.8.51
## 0.0.23
### Patch Changes
- jazz-react@0.8.50
- jazz-react-auth-clerk@0.8.50
- jazz-tools@0.8.50
## 0.0.22
### Patch Changes
- jazz-react@0.8.49
- jazz-react-auth-clerk@0.8.49
- jazz-tools@0.8.49
## 0.0.21
### Patch Changes
- Updated dependencies [635e824]
- Updated dependencies [0a85982]
- jazz-tools@0.8.48
- jazz-react@0.8.48
- jazz-react-auth-clerk@0.8.48
## 0.0.20
### Patch Changes
- Updated dependencies [fa41f8e]
- Updated dependencies [88d7d9a]
- Updated dependencies [60e35ea]
- jazz-tools@0.8.45
- jazz-react@0.8.45
- jazz-react-auth-clerk@0.8.45
## 0.0.19
### Patch Changes
- jazz-react@0.8.44
- jazz-react-auth-clerk@0.8.44
- jazz-tools@0.8.44
## 0.0.18
### Patch Changes
- jazz-react@0.8.41
- jazz-react-auth-clerk@0.8.41
- jazz-tools@0.8.41
## 0.0.17
### Patch Changes
- jazz-react@0.8.40
- jazz-react-auth-clerk@0.8.40
## 0.0.16
### Patch Changes
- Updated dependencies [249eecb]
- jazz-tools@0.8.39
- jazz-react@0.8.39
- jazz-react-auth-clerk@0.8.39
## 0.0.15
### Patch Changes
- jazz-react@0.8.38
- jazz-react-auth-clerk@0.8.38
- jazz-tools@0.8.38
## 0.0.14 ## 0.0.14
### Patch Changes ### Patch Changes

View File

@@ -1,4 +1,4 @@
# Passkey authentication example with Jazz and React # Clerk authentication example with Jazz and React
This is an example of how to use clerk authentication with Jazz. This is an example of how to use clerk authentication with Jazz.

View File

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

View File

@@ -0,0 +1,8 @@
{
"build": {
"env": {
"APP_NAME": "clerk-demo"
}
},
"ignoreCommand": "node ../../ignore-vercel-build.js"
}

23
examples/file-share-svelte/.gitignore vendored Normal file
View File

@@ -0,0 +1,23 @@
node_modules
# Output
.output
.vercel
/.svelte-kit
/build
# OS
.DS_Store
Thumbs.db
# Env
.env
.env.*
!.env.example
!.env.test
# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
playwright-report

View File

@@ -0,0 +1 @@
engine-strict=true

View File

@@ -0,0 +1,4 @@
# Package Managers
package-lock.json
pnpm-lock.yaml
yarn.lock

View File

@@ -0,0 +1,16 @@
{
"useTabs": false,
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
"overrides": [
{
"files": "*.svelte",
"options": {
"parser": "svelte"
}
}
]
}

View File

@@ -0,0 +1,72 @@
# file-share-svelte
## 0.0.10
### Patch Changes
- Updated dependencies [dc62b95]
- Updated dependencies [1de26f8]
- jazz-tools@0.8.51
- jazz-svelte@0.8.51
## 0.0.9
### Patch Changes
- jazz-tools@0.8.50
- jazz-svelte@0.8.50
## 0.0.8
### Patch Changes
- jazz-tools@0.8.49
- jazz-svelte@0.8.49
## 0.0.7
### Patch Changes
- Updated dependencies [635e824]
- Updated dependencies [0a85982]
- jazz-tools@0.8.48
- jazz-svelte@0.8.48
## 0.0.6
### Patch Changes
- Updated dependencies [fa41f8e]
- Updated dependencies [88d7d9a]
- Updated dependencies [60e35ea]
- jazz-tools@0.8.45
- jazz-svelte@0.8.45
## 0.0.5
### Patch Changes
- jazz-tools@0.8.44
- jazz-svelte@0.8.44
## 0.0.4
### Patch Changes
- jazz-tools@0.8.41
- jazz-svelte@0.8.41
## 0.0.3
### Patch Changes
- jazz-svelte@0.8.40
## 0.0.2
### Patch Changes
- Updated dependencies [249eecb]
- Updated dependencies [aa21072]
- jazz-tools@0.8.39
- jazz-svelte@0.8.39

View File

@@ -0,0 +1,56 @@
# File share example with Jazz and Svelte
This example app demonstrates how to implement secure file sharing in a Svelte application using Jazz.
## Features
This example showcases how to:
- Upload files securely with end-to-end encryption
- Generate and manage sharing links
- Handle file downloads with decryption
- Manage file access permissions
- Authenticate users using passkeys
## Getting Started
1. Clone the repository:
```sh
git clone https://github.com/garden-co/jazz.git
```
2. Navigate to the example directory:
```sh
cd examples/file-share-svelte
```
3. Install dependencies:
```sh
pnpm install
```
4. Run the development server:
```sh
turbo dev
```
5. Open your browser and visit [http://localhost:5173](http://localhost:5173)
---
Alternatively, you can build and preview the app:
```sh
turbo build
pnpm preview
```
## Learn More
- [Jazz Documentation](https://jazz.tools/docs/svelte)
- [Svelte Documentation](https://svelte.dev)
- [WebAuthn API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API)

View File

@@ -0,0 +1,33 @@
import js from '@eslint/js';
import prettier from 'eslint-config-prettier';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
import ts from 'typescript-eslint';
export default ts.config(
js.configs.recommended,
...ts.configs.recommended,
...svelte.configs['flat/recommended'],
prettier,
...svelte.configs['flat/prettier'],
{
languageOptions: {
globals: {
...globals.browser,
...globals.node
}
}
},
{
files: ['**/*.svelte'],
languageOptions: {
parserOptions: {
parser: ts.parser
}
}
},
{
ignores: ['build/', '.svelte-kit/', 'dist/']
}
);

View File

@@ -0,0 +1,47 @@
{
"name": "file-share-svelte",
"version": "0.0.10",
"private": true,
"type": "module",
"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": "playwright test",
"test:ui": "playwright test --ui"
},
"devDependencies": {
"@sveltejs/adapter-vercel": "^5.5.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^4.0.1",
"@types/is-ci": "^3.0.4",
"autoprefixer": "^10.4.20",
"eslint": "^9.7.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.36.0",
"globals": "^15.11.0",
"is-ci": "^3.0.1",
"prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.6",
"prettier-plugin-tailwindcss": "^0.6.5",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"tailwindcss": "^3.4.15",
"typescript": "~5.6.2",
"typescript-eslint": "^8.0.0",
"vite": "^5.4.10"
},
"dependencies": {
"@tailwindcss/typography": "^0.5.15",
"jazz-svelte": "workspace:*",
"jazz-tools": "workspace:*",
"lucide-svelte": "^0.463.0",
"svelte-sonner": "^0.3.28"
}
}

View File

@@ -0,0 +1,53 @@
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,
},
],
});

View File

@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
};

View File

@@ -0,0 +1,3 @@
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';

13
examples/file-share-svelte/src/app.d.ts vendored Normal file
View File

@@ -0,0 +1,13 @@
// See https://svelte.dev/docs/kit/types#app.d.ts
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface PageState {}
// interface Platform {}
}
}
export {};

View File

@@ -0,0 +1,12 @@
<!doctype html>
<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" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View File

@@ -0,0 +1,117 @@
<script lang="ts">
import { slide } from 'svelte/transition';
import { SharedFile } from '$lib/schema';
import { FileStream } from 'jazz-tools';
import { File, FileDown, Trash2, Link2 } from 'lucide-svelte';
import { useAccount } from '$lib/jazz';
import { toast } from 'svelte-sonner';
import { formatFileSize } from '$lib/utils';
const {
file,
loading = false,
onDelete
}: {
file: SharedFile;
loading?: boolean;
onDelete: (file: SharedFile) => void;
} = $props();
const { me } = useAccount();
const isAdmin = $derived(me && file._owner?.myRole() === 'admin');
async function downloadFile() {
if (!file._refs.file?.id || !me) {
toast.error('Failed to download file');
return;
}
try {
const fileId = file._refs.file.id;
// Load the file as a blob, can take a while
const blob = await FileStream.loadAsBlob(fileId, me, {});
if (!blob) {
toast.error('Failed to download file');
return;
}
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = file.name;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
toast.success('File downloaded successfully');
} catch (error) {
console.error('Error downloading file:', error);
toast.error('Failed to download file');
}
}
async function shareFile() {
try {
const fileUrl = `${window.location.origin}/file/${file.id}`;
await navigator.clipboard.writeText(fileUrl);
toast.success('Share link copied to clipboard');
} catch (error) {
console.error('Error sharing file:', error);
toast.error('Failed to create share link');
}
}
</script>
<div
class="flex items-center justify-between rounded-lg border border-gray-200 bg-white p-4"
transition:slide={{ duration: 200 }}
>
<div class="flex items-center space-x-4">
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600">
<File class="h-6 w-6" />
</div>
<div>
<a href="/file/{file.id}" class="hover:text-blue-600 hover:underline">
<h3 class="font-medium text-gray-900">{file.name}</h3>
</a>
<p class="text-sm text-gray-500">
{isAdmin ? 'Owned by you' : ''} • Uploaded {new Date(
file.createdAt || 0
).toLocaleDateString()}
{formatFileSize(file.size || 0)}
</p>
</div>
</div>
<div class="flex items-center space-x-2">
{#if loading}
<div class="text-sm text-gray-500">Uploading...</div>
{:else}
<button
onclick={downloadFile}
class="rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700"
aria-label="Download file"
>
<FileDown class="h-5 w-5" />
</button>
{#if isAdmin}
<button
onclick={shareFile}
class="rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700"
aria-label="Share file"
>
<Link2 class="h-5 w-5" />
</button>
<button
onclick={() => onDelete(file)}
class="rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-red-600"
aria-label="Delete file"
>
<Trash2 class="h-5 w-5" />
</button>
{/if}
{/if}
</div>
</div>

View File

@@ -0,0 +1 @@
// place files you want to import through the `$lib` alias in this folder.

View File

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

View File

@@ -0,0 +1,49 @@
import { Account, CoList, CoMap, FileStream, Profile, co, Group } from 'jazz-tools';
export class SharedFile extends CoMap {
name = co.string;
file = co.ref(FileStream);
createdAt = co.Date;
uploadedAt = co.Date;
size = co.number;
}
export class FileShareProfile extends Profile {
name = co.string;
}
export class ListOfSharedFiles extends CoList.Of(co.ref(SharedFile)) {}
export class FileShareAccountRoot extends CoMap {
type = co.string;
sharedFiles = co.ref(ListOfSharedFiles);
publicGroup = co.ref(Group);
}
export class FileShareAccount extends Account {
profile = co.ref(FileShareProfile);
root = co.ref(FileShareAccountRoot);
/** The account migration is run on account creation and on every log-in.
* You can use it to set up the account root and any other initial CoValues you need.
*/
async migrate() {
await this._refs.root?.load();
// Initialize root if it doesn't exist
if (!this.root || this.root.type !== 'file-share-account') {
// Create a group that will own all shared files
const publicGroup = Group.create({ owner: this });
publicGroup.addMember('everyone', 'reader');
this.root = FileShareAccountRoot.create(
{
type: 'file-share-account',
sharedFiles: ListOfSharedFiles.create([], { owner: publicGroup }),
publicGroup
},
{ owner: this }
);
}
}
}

View File

@@ -0,0 +1,22 @@
/**
* Formats a file size in bytes to a human readable string
* @param bytes The size in bytes
* @returns A formatted string like "1.5 MB"
*/
export function formatFileSize(bytes: number): string {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
}
/**
* Generates a temporary file ID based on the file name and creation time
* @param fileName The name of the file
* @param createdAt The creation date
* @returns A unique file ID string
*/
export function generateTempFileId(fileName: string, createdAt: Date): string {
return `file-${fileName}-${createdAt.getTime()}`;
}

View File

@@ -0,0 +1,32 @@
<script lang="ts">
import { Provider } from '$lib/jazz';
import { PasskeyAuthBasicUI, usePasskeyAuth } from 'jazz-svelte';
import { Toaster } from 'svelte-sonner';
import '../app.css';
let { children } = $props();
const auth = usePasskeyAuth({
appName: 'File Share'
});
</script>
<svelte:head>
<title>File Share</title>
</svelte:head>
<Toaster richColors />
{#if auth.state.state === 'ready'}
<div class="fixed inset-0 flex items-center justify-center bg-gray-50/80">
<div class="rounded-lg bg-white p-8 shadow-lg">
<PasskeyAuthBasicUI state={auth.state} />
</div>
</div>
{/if}
{#if auth.current}
<Provider auth={auth.current} peer="wss://cloud.jazz.tools/?key=file-share-svelte@garden.co">
<div class="min-h-screen bg-gray-100">
{@render children()}
</div>
</Provider>
{/if}

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