From 55edbf28135cc374e64761693baf3b12e01eb880 Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Sun, 24 Nov 2024 06:19:43 +0200 Subject: [PATCH 01/29] feat: basic but need to move to js sdk --- demo/with-rainbow/src/app/app.tsx | 7 +- demo/with-rainbow/src/main.tsx | 13 +- demo/with-rainbow/src/polyfills.ts | 4 + demo/with-rainbow/tsconfig.app.json | 1 + demo/with-rainbow/tsconfig.json | 1 + demo/with-rainbow/vite.config.ts | 6 +- package.json | 8 +- .../lib/hooks/primaryName/usePrimaryName.ts | 7 + .../react/src/lib/hooks/records/useRecords.ts | 2 +- .../react/src/lib/query/index.ts | 1 + .../plugin/src/lib/plugins/index.tsx | 11 - .../efp-plugin/src/lib/plugins/index.tsx | 18 - .../src/lib/ui/Checkbox/Checkbox.module.css | 35 + .../ui/src/lib/ui/Checkbox/index.tsx | 22 + .../ui/src/lib/ui/Label/Label.module.css | 18 + .../@justweb3/ui/src/lib/ui/Label/index.tsx | 21 + .../ui/src/lib/ui/Sheet/Sheet.module.css | 284 ++++++++ .../@justweb3/ui/src/lib/ui/Sheet/index.tsx | 128 ++++ .../ui/src/lib/ui/Tabs/Tabs.module.css | 6 +- packages/@justweb3/ui/src/lib/ui/index.ts | 3 + .../ui/src/stories/ui/checkbox.stories.tsx | 20 + .../ui/src/stories/ui/label.stories.tsx | 32 + .../ui/src/stories/ui/sheet.stories.tsx | 72 ++ .../lib/components/JustWeb3Button/index.tsx | 22 +- packages/@justweb3/widget/src/lib/index.ts | 4 +- packages/@justweb3/xmtp-plugin/.babelrc | 12 + packages/@justweb3/xmtp-plugin/.env.example | 6 + packages/@justweb3/xmtp-plugin/.eslintrc.json | 40 ++ packages/@justweb3/xmtp-plugin/.gitignore | 1 + .../@justweb3/xmtp-plugin/.storybook/main.ts | 36 + .../xmtp-plugin/.storybook/polyfills.ts | 4 + .../xmtp-plugin/.storybook/preview.tsx | 3 + packages/@justweb3/xmtp-plugin/.svgrrc.js | 6 + packages/@justweb3/xmtp-plugin/CHANGELOG.md | 675 ++++++++++++++++++ packages/@justweb3/xmtp-plugin/README.md | 58 ++ packages/@justweb3/xmtp-plugin/env.d.ts | 15 + packages/@justweb3/xmtp-plugin/jest.config.ts | 12 + packages/@justweb3/xmtp-plugin/package.json | 26 + packages/@justweb3/xmtp-plugin/project.json | 131 ++++ .../@justweb3/xmtp-plugin/release.config.js | 46 ++ .../@justweb3/xmtp-plugin/rollup.config.cjs | 22 + packages/@justweb3/xmtp-plugin/src/index.ts | 1 + .../src/lib/components/ChatButton/index.tsx | 53 ++ .../src/lib/components/ChatList/index.tsx | 17 + .../src/lib/components/ChatSheet/index.tsx | 117 +++ .../src/lib/components/MessageItem/index.tsx | 88 +++ .../@justweb3/xmtp-plugin/src/lib/index.ts | 1 + .../xmtp-plugin/src/lib/plugins/index.tsx | 26 + .../providers/JustWeb3XMTPProvider/index.tsx | 71 ++ .../xmtp-plugin/src/stories/xmtp.stories.tsx | 128 ++++ packages/@justweb3/xmtp-plugin/tsconfig.json | 33 + .../@justweb3/xmtp-plugin/tsconfig.lib.json | 39 + .../@justweb3/xmtp-plugin/tsconfig.spec.json | 27 + .../xmtp-plugin/tsconfig.storybook.json | 42 ++ packages/@justweb3/xmtp-plugin/typedoc.json | 7 + .../xmtp-plugin/update-package-json.js | 31 + yarn.lock | 413 ++++++++++- 57 files changed, 2868 insertions(+), 65 deletions(-) create mode 100644 demo/with-rainbow/src/polyfills.ts create mode 100644 packages/@justweb3/ui/src/lib/ui/Checkbox/Checkbox.module.css create mode 100644 packages/@justweb3/ui/src/lib/ui/Checkbox/index.tsx create mode 100644 packages/@justweb3/ui/src/lib/ui/Label/Label.module.css create mode 100644 packages/@justweb3/ui/src/lib/ui/Label/index.tsx create mode 100644 packages/@justweb3/ui/src/lib/ui/Sheet/Sheet.module.css create mode 100644 packages/@justweb3/ui/src/lib/ui/Sheet/index.tsx create mode 100644 packages/@justweb3/ui/src/stories/ui/checkbox.stories.tsx create mode 100644 packages/@justweb3/ui/src/stories/ui/label.stories.tsx create mode 100644 packages/@justweb3/ui/src/stories/ui/sheet.stories.tsx create mode 100644 packages/@justweb3/xmtp-plugin/.babelrc create mode 100644 packages/@justweb3/xmtp-plugin/.env.example create mode 100644 packages/@justweb3/xmtp-plugin/.eslintrc.json create mode 100644 packages/@justweb3/xmtp-plugin/.gitignore create mode 100644 packages/@justweb3/xmtp-plugin/.storybook/main.ts create mode 100644 packages/@justweb3/xmtp-plugin/.storybook/polyfills.ts create mode 100644 packages/@justweb3/xmtp-plugin/.storybook/preview.tsx create mode 100644 packages/@justweb3/xmtp-plugin/.svgrrc.js create mode 100644 packages/@justweb3/xmtp-plugin/CHANGELOG.md create mode 100644 packages/@justweb3/xmtp-plugin/README.md create mode 100644 packages/@justweb3/xmtp-plugin/env.d.ts create mode 100644 packages/@justweb3/xmtp-plugin/jest.config.ts create mode 100644 packages/@justweb3/xmtp-plugin/package.json create mode 100644 packages/@justweb3/xmtp-plugin/project.json create mode 100644 packages/@justweb3/xmtp-plugin/release.config.js create mode 100644 packages/@justweb3/xmtp-plugin/rollup.config.cjs create mode 100644 packages/@justweb3/xmtp-plugin/src/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx create mode 100644 packages/@justweb3/xmtp-plugin/tsconfig.json create mode 100644 packages/@justweb3/xmtp-plugin/tsconfig.lib.json create mode 100644 packages/@justweb3/xmtp-plugin/tsconfig.spec.json create mode 100644 packages/@justweb3/xmtp-plugin/tsconfig.storybook.json create mode 100644 packages/@justweb3/xmtp-plugin/typedoc.json create mode 100644 packages/@justweb3/xmtp-plugin/update-package-json.js diff --git a/demo/with-rainbow/src/app/app.tsx b/demo/with-rainbow/src/app/app.tsx index 073f4722..af04f9bf 100644 --- a/demo/with-rainbow/src/app/app.tsx +++ b/demo/with-rainbow/src/app/app.tsx @@ -14,6 +14,7 @@ import { WagmiProvider } from 'wagmi'; import { mainnet, sepolia } from 'wagmi/chains'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { EFPPlugin } from '@justweb3/efp-plugin'; +import { XMTPPlugin } from '@justweb3/xmtp-plugin'; import { JustVerifiedPlugin } from '@justverified/plugin'; const queryClient = new QueryClient(); @@ -35,7 +36,11 @@ const JustaNameConfig: JustWeb3ProviderConfig = { }, ], openOnWalletConnect: true, - plugins: [EFPPlugin, JustVerifiedPlugin(['github', 'email', 'discord'])], + plugins: [ + XMTPPlugin, + EFPPlugin, + JustVerifiedPlugin(['github', 'email', 'discord']), + ], dev: import.meta.env.VITE_APP_DEV === 'true', allowedEns: 'all', }; diff --git a/demo/with-rainbow/src/main.tsx b/demo/with-rainbow/src/main.tsx index 9526fa36..c1f6bf6d 100644 --- a/demo/with-rainbow/src/main.tsx +++ b/demo/with-rainbow/src/main.tsx @@ -1,11 +1,12 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './app/app' +import './polyfills'; +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './app/app'; import '@rainbow-me/rainbowkit/styles.css'; -import './index.css' +import './index.css'; ReactDOM.createRoot(document.getElementById('root')!).render( - , -) + +); diff --git a/demo/with-rainbow/src/polyfills.ts b/demo/with-rainbow/src/polyfills.ts new file mode 100644 index 00000000..38b13be9 --- /dev/null +++ b/demo/with-rainbow/src/polyfills.ts @@ -0,0 +1,4 @@ +import { Buffer } from 'buffer'; + +window.Buffer = window.Buffer ?? Buffer; +window.global = window.global ?? window; diff --git a/demo/with-rainbow/tsconfig.app.json b/demo/with-rainbow/tsconfig.app.json index 38eaf770..3814d16b 100644 --- a/demo/with-rainbow/tsconfig.app.json +++ b/demo/with-rainbow/tsconfig.app.json @@ -13,6 +13,7 @@ "@justweb3/ui": ["packages/@justweb3/ui"], "@justweb3/widget": ["packages/@justweb3/widget"], "@justweb3/efp-plugin": ["packages/@justweb3/efp-plugin"], + "@justweb3/xmtp-plugin": ["packages/@justweb3/xmtp-plugin"], "@justverified/plugin": ["packages/@justverified/plugin"] } }, diff --git a/demo/with-rainbow/tsconfig.json b/demo/with-rainbow/tsconfig.json index ecd7c3f7..7b44c3dc 100644 --- a/demo/with-rainbow/tsconfig.json +++ b/demo/with-rainbow/tsconfig.json @@ -13,6 +13,7 @@ "@justweb3/ui": ["packages/@justweb3/ui"], "@justweb3/widget": ["packages/@justweb3/widget"], "@justweb3/efp-plugin": ["packages/@justweb3/efp-plugin"], + "@justweb3/xmtp-plugin": ["packages/@justweb3/xmtp-plugin"], "@justverified/plugin": ["packages/@justverified/plugin"] } }, diff --git a/demo/with-rainbow/vite.config.ts b/demo/with-rainbow/vite.config.ts index 7220dc2b..e4c5f14c 100644 --- a/demo/with-rainbow/vite.config.ts +++ b/demo/with-rainbow/vite.config.ts @@ -2,6 +2,7 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; +import { nodePolyfills } from 'vite-plugin-node-polyfills'; export default defineConfig({ root: __dirname, @@ -17,11 +18,8 @@ export default defineConfig({ host: 'localhost', }, - plugins: [react(), nxViteTsPaths()], + plugins: [nodePolyfills(), react(), nxViteTsPaths()], - define: { - process: { env: process.env }, - }, // Uncomment this if you are using workers. // worker: { // plugins: [ nxViteTsPaths() ], diff --git a/package.json b/package.json index 80cc42e6..bbf115d2 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,12 @@ "@vitejs/plugin-react-swc": "^3.5.0", "@walletconnect/react-native-compat": "^2.11.2", "@web3modal/wagmi-react-native": "^1.2.0", + "@xmtp/content-type-reaction": "^1.1.11", + "@xmtp/content-type-read-receipt": "^1.1.12", + "@xmtp/content-type-remote-attachment": "^1.1.12", + "@xmtp/content-type-reply": "^1.1.12", + "@xmtp/react-sdk": "^9.0.0", + "@xmtp/xmtp-js": "^13.0.4", "axios": "^1.6.0", "class-variance-authority": "^0.7.0", "cors": "^2.8.5", @@ -81,7 +87,7 @@ "prism-react-renderer": "^2.4.0", "punycode": "^2.3.1", "qs": "^6.12.0", - "react": "18.3.1", + "react": "^18.3.1", "react-code-blocks": "^0.1.6", "react-dom": "18.3.1", "react-hook-form": "^7.53.0", diff --git a/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts b/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts index a140b5cf..09211636 100644 --- a/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts +++ b/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts @@ -81,6 +81,13 @@ export const usePrimaryName = ( const query = useQuery({ ...defaultOptions, + retry: (_count, error) => { + console.log('Error fetching primary name', error, _count); + if (error?.message.includes('PrimaryNameNotFound')) { + return false; + } + return _count < 3; + }, queryKey: buildPrimaryName(params?.address || '', _chainId), queryFn: () => getPrimaryName({ diff --git a/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts b/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts index 6139da3e..1e4ade79 100644 --- a/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts +++ b/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts @@ -155,7 +155,7 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { return { isRecordsPending: query.isPending, isRecordsFetching: query.isFetching, - isRecordsLoading: query.isLoading, + isRecordsLoading: query.isPending || query.isFetching, records: query.data, getRecords: getRecordsInternal, refetchRecords: query.refetch, diff --git a/packages/@justaname.id/react/src/lib/query/index.ts b/packages/@justaname.id/react/src/lib/query/index.ts index f627c6f6..f59f7f6f 100644 --- a/packages/@justaname.id/react/src/lib/query/index.ts +++ b/packages/@justaname.id/react/src/lib/query/index.ts @@ -6,4 +6,5 @@ export const defaultOptions = { refetchOnWindowFocus: false, retry: 3, retryDelay: 1000, + retryOnMount: false, }; diff --git a/packages/@justverified/plugin/src/lib/plugins/index.tsx b/packages/@justverified/plugin/src/lib/plugins/index.tsx index 6ff52931..dffc5719 100644 --- a/packages/@justverified/plugin/src/lib/plugins/index.tsx +++ b/packages/@justverified/plugin/src/lib/plugins/index.tsx @@ -12,7 +12,6 @@ export const JustVerifiedPlugin = ( mApp = 'justverified.eth' ): JustaPlugin => ({ name: 'JustVerifiedPlugin', - // mApps: [mApp], components: { Provider: (pluginApi, children) => { const chainId = pluginApi.chainId; @@ -85,16 +84,6 @@ export const JustVerifiedPlugin = ( } pluginApi.setState('verificationOpen', true); - - // setTimeout(() => { - // if ( - // canEnableMApps && - // !enabledMApps.includes('justverified.eth') && - // !Object.values(verifiableRecords).some((value) => value) - // ) { - // pluginApi.handleOpenAuthorizeMAppDialog(mApp, true); - // } - // }, 1000); }, onEnsSignOut: (pluginApi, ens) => { pluginApi.setState('verificationOpen', false); diff --git a/packages/@justweb3/efp-plugin/src/lib/plugins/index.tsx b/packages/@justweb3/efp-plugin/src/lib/plugins/index.tsx index 90594f3a..3a5473a1 100644 --- a/packages/@justweb3/efp-plugin/src/lib/plugins/index.tsx +++ b/packages/@justweb3/efp-plugin/src/lib/plugins/index.tsx @@ -22,23 +22,5 @@ export const EFPPlugin: JustaPlugin = { return ; }, - // SignInMenu: (pluginApi) => { - // if (pluginApi.chainId !== 1) { - // return null; - // } - // return ( - // } - // style={{ - // width: '100%', - // }} - // onClick={() => { - // pluginApi.setState('efpOpen', true); - // }} - // right={} - // /> - // ); - // }, }, }; diff --git a/packages/@justweb3/ui/src/lib/ui/Checkbox/Checkbox.module.css b/packages/@justweb3/ui/src/lib/ui/Checkbox/Checkbox.module.css new file mode 100644 index 00000000..99de7a80 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/ui/Checkbox/Checkbox.module.css @@ -0,0 +1,35 @@ +.checkbox { + height: 1rem; + width: 1rem; + padding: 1px; + border-radius: 0.25rem; + border: 1px solid var(--justweb3-foreground-color-4); + background-color: var(--justweb3-background-color); + transition-property: background-color, border-color, color, fill, stroke; + transition-duration: 200ms; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +.checkbox[data-state='checked'] { + background-color: var(--justweb3-primary-color); + border-color: var(--justweb3-primary-color); +} + +.checkbox:disabled { + opacity: 0.5; + pointer-events: none; +} + +.indicator { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; +} + +.icon { + width: 0.75rem; + height: 0.75rem; + color: var(--justweb3-primary-color-foreground); +} diff --git a/packages/@justweb3/ui/src/lib/ui/Checkbox/index.tsx b/packages/@justweb3/ui/src/lib/ui/Checkbox/index.tsx new file mode 100644 index 00000000..a4004fe1 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/ui/Checkbox/index.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; +import * as CheckboxPrimitive from '@radix-ui/react-checkbox'; +import { Check } from 'lucide-react'; +import styles from './Checkbox.module.css'; + +const Checkbox = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + + +)); +Checkbox.displayName = CheckboxPrimitive.Root.displayName; + +export { Checkbox }; diff --git a/packages/@justweb3/ui/src/lib/ui/Label/Label.module.css b/packages/@justweb3/ui/src/lib/ui/Label/Label.module.css new file mode 100644 index 00000000..7d8e9420 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/ui/Label/Label.module.css @@ -0,0 +1,18 @@ +.label { + font-size: 0.875rem; + font-weight: 500; + line-height: 1; + font-family: var(--justweb3-font-family); + color: var(--justweb3-foreground-color-2); +} + +.required::after { + content: "*"; + margin-left: 0.25rem; + color: var(--justweb3-destructive-color); +} + +[data-disabled] + .label { + opacity: 0.5; + cursor: not-allowed; +} diff --git a/packages/@justweb3/ui/src/lib/ui/Label/index.tsx b/packages/@justweb3/ui/src/lib/ui/Label/index.tsx new file mode 100644 index 00000000..66d6dacc --- /dev/null +++ b/packages/@justweb3/ui/src/lib/ui/Label/index.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; +import * as LabelPrimitive from '@radix-ui/react-label'; +import styles from './Label.module.css'; + +const Label = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + required?: boolean; + } +>(({ className, required, ...props }, ref) => ( + +)); +Label.displayName = LabelPrimitive.Root.displayName; + +export { Label }; diff --git a/packages/@justweb3/ui/src/lib/ui/Sheet/Sheet.module.css b/packages/@justweb3/ui/src/lib/ui/Sheet/Sheet.module.css new file mode 100644 index 00000000..9b18b622 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/ui/Sheet/Sheet.module.css @@ -0,0 +1,284 @@ +.sheetOverlay { + position: fixed; + inset: 0; + z-index: 50; + background-color: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(4px); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +.sheetOverlay[data-state='open'] { + animation: overlayShow 500ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.sheetOverlay[data-state='closed'] { + animation: overlayHide 300ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.sheetContent { + position: fixed; + z-index: 50; + display: flex; + flex-direction: column; + padding: 3rem 1.5rem 1.5rem; + gap: 1rem; + box-sizing: border-box; + background-color: var(--justweb3-background-color); + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + transition-property: transform; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 500ms; +} + +.sheetContent[data-state='open'] { + animation: contentShow 500ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.sheetContent[data-state='closed'] { + animation: contentHide 300ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.sheetContent:focus { + outline: none; +} + +.sheetHeader { + display: flex; + flex-direction: column; + space-y: 2; + text-align: center; +} + +.sheetFooter { + display: flex; + flex-direction: column-reverse; +} + +.sheetTitle { + font-size: 1.125rem; + font-weight: 600; + line-height: 1.75rem; + color: var(--justweb3-foreground-color-2); + font-family: var(--justweb3-font-family); + position: absolute; + top: 0; + left: 24px; +} + +.sheetDescription { + font-size: 0.875rem; + line-height: 1.25rem; + color: var(--justweb3-foreground-color-2); + font-family: var(--justweb3-font-family); +} + +.sheetClose { + position: absolute; + right: 1rem; + top: 1rem; + opacity: 0.7; + transition: opacity 0.2s; + outline: none; + border: none; + background: none; + cursor: pointer; +} + +.sheetClose:hover { + opacity: 1; +} + +/* Side variations */ +.top { + inset: 0 0 auto 0; + border-bottom: 1px solid var(--justweb3-foreground-color-4); +} + +.top[data-state='open'] { + animation: slideInTop 500ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.top[data-state='closed'] { + animation: slideOutTop 300ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.right { + inset: 0 0 0 auto; + border-left: 1px solid var(--justweb3-foreground-color-4); +} + +.right[data-state='open'] { + animation: slideInRight 500ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.right[data-state='closed'] { + animation: slideOutRight 300ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.bottom { + inset: auto 0 0 0; + border-top: 1px solid var(--justweb3-foreground-color-4); +} + +.bottom[data-state='open'] { + animation: slideInBottom 500ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.bottom[data-state='closed'] { + animation: slideOutBottom 300ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.left { + inset: 0 auto 0 0; + border-right: 1px solid var(--justweb3-foreground-color-4); +} + +.left[data-state='open'] { + animation: slideInLeft 500ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.left[data-state='closed'] { + animation: slideOutLeft 300ms cubic-bezier(0.16, 1, 0.3, 1); +} + +@media (min-width: 768px) { + .sheetContent.top, + .sheetContent.bottom { + max-height: 100vh; + } + + .sheetContent.right, + .sheetContent.left { + max-width: 420px; + } + + .sheetHeader { + text-align: left; + } + + .sheetFooter { + flex-direction: row; + justify-content: flex-end; + } +} + +@media (max-width: 768px) { + .sheetContent { + max-width: 100vw; + width: 100vw; + border-radius: 0; + } +} + +/* Animations */ +@keyframes contentShow { + from { + opacity: 0; + transform: translate(-50%, -48%) scale(0.96); + } + to { + opacity: 1; + transform: translate(-50%, -50%) scale(1); + } +} + +@keyframes contentHide { + from { + opacity: 1; + transform: translate(-50%, -50%) scale(1); + } + to { + opacity: 0; + transform: translate(-50%, -48%) scale(0.96); + } +} + +@keyframes slideInTop { + from { + transform: translateY(-100%); + } + to { + transform: translateY(0); + } +} + +@keyframes slideOutTop { + from { + transform: translateY(0); + } + to { + transform: translateY(-100%); + } +} + +@keyframes slideInRight { + from { + transform: translateX(100%); + } + to { + transform: translateX(0); + } +} + +@keyframes slideOutRight { + from { + transform: translateX(0); + } + to { + transform: translateX(100%); + } +} + +@keyframes slideInBottom { + from { + transform: translateY(100%); + } + to { + transform: translateY(0); + } +} + +@keyframes slideOutBottom { + from { + transform: translateY(0); + } + to { + transform: translateY(100%); + } +} + +@keyframes slideInLeft { + from { + transform: translateX(-100%); + } + to { + transform: translateX(0); + } +} + +@keyframes slideOutLeft { + from { + transform: translateX(0); + } + to { + transform: translateX(-100%); + } +} + +@keyframes overlayShow { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes overlayHide { + from { + opacity: 1; + } + to { + opacity: 0; + } +} \ No newline at end of file diff --git a/packages/@justweb3/ui/src/lib/ui/Sheet/index.tsx b/packages/@justweb3/ui/src/lib/ui/Sheet/index.tsx new file mode 100644 index 00000000..b6f80792 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/ui/Sheet/index.tsx @@ -0,0 +1,128 @@ +'use client'; + +import * as React from 'react'; +import * as SheetPrimitive from '@radix-ui/react-dialog'; +import { cva, type VariantProps } from 'class-variance-authority'; +import styles from './Sheet.module.css'; +import { CloseIcon } from '../../icons'; + +const Sheet = SheetPrimitive.Root; + +const SheetTrigger = SheetPrimitive.Trigger; + +const SheetClose = SheetPrimitive.Close; + +const SheetPortal = SheetPrimitive.Portal; + +export interface SheetOverlayProps + extends React.ComponentPropsWithoutRef { + overlay?: boolean; +} + +const SheetOverlay = React.forwardRef< + React.ElementRef, + SheetOverlayProps +>(({ className, overlay = true, ...props }, ref) => ( + +)); +SheetOverlay.displayName = SheetPrimitive.Overlay.displayName; + +const sheetVariants = cva(styles.sheetContent, { + variants: { + side: { + top: styles.top, + right: styles.right, + bottom: styles.bottom, + left: styles.left, + }, + }, + defaultVariants: { + side: 'right', + }, +}); + +interface SheetContentProps + extends React.ComponentPropsWithoutRef, + VariantProps { + overlay?: boolean; +} + +const SheetContent = React.forwardRef< + React.ElementRef, + SheetContentProps +>(({ side = 'right', overlay = true, className, children, ...props }, ref) => ( + + + + {children} + + + + + +)); +SheetContent.displayName = SheetPrimitive.Content.displayName; + +const SheetHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +SheetHeader.displayName = 'SheetHeader'; + +const SheetFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +SheetFooter.displayName = 'SheetFooter'; + +const SheetTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +SheetTitle.displayName = SheetPrimitive.Title.displayName; + +const SheetDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +SheetDescription.displayName = SheetPrimitive.Description.displayName; + +export { + Sheet, + SheetPortal, + SheetOverlay, + SheetTrigger, + SheetClose, + SheetContent, + SheetHeader, + SheetFooter, + SheetTitle, + SheetDescription, +}; diff --git a/packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css b/packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css index ec4d632b..74cb32af 100644 --- a/packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css +++ b/packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css @@ -4,11 +4,13 @@ justify-content: center; border-radius: 0.375rem; margin-bottom: 10px; + gap: 10px; + display: flex; } /* Underlined variant */ .underlinedTabs .tabsTrigger { - margin-right: 10px; + /*margin-right: 10px;*/ transition: border-color 0.3s ease-in-out, color 0.3s ease-in-out; background-color: transparent; border: unset; @@ -18,6 +20,8 @@ font-weight: 900; line-height: 18px; font-family: var(--justweb3-font-family); + border-bottom: 2px solid transparent; + } .underlinedTabs .tabsTrigger[data-state='active'] { diff --git a/packages/@justweb3/ui/src/lib/ui/index.ts b/packages/@justweb3/ui/src/lib/ui/index.ts index 5be7fdc5..a47f5589 100644 --- a/packages/@justweb3/ui/src/lib/ui/index.ts +++ b/packages/@justweb3/ui/src/lib/ui/index.ts @@ -14,3 +14,6 @@ export * from './Separator'; export * from './Tabs'; export * from './Text'; export * from './ToolTip'; +export * from './Sheet'; +export * from './Label'; +export * from './Checkbox'; diff --git a/packages/@justweb3/ui/src/stories/ui/checkbox.stories.tsx b/packages/@justweb3/ui/src/stories/ui/checkbox.stories.tsx new file mode 100644 index 00000000..e2d53caf --- /dev/null +++ b/packages/@justweb3/ui/src/stories/ui/checkbox.stories.tsx @@ -0,0 +1,20 @@ +import { Meta, StoryObj } from '@storybook/react'; +import { Checkbox } from '../../lib/ui'; + +const meta: Meta = { + component: Checkbox, + title: 'Design System/UI/Checkbox', + tags: ['autodocs'], +}; +export default meta; +type Story = StoryObj; + +export const Normal: Story = { + args: {}, +}; + +export const Disabled: Story = { + args: { + disabled: true, + }, +}; diff --git a/packages/@justweb3/ui/src/stories/ui/label.stories.tsx b/packages/@justweb3/ui/src/stories/ui/label.stories.tsx new file mode 100644 index 00000000..a831e758 --- /dev/null +++ b/packages/@justweb3/ui/src/stories/ui/label.stories.tsx @@ -0,0 +1,32 @@ +import { StoryObj } from '@storybook/react'; +import { Checkbox, Label } from '../../lib/ui'; + +export const Example = () => { + return ( +
+
+ + +
+
+ ); +}; + +const meta = { + component: Example, + title: 'Design System/UI/Label', +}; + +export default meta; + +type Story = StoryObj; + +export const Primary: Story = { + args: {}, +}; diff --git a/packages/@justweb3/ui/src/stories/ui/sheet.stories.tsx b/packages/@justweb3/ui/src/stories/ui/sheet.stories.tsx new file mode 100644 index 00000000..4cbe9df5 --- /dev/null +++ b/packages/@justweb3/ui/src/stories/ui/sheet.stories.tsx @@ -0,0 +1,72 @@ +import { StoryObj } from '@storybook/react'; +import { + Button, + Input, + Label, + Sheet, + SheetClose, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, + SheetTrigger, +} from '../../lib/ui'; + +export const Example = () => { + return ( + + + + + + + Edit profile + + Make changes to your profile here. Click save when you're done. + + +
+
+ + +
+
+ + +
+
+ + + + + +
+
+ ); +}; + +const meta = { + component: Example, + title: 'Design System/UI/Sheet', +}; + +export default meta; + +type Story = StoryObj; + +export const Primary: Story = { + args: {}, +}; diff --git a/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx b/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx index 62081f55..ec4dce46 100644 --- a/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx @@ -181,19 +181,6 @@ export const JustWeb3Button: FC = ({ setMobileDialogOpen(true); } }} - // right={ - // - // {address && formatText(address, 4)} - // - // - // } /> ); }; @@ -303,9 +290,14 @@ export const JustWeb3Button: FC = ({ } return ( - +
{ + setMobileDialogOpen(false); + }} + > {component(createPluginApi(plugin.name))} - +
); })} diff --git a/packages/@justweb3/widget/src/lib/index.ts b/packages/@justweb3/widget/src/lib/index.ts index e51caa2c..5c15af85 100644 --- a/packages/@justweb3/widget/src/lib/index.ts +++ b/packages/@justweb3/widget/src/lib/index.ts @@ -6,11 +6,12 @@ import { ProfileSection } from './components/Profile/ProfileSection'; import { JustWeb3Button } from './components/JustWeb3Button'; import { MetadataCard } from './components/MetadataCard'; import { JustEnsCard } from './components/JustEnsCard'; +import { BasePopoverContent } from './components/DefaultPopover'; export * from './plugins'; export * from './providers'; export * from './hooks'; -export * from './icons' +export * from './icons'; export { JustaNameFooter, JustWeb3Button, @@ -19,4 +20,5 @@ export { DefaultDialog as JustaNameDialog, LoadingDialog as JustaNameLoadingDialog, ProfileSection, + BasePopoverContent as JustaNamePopoverContent, }; diff --git a/packages/@justweb3/xmtp-plugin/.babelrc b/packages/@justweb3/xmtp-plugin/.babelrc new file mode 100644 index 00000000..1ea870ea --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/packages/@justweb3/xmtp-plugin/.env.example b/packages/@justweb3/xmtp-plugin/.env.example new file mode 100644 index 00000000..b65ab5ba --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/.env.example @@ -0,0 +1,6 @@ +STORYBOOK_APP_BACKEND_URL=http://localhost:3333 +STORYBOOK_APP_ORIGIN=http://localhost:3000 +STORYBOOK_APP_DOMAIN=localhost +STORYBOOK_APP_MAINNET_PROVIDER_URL= +STORYBOOK_APP_SEPOLIA_PROVIDER_URL= +STORYBOOK_APP_PRIVY_APP_ID= \ No newline at end of file diff --git a/packages/@justweb3/xmtp-plugin/.eslintrc.json b/packages/@justweb3/xmtp-plugin/.eslintrc.json new file mode 100644 index 00000000..324c11cb --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/.eslintrc.json @@ -0,0 +1,40 @@ +{ + "extends": ["plugin:@nx/react", "../../../.eslintrc.base.json"], + "ignorePatterns": ["!**/*", "dist", "src/test"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": { + "@typescript-eslint/ban-types": ["warn"], + "@typescript-eslint/no-empty-function": ["warn"], + "@typescript-eslint/no-empty-interface": ["warn"] + } + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/rollup.config.{js,ts,mjs,mts,cjs}", "{projectRoot}/src/stories/**/*", "{projectRoot}/.storybook/**/*"], + "ignoredDependencies": [ + "@justaname.id/siwens", + "@justaname.id/sdk", + "@justaname.id/react", + "@justweb3/ui" + ] + } + ] + } + } + ] +} diff --git a/packages/@justweb3/xmtp-plugin/.gitignore b/packages/@justweb3/xmtp-plugin/.gitignore new file mode 100644 index 00000000..4c49bd78 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/.gitignore @@ -0,0 +1 @@ +.env diff --git a/packages/@justweb3/xmtp-plugin/.storybook/main.ts b/packages/@justweb3/xmtp-plugin/.storybook/main.ts new file mode 100644 index 00000000..3e575653 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/.storybook/main.ts @@ -0,0 +1,36 @@ +import type { StorybookConfig } from '@storybook/react-vite'; +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; +import { mergeConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +const config: StorybookConfig = { + stories: ['../src/stories/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'], + addons: ['@storybook/addon-essentials', '@storybook/addon-interactions'], + framework: { + name: '@storybook/react-vite', + options: {}, + }, + + viteFinal: async (config) => + mergeConfig(config, { + plugins: [react(), nxViteTsPaths()], + define: { + 'process.env': process.env, + }, + optimizeDeps: { + exclude: ['@xmtp/user-preferences-bindings-wasm'], + }, + }), + typescript: { + reactDocgen: 'react-docgen-typescript', + reactDocgenTypescriptOptions: { + include: ['src/**/*.{ts,tsx}'], + }, + }, +}; + +export default config; + +// To customize your Vite configuration you can use the viteFinal field. +// Check https://storybook.js.org/docs/react/builders/vite#configuration +// and https://nx.dev/recipes/storybook/custom-builder-configs diff --git a/packages/@justweb3/xmtp-plugin/.storybook/polyfills.ts b/packages/@justweb3/xmtp-plugin/.storybook/polyfills.ts new file mode 100644 index 00000000..38b13be9 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/.storybook/polyfills.ts @@ -0,0 +1,4 @@ +import { Buffer } from 'buffer'; + +window.Buffer = window.Buffer ?? Buffer; +window.global = window.global ?? window; diff --git a/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx b/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx new file mode 100644 index 00000000..940554e4 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx @@ -0,0 +1,3 @@ +import './polyfills'; + +export const decorators = [(Story) => ]; diff --git a/packages/@justweb3/xmtp-plugin/.svgrrc.js b/packages/@justweb3/xmtp-plugin/.svgrrc.js new file mode 100644 index 00000000..1bf9583a --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/.svgrrc.js @@ -0,0 +1,6 @@ +module.exports ={ + "typescript": true, + "template": require("./src/template/template.js"), + "dimensions": false, + "svgo": true +} diff --git a/packages/@justweb3/xmtp-plugin/CHANGELOG.md b/packages/@justweb3/xmtp-plugin/CHANGELOG.md new file mode 100644 index 00000000..95d762ea --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/CHANGELOG.md @@ -0,0 +1,675 @@ +## 0.1.32 (2024-11-04) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.136 +- Updated @justweb3/ui to 0.0.72 +- Updated @justweb3/widget to 0.0.72 + +## 0.1.31 (2024-11-04) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.135 +- Updated @justweb3/ui to 0.0.71 +- Updated @justweb3/widget to 0.0.71 + +## 0.1.30 (2024-11-04) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.134 +- Updated @justweb3/ui to 0.0.70 +- Updated @justweb3/widget to 0.0.70 + +## 0.1.29 (2024-11-04) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.133 +- Updated @justweb3/ui to 0.0.69 +- Updated @justweb3/widget to 0.0.69 + +## 0.1.28 (2024-11-04) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.132 +- Updated @justweb3/ui to 0.0.68 +- Updated @justweb3/widget to 0.0.68 + +## 0.1.27 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.131 +- Updated @justweb3/ui to 0.0.67 +- Updated @justweb3/widget to 0.0.67 + +## 0.1.26 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.130 +- Updated @justweb3/ui to 0.0.66 +- Updated @justweb3/widget to 0.0.66 + +## 0.1.25 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.129 +- Updated @justweb3/ui to 0.0.65 +- Updated @justweb3/widget to 0.0.65 + +## 0.1.24 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.128 +- Updated @justweb3/ui to 0.0.64 +- Updated @justweb3/widget to 0.0.64 + +## 0.1.23 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.127 +- Updated @justweb3/ui to 0.0.63 +- Updated @justweb3/widget to 0.0.63 + +## 0.1.22 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.126 +- Updated @justweb3/ui to 0.0.62 +- Updated @justweb3/widget to 0.0.62 + +## 0.1.21 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.125 +- Updated @justweb3/ui to 0.0.61 +- Updated @justweb3/widget to 0.0.61 + +## 0.1.20 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.124 +- Updated @justweb3/ui to 0.0.60 +- Updated @justweb3/widget to 0.0.60 + +## 0.1.19 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.123 +- Updated @justweb3/ui to 0.0.59 +- Updated @justweb3/widget to 0.0.59 + +## 0.1.18 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.122 +- Updated @justweb3/ui to 0.0.58 +- Updated @justweb3/widget to 0.0.58 + +## 0.1.17 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.121 +- Updated @justweb3/ui to 0.0.57 +- Updated @justweb3/widget to 0.0.57 + +## 0.1.16 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.120 +- Updated @justweb3/ui to 0.0.56 +- Updated @justweb3/widget to 0.0.56 + +## 0.1.15 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.119 +- Updated @justweb3/ui to 0.0.55 +- Updated @justweb3/widget to 0.0.55 + +## 0.1.14 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.118 +- Updated @justweb3/ui to 0.0.54 +- Updated @justweb3/widget to 0.0.54 + +## 0.1.13 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.117 +- Updated @justweb3/ui to 0.0.53 +- Updated @justweb3/widget to 0.0.53 + +## 0.1.12 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.116 +- Updated @justweb3/ui to 0.0.52 +- Updated @justweb3/widget to 0.0.52 + +## 0.1.11 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.115 +- Updated @justweb3/ui to 0.0.51 +- Updated @justweb3/widget to 0.0.51 + +## 0.1.10 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.114 +- Updated @justweb3/ui to 0.0.50 +- Updated @justweb3/widget to 0.0.50 + +## 0.1.9 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.113 +- Updated @justweb3/ui to 0.0.49 +- Updated @justweb3/widget to 0.0.49 + +## 0.1.8 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.112 +- Updated @justweb3/ui to 0.0.48 +- Updated @justweb3/widget to 0.0.48 + +## 0.1.7 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.111 +- Updated @justweb3/ui to 0.0.47 +- Updated @justweb3/widget to 0.0.47 + +## 0.1.6 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.110 +- Updated @justweb3/ui to 0.0.46 +- Updated @justweb3/widget to 0.0.46 + +## 0.1.5 (2024-10-31) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/react to 0.3.109 +- Updated @justweb3/ui to 0.0.45 +- Updated @justweb3/widget to 0.0.45 + +## 0.1.4 (2024-10-30) + +This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. + +## 0.1.3 (2024-10-30) + +This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. + +## 0.1.2 (2024-10-30) + +This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. + +## 0.1.1 (2024-10-30) + +This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. + +## 0.1.0 (2024-10-30) + + +### 🚀 Features + +- remove mapps from justverified ([2898c52](https://github.com/JustaName-id/JustaName-sdk/commit/2898c52)) + +- efp ([36fcc15](https://github.com/JustaName-id/JustaName-sdk/commit/36fcc15)) + +- efp and storybook for react sdk ([f0c5c7a](https://github.com/JustaName-id/JustaName-sdk/commit/f0c5c7a)) + + +### ❤️ Thank You + +- HadiKhai + +## 0.0.38 (2024-10-21) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.100 +- Updated @justaname.id/react to 0.3.103 +- Updated @justweb3/ui to 0.0.39 +- Updated @justweb3/widget to 0.0.39 + +## 0.0.37 (2024-10-21) + + +### 🚀 Features + +- justverified fixes and double vc signature due to rerending fixed ([57965f5](https://github.com/JustaName-id/JustaName-sdk/commit/57965f5)) + +- update functionality ([69c4761](https://github.com/JustaName-id/JustaName-sdk/commit/69c4761)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.99 +- Updated @justaname.id/react to 0.3.102 +- Updated @justweb3/ui to 0.0.38 +- Updated @justweb3/widget to 0.0.38 + + +### ❤️ Thank You + +- HadiKhai + +## 0.0.36 (2024-10-14) + + +### 🧱 Updated Dependencies + +- Updated @justweb3/ui to 0.0.37 +- Updated @justweb3/widget to 0.0.37 + +## 0.0.35 (2024-10-14) + + +### 🧱 Updated Dependencies + +- Updated @justweb3/ui to 0.0.36 +- Updated @justweb3/widget to 0.0.36 + +## 0.0.34 (2024-10-14) + + +### 🧱 Updated Dependencies + +- Updated @justweb3/ui to 0.0.35 +- Updated @justweb3/widget to 0.0.35 + +## 0.0.33 (2024-10-14) + + +### 🧱 Updated Dependencies + +- Updated @justweb3/ui to 0.0.34 +- Updated @justweb3/widget to 0.0.34 + +## 0.0.32 (2024-10-14) + + +### 🧱 Updated Dependencies + +- Updated @justweb3/ui to 0.0.33 +- Updated @justweb3/widget to 0.0.33 + +## 0.0.31 (2024-10-14) + + +### 🧱 Updated Dependencies + +- Updated @justweb3/ui to 0.0.32 +- Updated @justweb3/widget to 0.0.32 + +## 0.0.30 (2024-10-14) + + +### 🧱 Updated Dependencies + +- Updated @justweb3/ui to 0.0.31 +- Updated @justweb3/widget to 0.0.31 + +## 0.0.29 (2024-10-14) + + +### 🧱 Updated Dependencies + +- Updated @justweb3/ui to 0.0.30 +- Updated @justweb3/widget to 0.0.30 + +## 0.0.28 (2024-10-14) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.98 +- Updated @justaname.id/react to 0.3.101 +- Updated @justweb3/ui to 0.0.29 +- Updated @justweb3/widget to 0.0.29 + +## 0.0.27 (2024-09-22) + + +### 🚀 Features + +- isCanOpenMAppDialogPending ([#32](https://github.com/JustaName-id/JustaName-sdk/pull/32)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.91 +- Updated @justaname.id/react to 0.3.94 + + +### ❤️ Thank You + +- JustHadi @HadiKhai + +## 0.0.26 (2024-09-22) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.90 +- Updated @justaname.id/react to 0.3.93 + +## 0.0.25 (2024-09-22) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.89 +- Updated @justaname.id/react to 0.3.92 + +## 0.0.24 (2024-09-21) + + +### 🚀 Features + +- expose usemapp in the package ([#29](https://github.com/JustaName-id/JustaName-sdk/pull/29)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.88 +- Updated @justaname.id/react to 0.3.91 + + +### ❤️ Thank You + +- JustHadi @HadiKhai + +## 0.0.23 (2024-09-21) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.87 +- Updated @justaname.id/react to 0.3.90 + +## 0.0.22 (2024-09-21) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.86 +- Updated @justaname.id/react to 0.3.89 + +## 0.0.21 (2024-09-20) + + +### 🚀 Features + +- mApp in sdk react and react-signin ([#26](https://github.com/JustaName-id/JustaName-sdk/pull/26)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.85 +- Updated @justaname.id/react to 0.3.88 + + +### ❤️ Thank You + +- JustHadi @HadiKhai + +## 0.0.20 (2024-09-20) + + +### 🩹 Fixes + +- **react-signin:** design subnames ([b384537](https://github.com/JustaName-id/JustaName-sdk/commit/b384537)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.84 +- Updated @justaname.id/react to 0.3.87 + + +### ❤️ Thank You + +- anthony2399 @anthony23991 + +## 0.0.19 (2024-09-19) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.83 +- Updated @justaname.id/react to 0.3.86 + +## 0.0.18 (2024-09-19) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.82 +- Updated @justaname.id/react to 0.3.85 + +## 0.0.17 (2024-09-19) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.81 +- Updated @justaname.id/react to 0.3.84 + +## 0.0.16 (2024-09-18) + + +### 🚀 Features + +- siwens and ebdc ([87677f3](https://github.com/JustaName-id/JustaName-sdk/commit/87677f3)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.80 +- Updated @justaname.id/react to 0.3.83 + + +### ❤️ Thank You + +- HadiKhai + +## 0.0.15 (2024-09-18) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.79 +- Updated @justaname.id/react to 0.3.82 + +## 0.0.14 (2024-09-16) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.78 +- Updated @justaname.id/react to 0.3.81 + +## 0.0.13 (2024-09-16) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.77 +- Updated @justaname.id/react to 0.3.80 + +## 0.0.12 (2024-09-15) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.76 +- Updated @justaname.id/react to 0.3.79 + +## 0.0.11 (2024-09-15) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.75 +- Updated @justaname.id/react to 0.3.78 + +## 0.0.10 (2024-09-15) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.74 +- Updated @justaname.id/react to 0.3.77 + +## 0.0.9 (2024-09-15) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.73 +- Updated @justaname.id/react to 0.3.76 + +## 0.0.8 (2024-09-15) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.72 +- Updated @justaname.id/react to 0.3.75 + +## 0.0.7 (2024-09-14) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.71 +- Updated @justaname.id/react to 0.3.74 + +## 0.0.6 (2024-09-14) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.70 +- Updated @justaname.id/react to 0.3.73 + +## 0.0.5 (2024-09-14) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.69 +- Updated @justaname.id/react to 0.3.72 + +## 0.0.4 (2024-09-14) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.68 +- Updated @justaname.id/react to 0.3.71 + +## 0.0.3 (2024-09-14) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.67 +- Updated @justaname.id/react to 0.3.70 + +## 0.0.2 (2024-09-14) + + +### 🚀 Features + +- published react-signin and react-ui ([1d90025](https://github.com/JustaName-id/JustaName-sdk/commit/1d90025)) + +- added git repository for new packages ([e40c722](https://github.com/JustaName-id/JustaName-sdk/commit/e40c722)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.66 +- Updated @justaname.id/react to 0.3.69 + + +### ❤️ Thank You + +- anthony2399 @anthony23991 + +## 0.0.1 (2024-09-13) + + +### 🚀 Features + +- signin widget and privy example ([3f9bc14](https://github.com/JustaName-id/JustaName-sdk/commit/3f9bc14)) + +- update loading flags in hooks naming convention ([70f70a4](https://github.com/JustaName-id/JustaName-sdk/commit/70f70a4)) + +- update subname ([12755c4](https://github.com/JustaName-id/JustaName-sdk/commit/12755c4)) + + +### ❤️ Thank You + +- HadiKhai \ No newline at end of file diff --git a/packages/@justweb3/xmtp-plugin/README.md b/packages/@justweb3/xmtp-plugin/README.md new file mode 100644 index 00000000..261859ff --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/README.md @@ -0,0 +1,58 @@ +# @justweb3/xmtp-plugin + +The **@justweb3/xmtp-plugin** extends the **JustWeb3 Widget** with **Builder Score (Talent Protocol)** functionalities, allowing users to **view Talent Protocol Credentials and Builder Score** directly within your dApp. + +--- + +## Installation + +Install the **Talent Protocol Plugin** using your preferred package manager: + +```bash +bash +npm install @justweb3/xmtp-plugin + +# or + +yarn add @justweb3/xmtp-plugin +``` + +--- + +## Usage Example + +Here’s how to enable the **Talent Protocol Plugin** in your **JustWeb3 Widget** configuration: + +```tsx +import { TalentProtocolPlugin } from '@justweb3/xmtp-plugin'; + +const justweb3Config = { + config: { + origin: 'http://localhost:3000/', + domain: 'localhost', + signInTtl: 86400000, + }, + plugins: [ + TalentProtocolPlugin({ + apiKey: "", // # Optional: Calls the Talent Protocol API from the client side + backendUrl: "", // # Optional: Calls the Talent Protocol API from the backend, best for production + }) + ], + ensDomains: [ + { + ensDomain: 'yourdomain.eth', + apiKey: 'YOUR_API_KEY', + chainId: 1, + }, + ], + color: { + primary: '#FEA801', + background: 'hsl(0, 0%, 100%)', + destructive: 'hsl(0, 100%, 50%)', + }, +}; +``` + +### Contributing + +Contributions are welcome! If you have suggestions or find issues, please open an issue or submit a pull request on the GitHub repository. diff --git a/packages/@justweb3/xmtp-plugin/env.d.ts b/packages/@justweb3/xmtp-plugin/env.d.ts new file mode 100644 index 00000000..6ae21f5d --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/env.d.ts @@ -0,0 +1,15 @@ +/// + +interface ImportMetaEnv { + STORYBOOK_APP_CHAIN_ID: string; + STORYBOOK_APP_ORIGIN: string; + STORYBOOK_APP_DOMAIN: string; + STORYBOOK_APP_BACKEND_URL: string; + STORYBOOK_APP_PROVIDER_URL: string; + STORYBOOK_APP_ENS_DOMAIN: string; + STORYBOOK_APP_ENV: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/packages/@justweb3/xmtp-plugin/jest.config.ts b/packages/@justweb3/xmtp-plugin/jest.config.ts new file mode 100644 index 00000000..7c44f4d5 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/jest.config.ts @@ -0,0 +1,12 @@ +/* eslint-disable */ +export default { + displayName: '@justweb3/xmtp-plugin', + preset: '../../../jest.preset.js', + transform: { + '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest', + '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/react/babel'] }], + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], + coverageDirectory: '../../../coverage/packages/@justweb3/xmtp-plugin', + passWithNoTests: true, +}; diff --git a/packages/@justweb3/xmtp-plugin/package.json b/packages/@justweb3/xmtp-plugin/package.json new file mode 100644 index 00000000..35af25b3 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/package.json @@ -0,0 +1,26 @@ +{ + "name": "@justweb3/xmtp-plugin", + "version": "0.0.1", + "dependencies": { + "@xmtp/react-sdk": "^9.0.0" + }, + "peerDependencies": { + "@justweb3/widget": ">=0.0.0", + "react": ">=17", + "wagmi": "2.x" + }, + "exports": { + "./package.json": "./dist/package.json", + ".": "./dist/index.esm.js" + }, + "publishConfig": { + "access": "public" + }, + "module": "./dist/index.esm.js", + "main": "./dist/index.esm.js", + "types": "./dist/index.esm.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/JustaName-id/JustaName-sdk" + } +} diff --git a/packages/@justweb3/xmtp-plugin/project.json b/packages/@justweb3/xmtp-plugin/project.json new file mode 100644 index 00000000..d235f090 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/project.json @@ -0,0 +1,131 @@ +{ + "name": "@justweb3/xmtp-plugin", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/@justweb3/xmtp-plugin/src", + "projectType": "library", + "tags": [], + "targets": { + "storybook": { + "executor": "@nx/storybook:storybook", + "options": { + "port": 4407, + "configDir": "packages/@justweb3/xmtp-plugin/.storybook" + }, + "configurations": { + "ci": { + "quiet": true + } + } + }, + "typedoc": { + "executor": "nx:run-commands", + "options": { + "commands": [ + { + "command": "typedoc" + } + ], + "cwd": "packages/@justweb3/xmtp-plugin", + "parallel": false + } + }, + "build": { + "executor": "nx:run-commands", + "options": { + "commands": [ + { + "command": "nx buildProject @justweb3/xmtp-plugin" + }, + { + "command": "node update-package-json.js" + }, + { + "command": "rm -rf node_modules || rmdir /s /q node_modules" + } + ], + "cwd": "packages/@justweb3/xmtp-plugin", + "parallel": false + } + }, + "buildProject": { + "executor": "@nx/rollup:rollup", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "production", + "options": { + "outputPath": "packages/@justweb3/xmtp-plugin/dist", + "tsConfig": "packages/@justweb3/xmtp-plugin/tsconfig.lib.json", + "project": "packages/@justweb3/xmtp-plugin/package.json", + "entryFile": "packages/@justweb3/xmtp-plugin/src/index.ts", + "external": [ + "react", + "react-dom", + "react/jsx-runtime", + "@justaname.id/react", + "@justweb3/ui", + "@justaname.id/sdk", + "@justweb3/widget" + ], + "rollupConfig": "packages/@justweb3/xmtp-plugin/rollup.config.cjs", + "generateExportsField": true, + "compiler": "swc", + "format": ["esm"], + "assets": [ + { + "glob": "packages/@justweb3/xmtp-plugin/README.md", + "input": ".", + "output": "." + } + ] + }, + "configurations": { + "production": { + "optimization": true, + "sourceMap": false, + "namedChunks": false, + "extractLicenses": true, + "vendorChunk": false + } + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"], + "options": { + "fix": true, + "lintFilePatterns": [ + "packages/@justweb3/xmtp-plugin/**/*.{ts,tsx,js,jsx}", + "packages/@justweb3/xmtp-plugin/package.json" + ] + } + }, + "publish": { + "command": "node tools/scripts/publish.mjs @justweb3/xmtp-plugin {args.ver} {args.tag}", + "dependsOn": ["build"] + }, + "nx-release-publish": { + "options": { + "packageRoot": "packages/@justweb3/xmtp-plugin/dist" + }, + "dependsOn": ["^build", "build", "^@justaname.id/react:build"] + }, + "release:package": { + "executor": "nx:run-commands", + "options": { + "command": "npx semantic-release --debug --extends=./packages/@justweb3/xmtp-plugin/release.config.js" + } + }, + "update-deps": { + "executor": "nx:run-commands", + "options": { + "command": "npx rjp ./packages/@justweb3/xmtp-plugin/dist/package.json $PACKAGE_NAME $VERSION" + } + }, + "transform:linux": { + "executor": "nx:run-commands", + "options": { + "cwd": "packages/@justweb3/xmtp-plugin", + "command": "rm -rf src/lib/icons/components && mkdir src/lib/icons/components && npx @svgr/cli --out-dir src/lib/icons/components --config-file .svgrrc.js --index-template=src/template/linux/index-template.js -- src/lib/icons/svgs " + } + } + } +} diff --git a/packages/@justweb3/xmtp-plugin/release.config.js b/packages/@justweb3/xmtp-plugin/release.config.js new file mode 100644 index 00000000..cfcf0470 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/release.config.js @@ -0,0 +1,46 @@ +const libName = 'react-signin'; +const artifactName = 'justaname-react-signin'; +const libPath = `packages/@justaname.id/${libName}`; +const importPath = `@justaname.id/${libName}`; + +module.exports = { + name: libName, + pkgRoot: `${libPath}/dist`, + branches: [ + '+([0-9])?(.{+([0-9]),x}).x', + ' main', + 'next', + 'next-major', + { name: 'beta', prerelease: true }, + { name: 'alpha', prerelease: true }, + ], + tagFormat: artifactName + '-v${version}', + commitPaths: [`${libPath}/*`], + assets: [`${libPath}/README.md`, `${libPath}/CHANGELOG.md`], + plugins: [ + '@semantic-release/commit-analyzer', + '@semantic-release/release-notes-generator', + [ + '@semantic-release/changelog', + { + changelogFile: `${libPath}/CHANGELOG.md`, + }, + ], + '@semantic-release/npm', + [ + '@semantic-release/exec', + { + prepareCmd: ` PACKAGE_NAME=${importPath} VERSION=\${nextRelease.version} npm run update-deps && VERSION=\${nextRelease.version} npm run bump-version:${libName}`, + }, + ], + [ + '@semantic-release/git', + { + assets: [`${libPath}/CHANGELOG.md`], + message: + `chore(release): ${libName}` + + '-v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}', + }, + ], + ], +}; diff --git a/packages/@justweb3/xmtp-plugin/rollup.config.cjs b/packages/@justweb3/xmtp-plugin/rollup.config.cjs new file mode 100644 index 00000000..f32d0249 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/rollup.config.cjs @@ -0,0 +1,22 @@ +const nrwlConfig = require('@nrwl/react/plugins/bundle-rollup'); +const svgr = require('@svgr/rollup').default; +const preserveDirectives = require('rollup-preserve-directives').default; +const nodeResolve = require('@rollup/plugin-node-resolve').default; +const commonjs = require('@rollup/plugin-commonjs'); +const path = require('path'); + +module.exports = (config) => { + const nxConfig = nrwlConfig(config); + return { + ...nxConfig, + plugins: [ + ...nxConfig.plugins, + nodeResolve({ + preferBuiltins: false, + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }), + commonjs(), + preserveDirectives(), + ], + }; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/index.ts b/packages/@justweb3/xmtp-plugin/src/index.ts new file mode 100644 index 00000000..f41a696f --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/index.ts @@ -0,0 +1 @@ +export * from './lib'; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx new file mode 100644 index 00000000..883b7ca9 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx @@ -0,0 +1,53 @@ +import { ArrowIcon, ClickableItem } from '@justweb3/ui'; +import { useClient } from '@xmtp/react-sdk'; +import { useWalletClient } from 'wagmi'; + +export interface ChatButtonProps { + handleOpen: (open: boolean) => void; +} +export const ChatButton: React.FC = ({ handleOpen }) => { + const { initialize } = useClient(); + const { client } = useClient(); + const { data: walletClient } = useWalletClient(); + + const handleChat = async () => { + if (!client) { + initialize({ + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + signer: walletClient, + options: { + env: 'dev', + }, + }).then(() => { + handleOpen(true); + }); + } else { + handleOpen(true); + } + }; + return ( + + + + } + style={{ + width: '100%', + }} + onClick={handleChat} + right={} + /> + ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx new file mode 100644 index 00000000..9fc74f8d --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx @@ -0,0 +1,17 @@ +import { CachedConversation, ContentTypeMetadata } from '@xmtp/react-sdk'; +import { Flex } from '@justweb3/ui'; +import { MessageItem } from '../MessageItem'; + +export interface ChatListProps { + conversations: CachedConversation[]; +} + +export const ChatList: React.FC = ({ conversations }) => { + return ( + + {conversations.map((conversation) => ( + + ))} + + ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx new file mode 100644 index 00000000..95b4ccd8 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx @@ -0,0 +1,117 @@ +import { + Sheet, + SheetContent, + SheetTitle, + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from '@justweb3/ui'; +import React, { useEffect, useMemo } from 'react'; +import { + useConsent, + useConversations, + useStreamConversations, +} from '@xmtp/react-sdk'; +import { ChatList } from '../ChatList'; + +export interface ChatSheetProps { + open?: boolean; + handleOpen?: (open: boolean) => void; +} + +export const ChatSheet: React.FC = ({ open, handleOpen }) => { + const [tab, setTab] = React.useState('Chats'); + const { conversations, isLoading } = useConversations(); + const [isConsentListLoading, setIsConsentListLoading] = React.useState(true); + const { loadConsentList, entries } = useConsent(); + + const allowedConversations = useMemo(() => { + return conversations.filter( + (convo) => + entries && + entries[convo.peerAddress] && + entries[convo.peerAddress]?.permissionType === 'allowed' + ); + }, [conversations, entries]); + + const blockedConversations = useMemo(() => { + return conversations.filter( + (convo) => + entries && + entries[convo.peerAddress] && + entries[convo.peerAddress]?.permissionType === 'denied' + ); + }, [conversations, entries]); + + const requestConversations = useMemo(() => { + return conversations.filter((convo) => { + if (!entries[convo.peerAddress]) return true; + return entries[convo.peerAddress]?.permissionType === 'unknown'; + }); + }, [conversations, entries]); + + useEffect(() => { + loadConsentList().then(() => { + setIsConsentListLoading(false); + }); + }, [loadConsentList]); + + useStreamConversations(); + + return ( + + + Chats + setTab(value)} + style={{ + display: 'flex', + flexDirection: 'column', + marginBottom: '0px', + overflow: 'hidden', + flex: '1', + }} + > + + + Chats + + + Requests + + + Blocked + + + {isLoading || isConsentListLoading ? ( +
Loading...
+ ) : ( + <> + + + + + + + + + + + )} +
+
+
+ ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx new file mode 100644 index 00000000..71fd7388 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx @@ -0,0 +1,88 @@ +import { + attachmentContentTypeConfig, + CachedConversation, + ContentTypeMetadata, + reactionContentTypeConfig, + replyContentTypeConfig, + useLastMessage, +} from '@xmtp/react-sdk'; +import { useEnsAvatar, usePrimaryName, useRecords } from '@justaname.id/react'; +import { Avatar, Flex, formatText, P, SPAN } from '@justweb3/ui'; +import React, { useMemo } from 'react'; + +export interface MessageItemProps { + conversation: CachedConversation; +} + +export const MessageItem: React.FC = ({ conversation }) => { + const lastMessage = useLastMessage(conversation.topic); + const { primaryName } = usePrimaryName({ + address: conversation.peerAddress as `0x${string}`, + }); + const { records } = useRecords({ + ens: primaryName, + }); + const { sanitizeEnsImage } = useEnsAvatar(); + + const lastContent = useMemo(() => { + if (!lastMessage) return ''; + + if (typeof lastMessage.content === 'string') { + return lastMessage.content; + } + + if ( + attachmentContentTypeConfig.contentTypes.includes( + lastMessage?.contentType + ) + ) { + return lastMessage.content.filename; + } + + if ( + reactionContentTypeConfig.contentTypes.includes(lastMessage?.contentType) + ) { + return lastMessage.contentFallback; + } + + if ( + replyContentTypeConfig.contentTypes.includes(lastMessage?.contentType) + ) { + return lastMessage.contentFallback; + } + + return lastMessage.contentFallback; + }, [lastMessage]); + + return ( + + + + +

+ {primaryName || formatText(conversation.peerAddress, 4)} +

+ + {lastContent || 'No preview available'} + +
+
+ ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/index.ts new file mode 100644 index 00000000..460ab6b5 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/index.ts @@ -0,0 +1 @@ +export * from './plugins'; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx new file mode 100644 index 00000000..5f0d27c9 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx @@ -0,0 +1,26 @@ +import { JustaPlugin } from '@justweb3/widget'; +import { JustWeb3XMTPProvider } from '../providers/JustWeb3XMTPProvider'; +import { ChatButton } from '../components/ChatButton'; + +export const XMTPPlugin: JustaPlugin = { + name: 'XMTPPlugin', + components: { + Provider: (pluginApi, children) => { + return ( + pluginApi.setState('xmtpOpen', open)} + > + {children} + + ); + }, + SignInMenu: (pluginApi) => { + return ( + pluginApi.setState('xmtpOpen', open)} + /> + ); + }, + }, +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx new file mode 100644 index 00000000..a32f800e --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx @@ -0,0 +1,71 @@ +import React, { useEffect } from 'react'; +import { + attachmentContentTypeConfig, + reactionContentTypeConfig, + replyContentTypeConfig, + useClient, + XMTPProvider, +} from '@xmtp/react-sdk'; +import { useJustWeb3 } from '@justweb3/widget'; +import { ChatSheet } from '../../components/ChatSheet'; + +const contentTypeConfigs = [ + attachmentContentTypeConfig, + reactionContentTypeConfig, + replyContentTypeConfig, +]; + +interface JustWeb3XMTPContextProps {} + +const JustWeb3XMTPContext = React.createContext< + JustWeb3XMTPContextProps | undefined +>(undefined); + +export interface JustWeb3XMTPProviderProps { + children: React.ReactNode; + open?: boolean; + handleOpen?: (open: boolean) => void; +} + +export const JustWeb3XMTPProvider: React.FC = ({ + children, + open, + handleOpen, +}) => { + const [isXmtpEnabled, setIsXmtpEnabled] = React.useState(false); + const handleXmtpEnabled = (enabled: boolean) => { + setIsXmtpEnabled(enabled); + }; + + return ( + + + + {isXmtpEnabled && } + {children} + + + ); +}; + +interface ChecksProps { + open?: boolean; + handleXmtpEnabled: (enabled: boolean) => void; +} + +export const Checks: React.FC = ({ open, handleXmtpEnabled }) => { + const { connectedEns } = useJustWeb3(); + const { disconnect, client } = useClient(); + + useEffect(() => { + handleXmtpEnabled(!!client); + }, [client, handleXmtpEnabled]); + + useEffect(() => { + if (!connectedEns?.ens) { + disconnect(); + } + }, [connectedEns?.ens, disconnect]); + + return null; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx new file mode 100644 index 00000000..42b6fef5 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx @@ -0,0 +1,128 @@ +import { + JustWeb3Button, + JustWeb3Provider, + JustWeb3ProviderConfig, +} from '@justweb3/widget'; +import '@justweb3/widget/styles.css'; +import { + ConnectButton, + getDefaultConfig, + RainbowKitProvider, +} from '@rainbow-me/rainbowkit'; +import '@rainbow-me/rainbowkit/styles.css'; +import { Meta, StoryObj } from '@storybook/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { WagmiProvider } from 'wagmi'; +import { mainnet, sepolia } from 'wagmi/chains'; +import { XMTPPlugin } from '../lib'; +import { ChainId } from '@justaname.id/sdk'; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; + +const queryClient = new QueryClient(); + +const JustWeb3Config: JustWeb3ProviderConfig = { + config: { + origin: import.meta.env.STORYBOOK_APP_ORIGIN, + domain: import.meta.env.STORYBOOK_APP_DOMAIN, + signInTtl: 1000 * 60 * 60 * 24, + }, + backendUrl: import.meta.env.STORYBOOK_APP_BACKEND_URL, + networks: [ + { + chainId: 1, + providerUrl: import.meta.env.STORYBOOK_APP_MAINNET_PROVIDER_URL, + }, + { + chainId: 11155111, + providerUrl: import.meta.env.STORYBOOK_APP_SEPOLIA_PROVIDER_URL, + }, + ], + ensDomains: [ + { + ensDomain: import.meta.env.STORYBOOK_APP_ENS_DOMAIN, + chainId: parseInt(import.meta.env.STORYBOOK_APP_CHAIN_ID) as ChainId, + }, + ], + openOnWalletConnect: false, + allowedEns: 'all', + dev: import.meta.env.STORYBOOK_APP_DEV === 'true', + plugins: [XMTPPlugin], + // color: { + // primary: '#FF00FF', + // background: '#000000', + // }, +}; + +export const Example = () => { + const config = getDefaultConfig({ + appName: 'My RainbowKit App', + projectId: 'YOUR_PROJECT_ID', + chains: [mainnet, sepolia], + }); + + return ( + + + + +

JustWeb3 Sign In

+ +
+
+ + + +
+ + {/*
*/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/*
*/} + {/*
*/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/*
*/} +
+
+
+ +
+
+ ); +}; + +const meta: Meta = { + component: Example, + title: 'Connect/XMTP', +}; +export default meta; +type Story = StoryObj; diff --git a/packages/@justweb3/xmtp-plugin/tsconfig.json b/packages/@justweb3/xmtp-plugin/tsconfig.json new file mode 100644 index 00000000..759148c7 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/tsconfig.json @@ -0,0 +1,33 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "moduleResolution": "node", + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true, + "paths": { + "@justaname.id/siwens": ["packages/@justaname.id/siwens"], + "@justaname.id/sdk": ["packages/@justaname.id/sdk"], + "@justaname.id/react": ["packages/@justaname.id/react"], + "@justweb3/ui": ["packages/@justweb3/ui"], + "@justweb3/widget": ["packages/@justweb3/widget"] + } + }, + "files": [], + "include": [ + "node_modules/viem/**/*" + ], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.storybook.json" + } + ] +} diff --git a/packages/@justweb3/xmtp-plugin/tsconfig.lib.json b/packages/@justweb3/xmtp-plugin/tsconfig.lib.json new file mode 100644 index 00000000..b7ad5977 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/tsconfig.lib.json @@ -0,0 +1,39 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "declaration": true, + "declarationMap": true, + "moduleResolution": "node", + "types": [ + "node", + "jest", + "@nx/react/typings/cssmodule.d.ts", + "@nx/react/typings/image.d.ts" + ], + "paths": { + "@justaname.id/siwens": ["packages/@justaname.id/siwens"], + "@justaname.id/sdk": ["packages/@justaname.id/sdk"], + "@justaname.id/react": ["packages/@justaname.id/react"], + "@justweb3/ui": ["packages/@justweb3/ui"], + "@justweb3/widget": ["packages/@justweb3/widget"] + } + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx", + "**/*.stories.ts", + "**/*.stories.js", + "**/*.stories.jsx", + "**/*.stories.tsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx", "../../node_modules/viem/**/*" + ] +} diff --git a/packages/@justweb3/xmtp-plugin/tsconfig.spec.json b/packages/@justweb3/xmtp-plugin/tsconfig.spec.json new file mode 100644 index 00000000..70d68044 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/tsconfig.spec.json @@ -0,0 +1,27 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"], + "paths": { + "@justaname.id/siwens": ["packages/@justaname.id/siwens"], + "@justaname.id/sdk": ["packages/@justaname.id/sdk"], + "@justaname.id/react": ["packages/@justaname.id/react"], + "@justweb3/ui": ["packages/@justweb3/ui"], + "@justweb3/widget": ["packages/@justweb3/widget"] + } + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/packages/@justweb3/xmtp-plugin/tsconfig.storybook.json b/packages/@justweb3/xmtp-plugin/tsconfig.storybook.json new file mode 100644 index 00000000..81d3537c --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/tsconfig.storybook.json @@ -0,0 +1,42 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "emitDecoratorMetadata": true, + "outDir": "tsconfig.storybook", + "module": "esnext", + "noUnusedLocals": false, + "paths": { + "@justaname.id/siwens": ["packages/@justaname.id/siwens"], + "@justaname.id/sdk": ["packages/@justaname.id/sdk"], + "@justaname.id/react": ["packages/@justaname.id/react"], + "@justweb3/ui": ["packages/@justweb3/ui"], + "@justweb3/widget": ["packages/@justweb3/widget"] + } + }, + "files": [ + "../../../../node_modules/@nx/react/typings/styled-jsx.d.ts", + "../../../node_modules/@nx/react/typings/cssmodule.d.ts", + "../../../node_modules/@nx/react/typings/image.d.ts" + ], + "exclude": [ + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.jsx", + "src/**/*.test.js" + ], + "include": [ + "src/lib/**/*.ts", + "src/**/*.stories.ts", + "src/**/*.stories.js", + "src/**/*.stories.jsx", + "src/**/*.stories.tsx", + "src/**/*.stories.mdx", + ".storybook/*.js", + ".storybook/*.ts", + "env.d.ts" + ] +} diff --git a/packages/@justweb3/xmtp-plugin/typedoc.json b/packages/@justweb3/xmtp-plugin/typedoc.json new file mode 100644 index 00000000..d9109a89 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/typedoc.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://typedoc-plugin-markdown.org/schema.json", + "entryPoints": ["./src/index.ts"], + "plugin": ["typedoc-plugin-markdown"], + "out": "../../../docs/sdk/JustWeb3 Talent Protocol Plugin", + "cleanOutputDir": true +} diff --git a/packages/@justweb3/xmtp-plugin/update-package-json.js b/packages/@justweb3/xmtp-plugin/update-package-json.js new file mode 100644 index 00000000..e65e6887 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/update-package-json.js @@ -0,0 +1,31 @@ +const fs = require('fs'); +const path = require('path'); + +// Read the original package.json +const packageJson = require('./package.json'); + +// Modify the paths +packageJson.main = packageJson.main.replace('./dist/', './'); +packageJson.module = packageJson.module.replace('./dist/', './'); +packageJson.types = packageJson.types.replace('./dist/', './'); + +if (packageJson.exports) { + Object.keys(packageJson.exports).forEach((key) => { + if (typeof packageJson.exports[key] === 'string') { + packageJson.exports[key] = packageJson.exports[key].replace( + './dist/', + './' + ); + } else if (typeof packageJson.exports[key] === 'object') { + Object.keys(packageJson.exports[key]).forEach((subKey) => { + packageJson.exports[key][subKey] = packageJson.exports[key][ + subKey + ].replace('./dist/', './'); + }); + } + }); +} + +// Write the modified package.json to the dist folder +const distPath = path.join(__dirname, 'dist', 'package.json'); +fs.writeFileSync(distPath, JSON.stringify(packageJson, null, 2)); diff --git a/yarn.lock b/yarn.lock index 5bd02018..b4be1bad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,6 +24,13 @@ __metadata: languageName: node linkType: hard +"@adraffy/ens-normalize@npm:1.10.0": + version: 1.10.0 + resolution: "@adraffy/ens-normalize@npm:1.10.0" + checksum: 10c0/78ae700847a2516d5a0ae12c4e23d09392a40c67e73b137eb7189f51afb1601c8d18784aeda2ed288a278997824dc924d1f398852c21d41ee2c4c564f2fb4d26 + languageName: node + linkType: hard + "@adraffy/ens-normalize@npm:1.10.1": version: 1.10.1 resolution: "@adraffy/ens-normalize@npm:1.10.1" @@ -3510,6 +3517,13 @@ __metadata: languageName: node linkType: hard +"@fastify/busboy@npm:^2.0.0": + version: 2.1.1 + resolution: "@fastify/busboy@npm:2.1.1" + checksum: 10c0/6f8027a8cba7f8f7b736718b013f5a38c0476eea67034c94a0d3c375e2b114366ad4419e6a6fa7ffc2ef9c6d3e0435d76dd584a7a1cbac23962fda7650b579e3 + languageName: node + linkType: hard + "@floating-ui/core@npm:^1.6.0": version: 1.6.8 resolution: "@floating-ui/core@npm:1.6.8" @@ -4632,6 +4646,18 @@ __metadata: languageName: unknown linkType: soft +"@justweb3/xmtp-plugin@workspace:packages/@justweb3/xmtp-plugin": + version: 0.0.0-use.local + resolution: "@justweb3/xmtp-plugin@workspace:packages/@justweb3/xmtp-plugin" + dependencies: + "@xmtp/react-sdk": "npm:^9.0.0" + peerDependencies: + "@justweb3/widget": ">=0.0.0" + react: ">=17" + wagmi: 2.x + languageName: unknown + linkType: soft + "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.5 resolution: "@leichtgewicht/ip-codec@npm:2.0.5" @@ -5559,7 +5585,7 @@ __metadata: languageName: node linkType: hard -"@noble/curves@npm:1.2.0": +"@noble/curves@npm:1.2.0, @noble/curves@npm:~1.2.0": version: 1.2.0 resolution: "@noble/curves@npm:1.2.0" dependencies: @@ -5614,7 +5640,14 @@ __metadata: languageName: node linkType: hard -"@noble/secp256k1@npm:1.7.1, @noble/secp256k1@npm:~1.7.0": +"@noble/hashes@npm:~1.3.0, @noble/hashes@npm:~1.3.2": + version: 1.3.3 + resolution: "@noble/hashes@npm:1.3.3" + checksum: 10c0/23c020b33da4172c988e44100e33cd9f8f6250b68b43c467d3551f82070ebd9716e0d9d2347427aa3774c85934a35fa9ee6f026fca2117e3fa12db7bedae7668 + languageName: node + linkType: hard + +"@noble/secp256k1@npm:1.7.1, @noble/secp256k1@npm:^1.7.1, @noble/secp256k1@npm:~1.7.0": version: 1.7.1 resolution: "@noble/secp256k1@npm:1.7.1" checksum: 10c0/48091801d39daba75520012027d0ff0b1719338d96033890cfe0d287ad75af00d82769c0194a06e7e4fbd816ae3f204f4a59c9e26f0ad16b429f7e9b5403ccd5 @@ -6952,6 +6985,79 @@ __metadata: languageName: node linkType: hard +"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/aspromise@npm:1.1.2" + checksum: 10c0/a83343a468ff5b5ec6bff36fd788a64c839e48a07ff9f4f813564f58caf44d011cd6504ed2147bf34835bd7a7dd2107052af755961c6b098fd8902b4f6500d0f + languageName: node + linkType: hard + +"@protobufjs/base64@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/base64@npm:1.1.2" + checksum: 10c0/eec925e681081af190b8ee231f9bad3101e189abbc182ff279da6b531e7dbd2a56f1f306f37a80b1be9e00aa2d271690d08dcc5f326f71c9eed8546675c8caf6 + languageName: node + linkType: hard + +"@protobufjs/codegen@npm:^2.0.4": + version: 2.0.4 + resolution: "@protobufjs/codegen@npm:2.0.4" + checksum: 10c0/26ae337c5659e41f091606d16465bbcc1df1f37cc1ed462438b1f67be0c1e28dfb2ca9f294f39100c52161aef82edf758c95d6d75650a1ddf31f7ddee1440b43 + languageName: node + linkType: hard + +"@protobufjs/eventemitter@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/eventemitter@npm:1.1.0" + checksum: 10c0/1eb0a75180e5206d1033e4138212a8c7089a3d418c6dfa5a6ce42e593a4ae2e5892c4ef7421f38092badba4040ea6a45f0928869989411001d8c1018ea9a6e70 + languageName: node + linkType: hard + +"@protobufjs/fetch@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/fetch@npm:1.1.0" + dependencies: + "@protobufjs/aspromise": "npm:^1.1.1" + "@protobufjs/inquire": "npm:^1.1.0" + checksum: 10c0/cda6a3dc2d50a182c5865b160f72077aac197046600091dbb005dd0a66db9cce3c5eaed6d470ac8ed49d7bcbeef6ee5f0bc288db5ff9a70cbd003e5909065233 + languageName: node + linkType: hard + +"@protobufjs/float@npm:^1.0.2": + version: 1.0.2 + resolution: "@protobufjs/float@npm:1.0.2" + checksum: 10c0/18f2bdede76ffcf0170708af15c9c9db6259b771e6b84c51b06df34a9c339dbbeec267d14ce0bddd20acc142b1d980d983d31434398df7f98eb0c94a0eb79069 + languageName: node + linkType: hard + +"@protobufjs/inquire@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/inquire@npm:1.1.0" + checksum: 10c0/64372482efcba1fb4d166a2664a6395fa978b557803857c9c03500e0ac1013eb4b1aacc9ed851dd5fc22f81583670b4f4431bae186f3373fedcfde863ef5921a + languageName: node + linkType: hard + +"@protobufjs/path@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/path@npm:1.1.2" + checksum: 10c0/cece0a938e7f5dfd2fa03f8c14f2f1cf8b0d6e13ac7326ff4c96ea311effd5fb7ae0bba754fbf505312af2e38500250c90e68506b97c02360a43793d88a0d8b4 + languageName: node + linkType: hard + +"@protobufjs/pool@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/pool@npm:1.1.0" + checksum: 10c0/eda2718b7f222ac6e6ad36f758a92ef90d26526026a19f4f17f668f45e0306a5bd734def3f48f51f8134ae0978b6262a5c517c08b115a551756d1a3aadfcf038 + languageName: node + linkType: hard + +"@protobufjs/utf8@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/utf8@npm:1.1.0" + checksum: 10c0/a3fe31fe3fa29aa3349e2e04ee13dc170cc6af7c23d92ad49e3eeaf79b9766264544d3da824dba93b7855bd6a2982fb40032ef40693da98a136d835752beb487 + languageName: node + linkType: hard + "@radix-ui/primitive@npm:1.1.0": version: 1.1.0 resolution: "@radix-ui/primitive@npm:1.1.0" @@ -8637,7 +8743,7 @@ __metadata: languageName: node linkType: hard -"@scure/base@npm:^1.1.3, @scure/base@npm:^1.1.5, @scure/base@npm:~1.1.0, @scure/base@npm:~1.1.6, @scure/base@npm:~1.1.7, @scure/base@npm:~1.1.8": +"@scure/base@npm:^1.1.3, @scure/base@npm:^1.1.5, @scure/base@npm:~1.1.0, @scure/base@npm:~1.1.2, @scure/base@npm:~1.1.6, @scure/base@npm:~1.1.7, @scure/base@npm:~1.1.8": version: 1.1.9 resolution: "@scure/base@npm:1.1.9" checksum: 10c0/77a06b9a2db8144d22d9bf198338893d77367c51b58c72b99df990c0a11f7cadd066d4102abb15e3ca6798d1529e3765f55c4355742465e49aed7a0c01fe76e8 @@ -8655,6 +8761,17 @@ __metadata: languageName: node linkType: hard +"@scure/bip32@npm:1.3.2": + version: 1.3.2 + resolution: "@scure/bip32@npm:1.3.2" + dependencies: + "@noble/curves": "npm:~1.2.0" + "@noble/hashes": "npm:~1.3.2" + "@scure/base": "npm:~1.1.2" + checksum: 10c0/2e9c1ce67f72b6c3329483f5fd39fb43ba6dcf732ed7ac63b80fa96341d2bc4cad1ea4c75bfeb91e801968c00df48b577b015fd4591f581e93f0d91178e630ca + languageName: node + linkType: hard + "@scure/bip32@npm:1.4.0": version: 1.4.0 resolution: "@scure/bip32@npm:1.4.0" @@ -8687,6 +8804,16 @@ __metadata: languageName: node linkType: hard +"@scure/bip39@npm:1.2.1": + version: 1.2.1 + resolution: "@scure/bip39@npm:1.2.1" + dependencies: + "@noble/hashes": "npm:~1.3.0" + "@scure/base": "npm:~1.1.0" + checksum: 10c0/fe951f69dd5a7cdcefbe865bce1b160d6b59ba19bd01d09f0718e54fce37a7d8be158b32f5455f0e9c426a7fbbede3e019bf0baa99bacc88ef26a76a07e115d4 + languageName: node + linkType: hard + "@scure/bip39@npm:1.3.0": version: 1.3.0 resolution: "@scure/bip39@npm:1.3.0" @@ -11638,6 +11765,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:>=13.7.0": + version: 22.9.1 + resolution: "@types/node@npm:22.9.1" + dependencies: + undici-types: "npm:~6.19.8" + checksum: 10c0/ea489ae603aa8874e4e88980aab6f2dad09c755da779c88dd142983bfe9609803c89415ca7781f723072934066f63daf2b3339ef084a8ad1a8079cf3958be243 + languageName: node + linkType: hard + "@types/node@npm:^12.12.6": version: 12.20.55 resolution: "@types/node@npm:12.20.55" @@ -14055,6 +14191,133 @@ __metadata: languageName: node linkType: hard +"@xmtp/consent-proof-signature@npm:^0.1.4": + version: 0.1.4 + resolution: "@xmtp/consent-proof-signature@npm:0.1.4" + dependencies: + "@xmtp/proto": "npm:^3.72.0" + long: "npm:^5.2.3" + checksum: 10c0/61a6744d5e4e063b6b2fac1c8f46b89bc7b6ef762a213b06d312ff9596882da5cb71837c9a7300094f6f82acef893e43a0c9273aa607c1eedf39bb7188b3c688 + languageName: node + linkType: hard + +"@xmtp/content-type-primitives@npm:^1.0.1, @xmtp/content-type-primitives@npm:^1.0.3": + version: 1.0.3 + resolution: "@xmtp/content-type-primitives@npm:1.0.3" + dependencies: + "@xmtp/proto": "npm:^3.72.0" + checksum: 10c0/a644dd24d0edad2c67b4b7a42f5af32914fb2df935debaabde61dba9d0c061692b198757777323c266a1ce84a1a3050d98bde21f795035a18ae076fee9528a0e + languageName: node + linkType: hard + +"@xmtp/content-type-reaction@npm:^1.1.11": + version: 1.1.11 + resolution: "@xmtp/content-type-reaction@npm:1.1.11" + dependencies: + "@xmtp/content-type-primitives": "npm:^1.0.3" + checksum: 10c0/11449e9f6f8d6e4c97ce9b306f40989db588725bb29dd3b87c869df766884c68cc3b128bcbae00bc2688c43b464b64d701a481560c874661b6b2a703340e9d0b + languageName: node + linkType: hard + +"@xmtp/content-type-read-receipt@npm:^1.1.12": + version: 1.1.12 + resolution: "@xmtp/content-type-read-receipt@npm:1.1.12" + dependencies: + "@xmtp/content-type-primitives": "npm:^1.0.3" + checksum: 10c0/086094c96d13c088306e422b395752a033ac8ac7ad8c77611312fd4a0f7c776abc162c9d34de93a9cea9651505bb93be2074bef4d84f582d5202a45860965db1 + languageName: node + linkType: hard + +"@xmtp/content-type-remote-attachment@npm:^1.1.12": + version: 1.1.12 + resolution: "@xmtp/content-type-remote-attachment@npm:1.1.12" + dependencies: + "@noble/secp256k1": "npm:^1.7.1" + "@xmtp/content-type-primitives": "npm:^1.0.3" + "@xmtp/proto": "npm:^3.72.0" + checksum: 10c0/e3491ac0c2a92e2510b8271ccacc9399d8115b7b11874974f208f26e50c1530992c5aadc87742891766f4be0a172549abadeeae1c951425359d959bb01a4a988 + languageName: node + linkType: hard + +"@xmtp/content-type-reply@npm:^1.1.12": + version: 1.1.12 + resolution: "@xmtp/content-type-reply@npm:1.1.12" + dependencies: + "@xmtp/content-type-primitives": "npm:^1.0.3" + "@xmtp/proto": "npm:^3.72.0" + checksum: 10c0/e9e60e69277f91792a7b261321c7ab85d05af56d9f4f128c98ab185f6b973d4adbafa02c788127eca9f8ac517460b3a65314e34d56f44e3e7b201aa7681edb1e + languageName: node + linkType: hard + +"@xmtp/content-type-text@npm:^1.0.0, @xmtp/content-type-text@npm:^1.0.1": + version: 1.0.1 + resolution: "@xmtp/content-type-text@npm:1.0.1" + dependencies: + "@xmtp/content-type-primitives": "npm:^1.0.3" + checksum: 10c0/d981039d21ce437b3ae7eaa2e2c2779788c823354b59f261d9bf0582862d9b44872c20ae4964587a502adcc2fca99162e60adf55460992dacdc795513e035465 + languageName: node + linkType: hard + +"@xmtp/proto@npm:^3.72.0": + version: 3.72.3 + resolution: "@xmtp/proto@npm:3.72.3" + dependencies: + long: "npm:^5.2.0" + protobufjs: "npm:^7.0.0" + rxjs: "npm:^7.8.0" + undici: "npm:^5.8.1" + checksum: 10c0/ce899a62307853efd2fe199144ded806560b7f9f5d2b5b08948a001530a8cf43151fbb6b56e6e71879c4a72ab50ab7233b0cc9f7b1ed28e7e3ea86ff90f7d9df + languageName: node + linkType: hard + +"@xmtp/react-sdk@npm:^9.0.0": + version: 9.0.0 + resolution: "@xmtp/react-sdk@npm:9.0.0" + dependencies: + "@xmtp/content-type-primitives": "npm:^1.0.1" + "@xmtp/content-type-text": "npm:^1.0.0" + async-mutex: "npm:^0.5.0" + date-fns: "npm:^3.6.0" + dexie: "npm:^4.0.8" + dexie-react-hooks: "npm:^1.1.7" + uuid: "npm:^10.0.0" + zod: "npm:^3.23.8" + peerDependencies: + "@xmtp/content-type-primitives": ^1.0.1 + "@xmtp/content-type-reaction": ^1.1.7 + "@xmtp/content-type-remote-attachment": ^1.1.8 + "@xmtp/content-type-reply": ^1.1.9 + "@xmtp/xmtp-js": ^12.1.0 + react: ^16.14.0 || ^17 || ^18 + checksum: 10c0/adaa6b8b576251b7da474ca013ab032ad88febba5518cdf561ed507e061a61a35db79460b40793a98dff17a0322a175490941495ee1e728126dbdb83cabe6d02 + languageName: node + linkType: hard + +"@xmtp/user-preferences-bindings-wasm@npm:^0.3.6": + version: 0.3.6 + resolution: "@xmtp/user-preferences-bindings-wasm@npm:0.3.6" + checksum: 10c0/8a28468e3c82c85157dd7962485fec2712f448aa510fb46c51ea0e01139b0e316aa52ecbbc4a84604b254aa848e045dd378b1c116465c7739926a9a0bb4425f6 + languageName: node + linkType: hard + +"@xmtp/xmtp-js@npm:^13.0.4": + version: 13.0.4 + resolution: "@xmtp/xmtp-js@npm:13.0.4" + dependencies: + "@noble/secp256k1": "npm:1.7.1" + "@xmtp/consent-proof-signature": "npm:^0.1.4" + "@xmtp/content-type-primitives": "npm:^1.0.3" + "@xmtp/content-type-text": "npm:^1.0.1" + "@xmtp/proto": "npm:^3.72.0" + "@xmtp/user-preferences-bindings-wasm": "npm:^0.3.6" + async-mutex: "npm:^0.5.0" + elliptic: "npm:^6.5.7" + long: "npm:^5.2.3" + viem: "npm:2.7.15" + checksum: 10c0/6e93652ba5f1385253fae0c0714042cf9ed070279e34bb907b3739325486741e85158a6d77273c779440a3dd9bda2f4c6510203f58a0bcba05afe52883c24f8d + languageName: node + linkType: hard + "@xtuc/ieee754@npm:^1.2.0": version: 1.2.0 resolution: "@xtuc/ieee754@npm:1.2.0" @@ -14150,6 +14413,21 @@ __metadata: languageName: node linkType: hard +"abitype@npm:1.0.0": + version: 1.0.0 + resolution: "abitype@npm:1.0.0" + peerDependencies: + typescript: ">=5.0.4" + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + checksum: 10c0/d685351a725c49f81bdc588e2f3825c28ad96c59048d4f36bf5e4ef30935c31f7e60b5553c70177b77a9e4d8b04290eea43d3d9c1c2562cb130381c88b15d39f + languageName: node + linkType: hard + "abitype@npm:1.0.6, abitype@npm:^1.0.0": version: 1.0.6 resolution: "abitype@npm:1.0.6" @@ -14891,6 +15169,15 @@ __metadata: languageName: node linkType: hard +"async-mutex@npm:^0.5.0": + version: 0.5.0 + resolution: "async-mutex@npm:0.5.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/9096e6ad6b674c894d8ddd5aa4c512b09bb05931b8746ebd634952b05685608b2b0820ed5c406e6569919ff5fe237ab3c491e6f2887d6da6b6ba906db3ee9c32 + languageName: node + linkType: hard + "async@npm:3.2.4": version: 3.2.4 resolution: "async@npm:3.2.4" @@ -18585,6 +18872,24 @@ __metadata: languageName: node linkType: hard +"dexie-react-hooks@npm:^1.1.7": + version: 1.1.7 + resolution: "dexie-react-hooks@npm:1.1.7" + peerDependencies: + "@types/react": ">=16" + dexie: ^3.2 || ^4.0.1-alpha + react: ">=16" + checksum: 10c0/3ff38e715a52bff9132b483963246ea5372a282d9257c8c2bf8891c522fa0d761d1e362bb352eb63386f49ea9a55c52e1bcc5cce2019deb1eceba40d8a88631d + languageName: node + linkType: hard + +"dexie@npm:^4.0.8": + version: 4.0.10 + resolution: "dexie@npm:4.0.10" + checksum: 10c0/7e5cbc79947fd830918679f8621bceb4e543f139eb8ec73d5a9605927e5d659ea306a9649bbac7c37d55e623888daaf416f9868422badebc26049c9c2ebf1dfb + languageName: node + linkType: hard + "didyoumean@npm:^1.2.2": version: 1.2.2 resolution: "didyoumean@npm:1.2.2" @@ -24475,6 +24780,15 @@ __metadata: languageName: node linkType: hard +"isows@npm:1.0.3": + version: 1.0.3 + resolution: "isows@npm:1.0.3" + peerDependencies: + ws: "*" + checksum: 10c0/adec15db704bb66615dd8ef33f889d41ae2a70866b21fa629855da98cc82a628ae072ee221fe9779a9a19866cad2a3e72593f2d161a0ce0e168b4484c7df9cd2 + languageName: node + linkType: hard + "isows@npm:1.0.6": version: 1.0.6 resolution: "isows@npm:1.0.6" @@ -26327,6 +26641,12 @@ __metadata: "@vitest/ui": "npm:1.3.1" "@walletconnect/react-native-compat": "npm:^2.11.2" "@web3modal/wagmi-react-native": "npm:^1.2.0" + "@xmtp/content-type-reaction": "npm:^1.1.11" + "@xmtp/content-type-read-receipt": "npm:^1.1.12" + "@xmtp/content-type-remote-attachment": "npm:^1.1.12" + "@xmtp/content-type-reply": "npm:^1.1.12" + "@xmtp/react-sdk": "npm:^9.0.0" + "@xmtp/xmtp-js": "npm:^13.0.4" autoprefixer: "npm:^10.4.20" axios: "npm:^1.6.0" babel-jest: "npm:29.7.0" @@ -26378,7 +26698,7 @@ __metadata: prism-react-renderer: "npm:^2.4.0" punycode: "npm:^2.3.1" qs: "npm:^6.12.0" - react: "npm:18.3.1" + react: "npm:^18.3.1" react-code-blocks: "npm:^0.1.6" react-dom: "npm:18.3.1" react-hook-form: "npm:^7.53.0" @@ -27367,6 +27687,13 @@ __metadata: languageName: node linkType: hard +"long@npm:^5.0.0, long@npm:^5.2.0, long@npm:^5.2.3": + version: 5.2.3 + resolution: "long@npm:5.2.3" + checksum: 10c0/6a0da658f5ef683b90330b1af76f06790c623e148222da9d75b60e266bbf88f803232dd21464575681638894a84091616e7f89557aa087fd14116c0f4e0e43d9 + languageName: node + linkType: hard + "loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" @@ -32187,6 +32514,26 @@ __metadata: languageName: node linkType: hard +"protobufjs@npm:^7.0.0": + version: 7.4.0 + resolution: "protobufjs@npm:7.4.0" + dependencies: + "@protobufjs/aspromise": "npm:^1.1.2" + "@protobufjs/base64": "npm:^1.1.2" + "@protobufjs/codegen": "npm:^2.0.4" + "@protobufjs/eventemitter": "npm:^1.1.0" + "@protobufjs/fetch": "npm:^1.1.0" + "@protobufjs/float": "npm:^1.0.2" + "@protobufjs/inquire": "npm:^1.1.0" + "@protobufjs/path": "npm:^1.1.2" + "@protobufjs/pool": "npm:^1.1.0" + "@protobufjs/utf8": "npm:^1.1.0" + "@types/node": "npm:>=13.7.0" + long: "npm:^5.0.0" + checksum: 10c0/a5460a63fe596523b9a067cbce39a6b310d1a71750fda261f076535662aada97c24450e18c5bc98a27784f70500615904ff1227e1742183509f0db4fdede669b + languageName: node + linkType: hard + "proxy-addr@npm:~2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" @@ -32993,7 +33340,7 @@ __metadata: languageName: node linkType: hard -"react@npm:18.3.1, react@npm:^16.8.0 || ^17.0.0 || ^18.0.0": +"react@npm:^16.8.0 || ^17.0.0 || ^18.0.0, react@npm:^18.3.1": version: 18.3.1 resolution: "react@npm:18.3.1" dependencies: @@ -37276,6 +37623,15 @@ __metadata: languageName: node linkType: hard +"undici@npm:^5.8.1": + version: 5.28.4 + resolution: "undici@npm:5.28.4" + dependencies: + "@fastify/busboy": "npm:^2.0.0" + checksum: 10c0/08d0f2596553aa0a54ca6e8e9c7f45aef7d042c60918564e3a142d449eda165a80196f6ef19ea2ef2e6446959e293095d8e40af1236f0d67223b06afac5ecad7 + languageName: node + linkType: hard + "unenv@npm:^1.10.0": version: 1.10.0 resolution: "unenv@npm:1.10.0" @@ -37805,6 +38161,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^10.0.0": + version: 10.0.0 + resolution: "uuid@npm:10.0.0" + bin: + uuid: dist/bin/uuid + checksum: 10c0/eab18c27fe4ab9fb9709a5d5f40119b45f2ec8314f8d4cf12ce27e4c6f4ffa4a6321dc7db6c515068fa373c075b49691ba969f0010bf37f44c37ca40cd6bf7fe + languageName: node + linkType: hard + "uuid@npm:^7.0.3": version: 7.0.3 resolution: "uuid@npm:7.0.3" @@ -38048,6 +38413,27 @@ __metadata: languageName: node linkType: hard +"viem@npm:2.7.15": + version: 2.7.15 + resolution: "viem@npm:2.7.15" + dependencies: + "@adraffy/ens-normalize": "npm:1.10.0" + "@noble/curves": "npm:1.2.0" + "@noble/hashes": "npm:1.3.2" + "@scure/bip32": "npm:1.3.2" + "@scure/bip39": "npm:1.2.1" + abitype: "npm:1.0.0" + isows: "npm:1.0.3" + ws: "npm:8.13.0" + peerDependencies: + typescript: ">=5.0.4" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/c9e987d959e5b91578fc0082a4142a83832d27575ec23fdafd7569d46acaa6f65ccd4c8a5a0b3ebfac8bfe0b2d74cd48d7e51357701806d9bebb9607077b242a + languageName: node + linkType: hard + "viem@npm:2.x, viem@npm:^2.1.1, viem@npm:^2.21.9": version: 2.21.37 resolution: "viem@npm:2.21.37" @@ -39103,6 +39489,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:8.13.0": + version: 8.13.0 + resolution: "ws@npm:8.13.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/579817dbbab3ee46669129c220cfd81ba6cdb9ab5c3e9a105702dd045743c4ab72e33bb384573827c0c481213417cc880e41bc097e0fc541a0b79fa3eb38207d + languageName: node + linkType: hard + "ws@npm:8.17.1, ws@npm:~8.17.1": version: 8.17.1 resolution: "ws@npm:8.17.1" @@ -39440,7 +39841,7 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.21.4, zod@npm:^3.22.4": +"zod@npm:^3.21.4, zod@npm:^3.22.4, zod@npm:^3.23.8": version: 3.23.8 resolution: "zod@npm:3.23.8" checksum: 10c0/8f14c87d6b1b53c944c25ce7a28616896319d95bc46a9660fe441adc0ed0a81253b02b5abdaeffedbeb23bdd25a0bf1c29d2c12dd919aef6447652dd295e3e69 From 9bc689c8851bfcef48e0acd356828762c44cb290 Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Mon, 25 Nov 2024 11:25:46 +0200 Subject: [PATCH 02/29] feat: chat and getting the messages --- .../lib/icons/components/general/Profile.tsx | 5 +- .../ui/src/lib/icons/svgs/general/profile.svg | 4 +- .../lib/components/JustWeb3Button/index.tsx | 74 ++++++++++++------- .../src/lib/components/Chat/index.tsx | 16 ++++ .../src/lib/components/ChatButton/index.tsx | 1 + .../src/lib/components/ChatList/index.tsx | 15 +++- .../src/lib/components/ChatSheet/index.tsx | 28 ++++++- .../src/lib/components/MessageItem/index.tsx | 53 ++++++++++++- .../src/lib/components/MessageSheet/index.tsx | 29 ++++++++ .../providers/JustWeb3XMTPProvider/index.tsx | 24 +++++- .../src/lib/utils/formatChatDate/index.ts | 49 ++++++++++++ 11 files changed, 256 insertions(+), 42 deletions(-) create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/utils/formatChatDate/index.ts diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Profile.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Profile.tsx index 6ca101a3..973f9f2d 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Profile.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Profile.tsx @@ -1,4 +1,5 @@ import type { SVGProps } from 'react'; + export default function Profile(props: SVGProps) { return ( ) { maskType: 'alpha', }} > - + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/profile.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/profile.svg index 8cdc7923..c09222df 100644 --- a/packages/@justweb3/ui/src/lib/icons/svgs/general/profile.svg +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/profile.svg @@ -1,8 +1,8 @@ - + - + diff --git a/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx b/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx index ec4dce46..1932a888 100644 --- a/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx @@ -2,10 +2,8 @@ import { FC, Fragment, ReactNode, useContext, useMemo, useState } from 'react'; import { JustWeb3Context, useJustWeb3 } from '../../providers'; import { ArrowIcon, - ArrowWhiteIcon, Avatar, Badge, - Button, ClickableItem, Flex, formatText, @@ -15,6 +13,7 @@ import { P, Popover, PopoverTrigger, + ProfileIcon, SPAN, } from '@justweb3/ui'; import { @@ -188,37 +187,37 @@ export const JustWeb3Button: FC = ({ const connectedEnsProfileContent = ( - -

- Profile Overview -

- - + {/**/} + {/* */} + {/* Profile Overview*/} + {/*

*/} + {/* */} + {/* }*/} + {/* onClick={() => {*/} + {/* openEnsProfile(connectedEns?.ens, connectedEns?.chainId);*/} + {/* }}*/} + {/* >*/} + {/* View Full Profile*/} + {/* */} + {/*
*/} {/* Profile */} @@ -283,6 +282,24 @@ export const JustWeb3Button: FC = ({ + + } + title={'Profile'} + style={{ + width: '100%', + }} + onClick={() => + openEnsProfile(connectedEns?.ens, connectedEns?.chainId) + } + right={ + + } + /> {plugins.map((plugin) => { const component = plugin.components?.SignInMenu; if (!component) { @@ -306,6 +323,7 @@ export const JustWeb3Button: FC = ({ title={'mApps'} style={{ width: '100%', + display: 'none', }} onClick={() => setOpenMApps(true)} right={ diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx new file mode 100644 index 00000000..4ad6d2e7 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx @@ -0,0 +1,16 @@ +import { + CachedConversation, + ContentTypeMetadata, + useMessages, +} from '@xmtp/react-sdk'; + +export interface ChatProps { + conversation: CachedConversation; +} + +export const Chat: React.FC = ({ conversation }) => { + const { messages } = useMessages(conversation); + + console.log(messages); + return null; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx index 883b7ca9..df728b2d 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx @@ -26,6 +26,7 @@ export const ChatButton: React.FC = ({ handleOpen }) => { handleOpen(true); } }; + return ( []; + handleOpenChat: ( + conversation: CachedConversation | null + ) => void; } -export const ChatList: React.FC = ({ conversations }) => { +export const ChatList: React.FC = ({ + conversations, + handleOpenChat, +}) => { return ( {conversations.map((conversation) => ( - + handleOpenChat(conversation)} + key={conversation.topic} + /> ))} ); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx index 95b4ccd8..5a794bda 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx @@ -9,8 +9,11 @@ import { } from '@justweb3/ui'; import React, { useEffect, useMemo } from 'react'; import { + CachedConversation, + ContentTypeMetadata, useConsent, useConversations, + useStreamAllMessages, useStreamConversations, } from '@xmtp/react-sdk'; import { ChatList } from '../ChatList'; @@ -18,9 +21,16 @@ import { ChatList } from '../ChatList'; export interface ChatSheetProps { open?: boolean; handleOpen?: (open: boolean) => void; + handleOpenChat: ( + conversation: CachedConversation | null + ) => void; } -export const ChatSheet: React.FC = ({ open, handleOpen }) => { +export const ChatSheet: React.FC = ({ + open, + handleOpen, + handleOpenChat, +}) => { const [tab, setTab] = React.useState('Chats'); const { conversations, isLoading } = useConversations(); const [isConsentListLoading, setIsConsentListLoading] = React.useState(true); @@ -58,6 +68,7 @@ export const ChatSheet: React.FC = ({ open, handleOpen }) => { }, [loadConsentList]); useStreamConversations(); + useStreamAllMessages(); return ( @@ -100,13 +111,22 @@ export const ChatSheet: React.FC = ({ open, handleOpen }) => { ) : ( <> - + - + - + )} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx index 71fd7388..80ee2e9b 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx @@ -5,17 +5,24 @@ import { reactionContentTypeConfig, replyContentTypeConfig, useLastMessage, + useStreamMessages, } from '@xmtp/react-sdk'; import { useEnsAvatar, usePrimaryName, useRecords } from '@justaname.id/react'; import { Avatar, Flex, formatText, P, SPAN } from '@justweb3/ui'; import React, { useMemo } from 'react'; +import { formatChatDate } from '../../utils/formatChatDate'; export interface MessageItemProps { conversation: CachedConversation; + onClick?: () => void; } -export const MessageItem: React.FC = ({ conversation }) => { +export const MessageItem: React.FC = ({ + conversation, + onClick, +}) => { const lastMessage = useLastMessage(conversation.topic); + useStreamMessages(conversation); const { primaryName } = usePrimaryName({ address: conversation.peerAddress as `0x${string}`, }); @@ -62,6 +69,7 @@ export const MessageItem: React.FC = ({ conversation }) => { borderRadius: '5px', cursor: 'pointer', }} + onClick={onClick} > = ({ conversation }) => { } /> - +

{primaryName || formatText(conversation.peerAddress, 4)}

+ + {lastMessage + ? lastMessage.senderAddress !== conversation.peerAddress + ? 'You: ' + : '' + : ''} + {lastMessage + ? lastContent + ? lastContent + : 'No preview available' + : ''} + +
+ + - {lastContent || 'No preview available'} + {lastMessage?.sentAt ? formatChatDate(lastMessage.sentAt) : ''}
diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx new file mode 100644 index 00000000..1f13604a --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx @@ -0,0 +1,29 @@ +import { CachedConversation, ContentTypeMetadata } from '@xmtp/react-sdk'; +import { Sheet, SheetContent } from '@justweb3/ui'; +import { Chat } from '../Chat'; + +export interface MessageSheetProps { + conversation: CachedConversation | null; + openChat: boolean; + handleOpenChat: ( + conversation: CachedConversation | null + ) => void; +} + +export const MessageSheet: React.FC = ({ + conversation, + handleOpenChat, + openChat, +}) => { + return ( + !open && handleOpenChat(null)} + > + + Messages + {conversation && } + + + ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx index a32f800e..d2f35b9b 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx @@ -1,6 +1,8 @@ import React, { useEffect } from 'react'; import { attachmentContentTypeConfig, + CachedConversation, + ContentTypeMetadata, reactionContentTypeConfig, replyContentTypeConfig, useClient, @@ -8,6 +10,7 @@ import { } from '@xmtp/react-sdk'; import { useJustWeb3 } from '@justweb3/widget'; import { ChatSheet } from '../../components/ChatSheet'; +import { MessageSheet } from '../../components/MessageSheet'; const contentTypeConfigs = [ attachmentContentTypeConfig, @@ -33,15 +36,34 @@ export const JustWeb3XMTPProvider: React.FC = ({ handleOpen, }) => { const [isXmtpEnabled, setIsXmtpEnabled] = React.useState(false); + const [conversation, setConversation] = + React.useState | null>(null); const handleXmtpEnabled = (enabled: boolean) => { setIsXmtpEnabled(enabled); }; + const handleOpenChat = ( + conversation: CachedConversation | null + ) => { + setConversation(conversation); + }; + return ( - {isXmtpEnabled && } + + {isXmtpEnabled && ( + + )} {children} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/utils/formatChatDate/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/utils/formatChatDate/index.ts new file mode 100644 index 00000000..158a16b7 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/utils/formatChatDate/index.ts @@ -0,0 +1,49 @@ +export const formatChatDate = (inputDate: Date): string => { + const now = new Date(); + const input = new Date(inputDate); + + // Helper function to format date as DD/MM/YYYY + const formatDate = (date: Date): string => + `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`; + + // Check if it's today + if ( + input.getDate() === now.getDate() && + input.getMonth() === now.getMonth() && + input.getFullYear() === now.getFullYear() + ) { + return `${input.getHours()}:${String(input.getMinutes()).padStart(2, '0')}`; + } + + // Check if it's yesterday + const yesterday = new Date(now); + yesterday.setDate(now.getDate() - 1); + + if ( + input.getDate() === yesterday.getDate() && + input.getMonth() === yesterday.getMonth() && + input.getFullYear() === yesterday.getFullYear() + ) { + return 'Yesterday'; + } + + // Check if it's within the last week + const oneWeekAgo = new Date(now); + oneWeekAgo.setDate(now.getDate() - 7); + + if (input > oneWeekAgo) { + const dayNames = [ + 'Sunday', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + ]; + return dayNames[input.getDay()]; + } + + // Default to DD/MM/YYYY format for older dates + return formatDate(input); +}; From b135daa70f0ccaa364c597130b7895316af733be Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Mon, 25 Nov 2024 12:59:27 +0200 Subject: [PATCH 03/29] fix: tabs css --- packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css b/packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css index 74cb32af..dac10440 100644 --- a/packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css +++ b/packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css @@ -1,7 +1,7 @@ .tabsList { - align-items: center; - justify-content: center; + /*align-items: center;*/ + /*justify-content: center;*/ border-radius: 0.375rem; margin-bottom: 10px; gap: 10px; From cbfb4af45494b645914506802a14413cc38a3e90 Mon Sep 17 00:00:00 2001 From: anthony2399 Date: Tue, 26 Nov 2024 21:24:56 +0200 Subject: [PATCH 04/29] feat: working on chat --- package.json | 3 + packages/@justweb3/ui/project.json | 2 +- .../icons/components/general/AddFolder.tsx | 31 ++ .../lib/icons/components/general/AddImage.tsx | 31 ++ .../lib/icons/components/general/AddVideo.tsx | 31 ++ .../components/general/BlockedAccount.tsx | 31 ++ .../lib/icons/components/general/Document.tsx | 31 ++ .../lib/icons/components/general/Download.tsx | 38 ++ .../src/lib/icons/components/general/Mic.tsx | 31 ++ .../lib/icons/components/general/Pause.tsx | 38 ++ .../src/lib/icons/components/general/Play.tsx | 28 ++ .../lib/icons/components/general/Profile.tsx | 1 - .../lib/icons/components/general/Reaction.tsx | 31 ++ .../lib/icons/components/general/Reply.tsx | 31 ++ .../src/lib/icons/components/general/Send.tsx | 31 ++ .../src/lib/icons/components/general/Stop.tsx | 38 ++ .../src/lib/icons/components/general/Tune.tsx | 31 ++ .../src/lib/icons/components/general/index.ts | 42 ++ .../src/lib/icons/svgs/general/add-folder.svg | 10 + .../src/lib/icons/svgs/general/add-image.svg | 10 + .../src/lib/icons/svgs/general/add-video.svg | 10 + .../icons/svgs/general/blocked-account.svg | 8 + .../src/lib/icons/svgs/general/document.svg | 10 + .../src/lib/icons/svgs/general/download.svg | 15 + .../ui/src/lib/icons/svgs/general/mic.svg | 10 + .../ui/src/lib/icons/svgs/general/pause.svg | 15 + .../ui/src/lib/icons/svgs/general/play.svg | 10 + .../src/lib/icons/svgs/general/reaction.svg | 8 + .../ui/src/lib/icons/svgs/general/reply.svg | 8 + .../ui/src/lib/icons/svgs/general/send.svg | 10 + .../ui/src/lib/icons/svgs/general/stop.svg | 15 + .../ui/src/lib/icons/svgs/general/tune.svg | 10 + .../src/lib/ui/Skeleton/Skeleton.module.css | 15 + .../ui/src/lib/ui/Skeleton/index.tsx | 17 + packages/@justweb3/ui/src/lib/ui/index.ts | 1 + .../src/lib/components/Chat/index.tsx | 391 ++++++++++++++- .../src/lib/components/CustomPlayer/index.tsx | 95 ++++ .../components/CustomVoicePreview/index.tsx | 89 ++++ .../lib/components/EmojiSelector/index.tsx | 80 +++ .../src/lib/components/MessageCard/index.tsx | 415 ++++++++++++++++ .../src/lib/components/MessageSheet/index.tsx | 6 +- .../components/MessageSkeletonCard/index.tsx | 37 ++ .../lib/components/MessageTextField/index.tsx | 459 ++++++++++++++++++ .../lib/components/VoiceMessageCard/index.tsx | 145 ++++++ .../xmtp-plugin/src/lib/hooks/index.ts | 8 + .../src/lib/hooks/sendAttachment/index.ts | 38 ++ .../src/lib/hooks/sendMessage/index.ts | 33 ++ .../lib/hooks/sendReactionMessage/index.ts | 57 +++ .../src/lib/hooks/sendReplyMessage/index.ts | 50 ++ .../lib/hooks/useAttachmentChange/index.tsx | 79 +++ .../src/lib/hooks/useDebounced/index.ts | 36 ++ .../lib/hooks/useGetAudioDuration/index.tsx | 41 ++ .../src/lib/hooks/useRecordingTimer/index.tsx | 46 ++ .../src/lib/hooks/useVoiceRecording/index.tsx | 96 ++++ .../providers/JustWeb3XMTPProvider/index.tsx | 2 +- .../src/lib/utils/attachments/index.ts | 14 + .../src/lib/utils/calculateFileSize/index.ts | 9 + .../xmtp-plugin/src/lib/utils/emojis/index.ts | 121 +++++ .../utils/filterReactionsMessages/index.ts | 25 + .../src/lib/utils/formatAddress/index.ts | 5 + .../src/lib/utils/formatVoiceTime/index.ts | 12 + .../src/lib/utils/groupMessageByDate/index.ts | 37 ++ .../src/lib/utils/messageTimeFormat/index.ts | 16 + .../src/lib/utils/recordingValue/index.ts | 12 + yarn.lock | 262 +++++++++- 65 files changed, 3387 insertions(+), 11 deletions(-) create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/AddFolder.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/AddImage.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/AddVideo.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/BlockedAccount.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Document.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Download.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Mic.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Pause.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Play.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Reaction.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Reply.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Send.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Stop.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/components/general/Tune.tsx create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/add-folder.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/add-image.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/add-video.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/blocked-account.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/document.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/download.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/mic.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/pause.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/play.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/reaction.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/reply.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/send.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/stop.svg create mode 100644 packages/@justweb3/ui/src/lib/icons/svgs/general/tune.svg create mode 100644 packages/@justweb3/ui/src/lib/ui/Skeleton/Skeleton.module.css create mode 100644 packages/@justweb3/ui/src/lib/ui/Skeleton/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/CustomPlayer/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/CustomVoicePreview/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/EmojiSelector/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/MessageSkeletonCard/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/sendAttachment/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/sendMessage/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/sendReactionMessage/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/sendReplyMessage/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/useAttachmentChange/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/useDebounced/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/useGetAudioDuration/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/useRecordingTimer/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/useVoiceRecording/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/utils/attachments/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/utils/calculateFileSize/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/utils/emojis/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/utils/filterReactionsMessages/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/utils/formatAddress/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/utils/formatVoiceTime/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/utils/groupMessageByDate/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/utils/messageTimeFormat/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/utils/recordingValue/index.ts diff --git a/package.json b/package.json index bbf115d2..01cf32bb 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-popover": "^1.1.1", "@radix-ui/react-radio-group": "^1.2.1", + "@radix-ui/react-slider": "^1.2.1", "@radix-ui/react-switch": "^1.1.1", "@radix-ui/react-tabs": "^1.1.1", "@radix-ui/react-tooltip": "^1.1.4", @@ -91,6 +92,7 @@ "react-code-blocks": "^0.1.6", "react-dom": "18.3.1", "react-hook-form": "^7.53.0", + "react-media-recorder-2": "^1.6.23", "react-native": "0.73.2", "react-native-svg": "14.1.0", "react-native-svg-transformer": "1.2.0", @@ -98,6 +100,7 @@ "react-native-web": "~0.19.9", "react-router-dom": "6.11.2", "react-split": "^2.0.14", + "react-timer-hook": "^3.0.8", "react-tiny-popover": "^8.0.4", "siwe": "^2.3.2", "styled-components": "^6.1.12", diff --git a/packages/@justweb3/ui/project.json b/packages/@justweb3/ui/project.json index 112cc57c..0983136a 100644 --- a/packages/@justweb3/ui/project.json +++ b/packages/@justweb3/ui/project.json @@ -40,7 +40,7 @@ "command": "node update-package-json.js" }, { - "command": "rm -rf node_modules || rmdir /s /q node_modules" + "command": "rmdir /s /q node_modules" } ], "cwd": "packages/@justweb3/ui", diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/AddFolder.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/AddFolder.tsx new file mode 100644 index 00000000..66192730 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/AddFolder.tsx @@ -0,0 +1,31 @@ +import type { SVGProps } from 'react'; +export default function AddFolder(props: SVGProps) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/AddImage.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/AddImage.tsx new file mode 100644 index 00000000..7839c549 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/AddImage.tsx @@ -0,0 +1,31 @@ +import type { SVGProps } from 'react'; +export default function AddImage(props: SVGProps) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/AddVideo.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/AddVideo.tsx new file mode 100644 index 00000000..6e10e959 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/AddVideo.tsx @@ -0,0 +1,31 @@ +import type { SVGProps } from 'react'; +export default function AddVideo(props: SVGProps) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/BlockedAccount.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/BlockedAccount.tsx new file mode 100644 index 00000000..4e9927c9 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/BlockedAccount.tsx @@ -0,0 +1,31 @@ +import type { SVGProps } from 'react'; +export default function BlockedAccount(props: SVGProps) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Document.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Document.tsx new file mode 100644 index 00000000..dd1985b3 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Document.tsx @@ -0,0 +1,31 @@ +import type { SVGProps } from 'react'; +export default function Document(props: SVGProps) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Download.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Download.tsx new file mode 100644 index 00000000..7e7ab106 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Download.tsx @@ -0,0 +1,38 @@ +import type { SVGProps } from 'react'; +export default function Download(props: SVGProps) { + return ( + + + + + + + + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Mic.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Mic.tsx new file mode 100644 index 00000000..09f22fad --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Mic.tsx @@ -0,0 +1,31 @@ +import type { SVGProps } from 'react'; +export default function Mic(props: SVGProps) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Pause.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Pause.tsx new file mode 100644 index 00000000..3a194831 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Pause.tsx @@ -0,0 +1,38 @@ +import type { SVGProps } from 'react'; +export default function Pause(props: SVGProps) { + return ( + + + + + + + + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Play.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Play.tsx new file mode 100644 index 00000000..415d1286 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Play.tsx @@ -0,0 +1,28 @@ +import type { SVGProps } from 'react'; +export default function Play(props: SVGProps) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Profile.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Profile.tsx index 973f9f2d..fb8b81ba 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Profile.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Profile.tsx @@ -1,5 +1,4 @@ import type { SVGProps } from 'react'; - export default function Profile(props: SVGProps) { return ( ) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Reply.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Reply.tsx new file mode 100644 index 00000000..f27a79eb --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Reply.tsx @@ -0,0 +1,31 @@ +import type { SVGProps } from 'react'; +export default function Reply(props: SVGProps) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Send.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Send.tsx new file mode 100644 index 00000000..8984fec6 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Send.tsx @@ -0,0 +1,31 @@ +import type { SVGProps } from 'react'; +export default function Send(props: SVGProps) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Stop.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Stop.tsx new file mode 100644 index 00000000..4a89de68 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Stop.tsx @@ -0,0 +1,38 @@ +import type { SVGProps } from 'react'; +export default function Stop(props: SVGProps) { + return ( + + + + + + + + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Tune.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Tune.tsx new file mode 100644 index 00000000..339fd4fc --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Tune.tsx @@ -0,0 +1,31 @@ +import type { SVGProps } from 'react'; +export default function Tune(props: SVGProps) { + return ( + + + + + + + + + ); +} diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/index.ts b/packages/@justweb3/ui/src/lib/icons/components/general/index.ts index e1e4e964..52eb7a0d 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/index.ts +++ b/packages/@justweb3/ui/src/lib/icons/components/general/index.ts @@ -1,4 +1,7 @@ import AddCircleIcon from './AddCircle'; +import AddFolderIcon from './AddFolder'; +import AddImageIcon from './AddImage'; +import AddVideoIcon from './AddVideo'; import AddIcon from './Add'; import AddressIcon from './Address'; import ArrowWhiteIcon from './ArrowWhite'; @@ -6,6 +9,7 @@ import ArrowIcon from './Arrow'; import AttachmentIcon from './Attachment'; import AvatarIcon from './Avatar'; import BannerIcon from './Banner'; +import BlockedAccountIcon from './BlockedAccount'; import CalendarClockIcon from './CalendarClock'; import CalendarMonthIcon from './CalendarMonth'; import ClipIcon from './Clip'; @@ -15,7 +19,9 @@ import ContactsIcon from './Contacts'; import CopiedIcon from './Copied'; import CopyIcon from './Copy'; import DeleteIcon from './Delete'; +import DocumentIcon from './Document'; import DoneIcon from './Done'; +import DownloadIcon from './Download'; import EditIcon from './Edit'; import GeneralIcon from './General'; import LocationOnIcon from './LocationOn'; @@ -23,21 +29,32 @@ import LocationIcon from './Location'; import LogoutIcon from './Logout'; import MappIcon from './Mapp'; import MaximizeIcon from './Maximize'; +import MicIcon from './Mic'; import MinimizeIcon from './Minimize'; import MinusIcon from './Minus'; import NicknameIcon from './Nickname'; import NotificationIcon from './Notification'; +import PauseIcon from './Pause'; import PenIcon from './Pen'; import PersonEditIcon from './PersonEdit'; +import PlayIcon from './Play'; import ProfileEditIcon from './ProfileEdit'; import ProfileIcon from './Profile'; +import ReactionIcon from './Reaction'; +import ReplyIcon from './Reply'; +import SendIcon from './Send'; import SocialIcon from './Social'; +import StopIcon from './Stop'; import TrashWhiteIcon from './TrashWhite'; import TrashIcon from './Trash'; +import TuneIcon from './Tune'; import VerificationsIcon from './Verifications'; import WalletIcon from './Wallet'; const general = { 'add-circle': AddCircleIcon, + 'add-folder': AddFolderIcon, + 'add-image': AddImageIcon, + 'add-video': AddVideoIcon, add: AddIcon, address: AddressIcon, 'arrow-white': ArrowWhiteIcon, @@ -45,6 +62,7 @@ const general = { attachment: AttachmentIcon, avatar: AvatarIcon, banner: BannerIcon, + 'blocked-account': BlockedAccountIcon, 'calendar-clock': CalendarClockIcon, 'calendar-month': CalendarMonthIcon, clip: ClipIcon, @@ -54,7 +72,9 @@ const general = { copied: CopiedIcon, copy: CopyIcon, delete: DeleteIcon, + document: DocumentIcon, done: DoneIcon, + download: DownloadIcon, edit: EditIcon, general: GeneralIcon, 'location-on': LocationOnIcon, @@ -62,17 +82,25 @@ const general = { logout: LogoutIcon, mapp: MappIcon, maximize: MaximizeIcon, + mic: MicIcon, minimize: MinimizeIcon, minus: MinusIcon, nickname: NicknameIcon, notification: NotificationIcon, + pause: PauseIcon, pen: PenIcon, 'person-edit': PersonEditIcon, + play: PlayIcon, 'profile-edit': ProfileEditIcon, profile: ProfileIcon, + reaction: ReactionIcon, + reply: ReplyIcon, + send: SendIcon, social: SocialIcon, + stop: StopIcon, 'trash-white': TrashWhiteIcon, trash: TrashIcon, + tune: TuneIcon, verifications: VerificationsIcon, wallet: WalletIcon, }; @@ -80,6 +108,9 @@ const general = { export { general, AddCircleIcon, + AddFolderIcon, + AddImageIcon, + AddVideoIcon, AddIcon, AddressIcon, ArrowWhiteIcon, @@ -87,6 +118,7 @@ export { AttachmentIcon, AvatarIcon, BannerIcon, + BlockedAccountIcon, CalendarClockIcon, CalendarMonthIcon, ClipIcon, @@ -96,7 +128,9 @@ export { CopiedIcon, CopyIcon, DeleteIcon, + DocumentIcon, DoneIcon, + DownloadIcon, EditIcon, GeneralIcon, LocationOnIcon, @@ -104,17 +138,25 @@ export { LogoutIcon, MappIcon, MaximizeIcon, + MicIcon, MinimizeIcon, MinusIcon, NicknameIcon, NotificationIcon, + PauseIcon, PenIcon, PersonEditIcon, + PlayIcon, ProfileEditIcon, ProfileIcon, + ReactionIcon, + ReplyIcon, + SendIcon, SocialIcon, + StopIcon, TrashWhiteIcon, TrashIcon, + TuneIcon, VerificationsIcon, WalletIcon, }; diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/add-folder.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/add-folder.svg new file mode 100644 index 00000000..08959924 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/add-folder.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/add-image.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/add-image.svg new file mode 100644 index 00000000..4498288e --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/add-image.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/add-video.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/add-video.svg new file mode 100644 index 00000000..45a14792 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/add-video.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/blocked-account.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/blocked-account.svg new file mode 100644 index 00000000..988ca9e5 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/blocked-account.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/document.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/document.svg new file mode 100644 index 00000000..24d822b3 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/document.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/download.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/download.svg new file mode 100644 index 00000000..f7b96a85 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/download.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/mic.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/mic.svg new file mode 100644 index 00000000..525e12fa --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/mic.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/pause.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/pause.svg new file mode 100644 index 00000000..67e47376 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/pause.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/play.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/play.svg new file mode 100644 index 00000000..46882629 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/play.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/reaction.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/reaction.svg new file mode 100644 index 00000000..e5fe7b0d --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/reaction.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/reply.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/reply.svg new file mode 100644 index 00000000..4bacd732 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/reply.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/send.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/send.svg new file mode 100644 index 00000000..98209eab --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/send.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/stop.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/stop.svg new file mode 100644 index 00000000..cf365a23 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/stop.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/icons/svgs/general/tune.svg b/packages/@justweb3/ui/src/lib/icons/svgs/general/tune.svg new file mode 100644 index 00000000..e1d5a083 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/icons/svgs/general/tune.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/@justweb3/ui/src/lib/ui/Skeleton/Skeleton.module.css b/packages/@justweb3/ui/src/lib/ui/Skeleton/Skeleton.module.css new file mode 100644 index 00000000..f027fdd2 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/ui/Skeleton/Skeleton.module.css @@ -0,0 +1,15 @@ +@keyframes pulse { + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } +} + +.skeleton { + animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; + border-radius: 0.375rem; + background-color: rgba(var(--jusstweb3-primary-color), 0.1); +} diff --git a/packages/@justweb3/ui/src/lib/ui/Skeleton/index.tsx b/packages/@justweb3/ui/src/lib/ui/Skeleton/index.tsx new file mode 100644 index 00000000..a5b8f068 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/ui/Skeleton/index.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import styles from './Skeleton.module.css'; + +const Skeleton = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className = '', ...props }, ref) => ( +
+)); + +Skeleton.displayName = 'Skeleton'; + +export { Skeleton }; diff --git a/packages/@justweb3/ui/src/lib/ui/index.ts b/packages/@justweb3/ui/src/lib/ui/index.ts index a47f5589..3cd6c64c 100644 --- a/packages/@justweb3/ui/src/lib/ui/index.ts +++ b/packages/@justweb3/ui/src/lib/ui/index.ts @@ -17,3 +17,4 @@ export * from './ToolTip'; export * from './Sheet'; export * from './Label'; export * from './Checkbox'; +export * from './Skeleton'; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx index 4ad6d2e7..a836bfff 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx @@ -1,16 +1,399 @@ +import { useEnsAvatar, useMountedAccount, usePrimaryName, useRecords } from '@justaname.id/react'; +import { ArrowIcon, Avatar, BlockedAccountIcon, Button, CloseIcon, Flex, LoadingSpinner, P, Popover, PopoverContent, PopoverTrigger, TuneIcon } from '@justweb3/ui'; import { CachedConversation, ContentTypeMetadata, + useCanMessage, + useClient, + useConsent, useMessages, + useStreamMessages } from '@xmtp/react-sdk'; +import React, { useEffect, useMemo } from 'react'; +import { useSendReactionMessage } from '../../hooks'; +import { filterReactionsMessages, MessageWithReaction } from '../../utils/filterReactionsMessages'; +import { formatAddress } from '../../utils/formatAddress'; +import { groupMessagesByDate } from '../../utils/groupMessageByDate'; +import MessageCard from '../MessageCard'; +import EmojiSelector from '../EmojiSelector'; +import MessageTextField from '../MessageTextField'; +import { MessageSkeletonCard } from '../MessageSkeletonCard'; export interface ChatProps { conversation: CachedConversation; + onBack: () => void; } -export const Chat: React.FC = ({ conversation }) => { - const { messages } = useMessages(conversation); +export const Chat: React.FC = ({ conversation, onBack }) => { + const [replyMessage, setReplyMessage] = React.useState(null); + const [reactionMessage, setReactionMessage] = React.useState(null); + const [emojiSelectorTop, setEmojiSelectorTop] = React.useState(0); + const [isRequest, setIsRequest] = React.useState(false); + const [isRequestChangeLoading, setIsRequestChangeLoading] = React.useState(false); + const { entries, allow, refreshConsentList, deny } = useConsent(); + const { mutateAsync: sendReaction } = useSendReactionMessage(conversation); - console.log(messages); - return null; + const { primaryName } = usePrimaryName({ + address: conversation.peerAddress as `0x${string}`, + }); + const { records } = useRecords({ + ens: primaryName, + }); + const { sanitizeEnsImage } = useEnsAvatar(); + + const { address } = useMountedAccount(); + const { client } = useClient(); + + const [canMessage, setCanMessage] = React.useState(true); + + const { messages, isLoading } = useMessages(conversation) + + + // Queries + + const blockAddress = async (peerAddress: string) => { + setIsRequestChangeLoading(true); + await refreshConsentList() + await deny([peerAddress]) + await refreshConsentList() + setIsRequestChangeLoading(false); + onBack(); + } + + + const { canMessage: canMessageFn, isLoading: isCanMessageLoading } = useCanMessage(); + + useEffect(() => { + if (isCanMessageLoading) return; + canMessageFn(conversation.peerAddress).then((result) => { + setCanMessage(result); + }) + }, [isCanMessageLoading, conversation, canMessageFn]) + + + useStreamMessages(conversation); + + console.log(messages) + + + // Memo + const filteredMessages = useMemo(() => { + const messagesWithoutRead = messages.filter((message) => !(message.contentType === "xmtp.org/readReceipt:1.0")); + console.log('messages without read', messagesWithoutRead) + const res = filterReactionsMessages(messagesWithoutRead); + return res; + }, [messages]); + + console.log("filtered msg", filteredMessages) + + const groupedMessages = useMemo(() => { + return groupMessagesByDate(filteredMessages ?? []); + }, [filteredMessages]); + + console.log("grouped messages", groupedMessages) + + + useEffect(() => { + const convoConsentState = entries[conversation.peerAddress]?.permissionType; + if (convoConsentState === 'unknown' || convoConsentState === undefined) { + setIsRequest(true); + } else { + setIsRequest(false); + } + }, [entries, conversation.peerAddress]); + + const isMessagesSenderOnly = useMemo(() => { + return filteredMessages.every((message) => message.senderAddress === address); + }, [filteredMessages, address]); + + + const handleAllowAddress = async () => { + setIsRequestChangeLoading(true); + await refreshConsentList() + await allow([conversation.peerAddress]) + void refreshConsentList() + // TODO: check if this is needed + // onRequestAllowed(); + setIsRequestChangeLoading(false); + } + + const handleEmojiSelect = (emoji: string) => { + if (!reactionMessage) return; + sendReaction({ + action: 'added', + content: emoji, + referenceId: reactionMessage.id, + }); + } + + useEffect(() => { + if (messages.length == 0) return; + setTimeout(() => { + const lastMessageId = messages[messages.length - 1]?.id; + const element = document.getElementById(lastMessageId); + if (element) { + element.scrollIntoView({ behavior: "smooth" }); + } + }, 500); + + // await checkMessageIfRead(); + + }, [messages, conversation]); + + + return ( + + +
{ + setReactionMessage(null); + const replica = document.getElementById(`${reactionMessage?.id}-replica`); + replica?.remove(); + }} + >
+ + + + + + +

{primaryName ? primaryName : formatAddress(conversation.peerAddress)}

+ {(!!primaryName) && ( +

{formatAddress(conversation.peerAddress)}

+ )} +
+
+
+ + + + + + + + blockAddress(conversation.peerAddress)} > +

Block

+ +
+
+
+
+
+
+
+ { + isCanMessageLoading || isLoading ? ( + + {[...Array(5)].map((_, index) => ( + + ))} + + ) : ( + + {canMessage ? ( + + {groupedMessages && Object.keys(groupedMessages).map((date, index) => ( + +

{date}

+ {groupedMessages[date].map((message) => + setReplyMessage(msg)} + message={message} + peerAddress={conversation.peerAddress} + key={`message-${message.id}`} + onReaction={(message) => { + setReactionMessage(message); + + const element = document.getElementById(message.id.toString()); + if (!element) return; + const replica = element?.cloneNode(true) as HTMLElement; + replica.id = `${message.id}-replica`; + replica.style.position = 'absolute'; + replica.style.top = element?.offsetTop + 'px'; + replica.style.top = '100px'; + replica.style.zIndex = '90'; + element?.parentElement?.appendChild(replica); + replica.classList.add('replica-animate'); + setEmojiSelectorTop(100 + element.getBoundingClientRect().height); + }} + /> + )} +
+ ))} + { + reactionMessage && ( +
+ { + handleEmojiSelect(emoji); + setReactionMessage(null); + const replica = document.getElementById(`${reactionMessage?.id}-replica`); + replica?.remove(); + }} + + /> +
+ ) + } +
+ ) : ( +
+

Cannot message {conversation.peerAddress}

+
+ )} +
+ ) + } + + {isRequest ? ( + isRequestChangeLoading ? + + + + : + + + + + ) : ( + + {isMessagesSenderOnly && ( + +

Message in user’s Requests

+

This user has not accepted your message request yet

+
+ )} + setReplyMessage(null)} conversation={conversation} replyMessage={replyMessage} /> +
+ )} + + ); }; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/CustomPlayer/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/CustomPlayer/index.tsx new file mode 100644 index 00000000..32af76c1 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/CustomPlayer/index.tsx @@ -0,0 +1,95 @@ +import { Flex, PauseIcon, PlayIcon } from '@justweb3/ui'; +import React, { useEffect, useRef, useState } from 'react'; + + +export interface CustomPlayerProps { + style?: React.CSSProperties; + url?: string; + disabled?: boolean; +} + +export const CustomPlayer: React.FC = ({ + style, + url = '', + disabled +}) => { + const [playing, setPlaying] = React.useState(false); + const videoRef = useRef(null); + const [hovered, setHovered] = useState(false) + + const togglePlay = () => { + if (disabled) return; + if (videoRef.current) { + if (playing) { + videoRef.current.pause(); + } else { + videoRef.current.play(); + } + setPlaying(!playing); + } + }; + + useEffect(() => { + const handleVisibilityChange = () => { + if (document.hidden && playing && videoRef.current) { + videoRef.current.pause(); + } + }; + document.addEventListener('visibilitychange', handleVisibilityChange); + return () => { + document.removeEventListener('visibilitychange', handleVisibilityChange); + if (videoRef.current && playing) { + videoRef.current.pause(); + setPlaying(false); + } + }; + }, [playing]); + + return ( + { setHovered(true) }} + onMouseLeave={() => { setHovered(false) }} + onClick={togglePlay} + style={{ + aspectRatio: '16/9', + position: 'relative', + // TODO: check background color + background: 'var(--justweb3-background-color)', + cursor: 'pointer', + borderRadius: '10px', + border: '1px solid var(--justweb3-primary-color)', + ...style + }}> + + ); +} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/CustomVoicePreview/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/CustomVoicePreview/index.tsx new file mode 100644 index 00000000..49e12de3 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/CustomVoicePreview/index.tsx @@ -0,0 +1,89 @@ +import { Flex, P, PauseIcon, PlayIcon, CloseIcon } from '@justweb3/ui'; +import { formatTime } from '../../utils/formatVoiceTime'; +import React, { useEffect, useRef, useState } from 'react'; +import useGetAudioDuration from '../../hooks/useGetAudioDuration'; + + +interface CustomVoicePreviewProps { + audioUrl: string; + onCancel: () => void; +} + +const CustomVoicePreview: React.FC = ({ + audioUrl, + onCancel +}) => { + const [playing, setPlaying] = useState(false); + const [currentTime, setCurrentTime] = useState(0); + const audioRef = useRef(new Audio()); + + const audioDuration = useGetAudioDuration(audioUrl); + + useEffect(() => { + const audio = new Audio(); + audioRef.current = audio; + + const onTimeUpdate = () => { + setCurrentTime(audio.currentTime); + }; + + const onEnded = () => { + setPlaying(false); + setCurrentTime(0); + }; + + audio.src = audioUrl; + audio.addEventListener('timeupdate', onTimeUpdate); + audio.addEventListener('ended', onEnded); + + return () => { + audio.removeEventListener('timeupdate', onTimeUpdate); + audio.removeEventListener('ended', onEnded); + }; + }, [audioUrl]); + + const handlePlayPause = () => { + const audio = audioRef.current; + if (!audio) return; + + if (playing) { + audio.pause(); + } else { + audio.play(); + } + setPlaying(!playing); + }; + + return ( + + {playing ? + + : + + } +

{playing || currentTime > 0 ? formatTime(currentTime) : formatTime(audioDuration ?? 0)}

+ +
+ ); +}; + +export default CustomVoicePreview; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/EmojiSelector/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/EmojiSelector/index.tsx new file mode 100644 index 00000000..f39022f8 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/EmojiSelector/index.tsx @@ -0,0 +1,80 @@ +import { Flex, Input } from '@justweb3/ui'; +import React, { useMemo } from 'react'; +import { EmojiObject, emojis } from '../../utils/emojis'; +import { useDebounced } from '../../hooks'; + + +interface EmojiSelectorProps { + onEmojiSelect: (emoji: string) => void; +} + +const EmojiSelector: React.FC = ({ + onEmojiSelect, +}) => { + const [searchValue, setSearchValue] = React.useState(""); + + const { + value: debouncedSearch, + } = useDebounced(searchValue, 50); + + const onEmojiClickHandler = (emoji: EmojiObject) => { + onEmojiSelect(emoji.name); + + } + + const filteredEmojis = useMemo(() => { + if (debouncedSearch.length === 0) return emojis; + const filteredEmojis = emojis.filter(emoji => + emoji.name.toLowerCase().includes(debouncedSearch.toLowerCase()) + ); + return filteredEmojis; + }, [debouncedSearch]); + + + return ( + + setSearchValue(e.target.value)} + /> +
+ {filteredEmojis.map((emoji, index) => ( + + ))} +
+
+ + ); +}; + +export default EmojiSelector; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx new file mode 100644 index 00000000..c653ed11 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx @@ -0,0 +1,415 @@ +import { useEffect, useMemo, useRef } from "react"; +import { CachedConversation, DecodedMessage } from "@xmtp/react-sdk"; +import { MessageWithReaction } from "../../utils/filterReactionsMessages"; +import { useState } from "react"; +import { useMountedAccount } from "@justaname.id/react"; +import React from "react"; +import { useSendReactionMessage } from "../../hooks"; +import { typeLookup } from "../../utils/attachments"; +import { findEmojiByName } from "../../utils/emojis"; +import { formatMessageSentTime } from "../../utils/messageTimeFormat"; +import { DocumentIcon, Flex, P, ReplyIcon, ReactionIcon, DownloadIcon } from "@justweb3/ui"; +import { formatAddress } from "../../utils/formatAddress"; +import { calculateFileSize } from "../../utils/calculateFileSize"; +import VoiceMessageCard from "../VoiceMessageCard"; +import { CustomPlayer } from "../CustomPlayer"; + + +interface MessageCardProps { + message: MessageWithReaction; + conversation: CachedConversation; + peerAddress: string; + // onReply: (message: DecodedMessage) => void; + // onReaction: (message: DecodedMessage) => void; + onReply: (message: MessageWithReaction) => void; + onReaction: (message: MessageWithReaction) => void; +} + +const MeasureAndHyphenateText: React.FC<{ text: string; maxWidth: number }> = ({ text, maxWidth }) => { + const [processedText, setProcessedText] = useState(''); + + useEffect(() => { + // Function to measure text width + const measureText = (text = '', font = '16px Arial') => { + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + if (!context) return 0; + context.font = font; + return context.measureText(text).width; + }; + + // Function to insert hyphens + const insertHyphens = (text: string) => { + const words = text.split(' '); + let currentLine = ''; + let finalText = ''; + + words.forEach((word) => { + const testLine = currentLine + word + ' '; + const testLineWidth = measureText(testLine); + + if (testLineWidth > maxWidth && currentLine !== '') { + // Check if it's necessary to hyphenate the current word + let hyphenated = false; + for (let i = word.length; i > 0; i--) { + const part = word.substring(0, i); + const testPartWidth = measureText(currentLine + part + '-'); + + if (testPartWidth <= maxWidth) { + finalText += currentLine + part + '-\n'; + currentLine = word.substring(i) + ' '; + hyphenated = true; + break; + } + } + + if (!hyphenated) { + finalText += currentLine + '\n'; + currentLine = word + ' '; + } + } else { + currentLine = testLine; + } + }); + + finalText += currentLine; + return finalText; + }; + + // Process the text + const processed = insertHyphens(text); + setProcessedText(processed); + }, [text, maxWidth]); + + return ( +
+            {processedText}
+        
+ ); +}; + +const MessageCard: React.FC = ({ + message, + peerAddress, + onReply, + conversation, + onReaction +}) => { + const { address } = useMountedAccount(); + const [repliedMessage, setRepliedMessage] = React.useState(null); + const divRef = useRef(null); + const { mutateAsync: sendReaction } = useSendReactionMessage(conversation); + + const isText = useMemo(() => { + return typeof message.content === "string" + }, [message.content]) + + + const attachmentExtention = useMemo(() => { + if (!isText && message.content.mimeType) + return message.content.mimeType.split("/")?.[1] || ""; + }, [isText, message.content.mimeType]); + + + const isImage = message.content && message.content.data; + const isReply = message.content && message.contentType === "xmtp.org/reply:1.0" + const isReceiver = message.senderAddress === peerAddress; + const isVoice = message.content.mimeType === "audio/wav"; + + + const getMessageDataById = (messageId: string) => { + const messageElement = document.getElementById(messageId); + if (!messageElement) { + return null; + } + + const messageDataString = messageElement.getAttribute('data-message'); + if (!messageDataString) { + return null; + } + try { + const messageData = JSON.parse(messageDataString); + return messageData; + } catch (e) { + console.error('Failed to parse message data:', e); + return null; + } + } + + const handleEmojiSelect = (emoji: string, action: "added" | "removed") => { + sendReaction({ + action: action, + content: emoji, + referenceId: message.id, + }); + } + + const navigateToRepliedMessage = () => { + if (!repliedMessage) return; + const element = document.getElementById(repliedMessage.id); + if (element) { + element.scrollIntoView({ behavior: "smooth" }); + } + } + + + const isReplyVoice = useMemo(() => { + if (!repliedMessage) return false; + return repliedMessage.content.mimeType === "audio/wav"; + }, [repliedMessage]); + + const isReplyText = useMemo(() => { + if (!repliedMessage) return false; + return typeof repliedMessage.content === "string" + }, [repliedMessage]) + + const isReplyReply = useMemo(() => { + if (!repliedMessage) return false; + return !!repliedMessage.content.reference + }, [repliedMessage]) + + const replyAttachmentExtention = useMemo(() => { + if (!isReplyText && !!repliedMessage && !isReplyReply) + return repliedMessage.content.mimeType.split("/")?.[1] || ""; + }, [isReplyText, repliedMessage]); + + useEffect(() => { + if (!isReply || !!repliedMessage) return; + const repliedMsg = getMessageDataById(message.content.reference) + setRepliedMessage(repliedMsg); + }, [isReply, message.content.reference, repliedMessage]) + + return ( + + + + <> + { + repliedMessage && isReply ? + + + + +

{repliedMessage?.senderAddress === address ? "YOU" : formatAddress(repliedMessage?.senderAddress ?? "")}

+ + {(isReplyText || isReplyReply) ? ( +

{isReplyReply ? repliedMessage.content.content : repliedMessage.content}

+ ) : ( + isReplyVoice ? + + : + typeLookup[replyAttachmentExtention] === "image" ? + {repliedMessage.content.filename} + : + typeLookup[replyAttachmentExtention] === "video" ? + + : + + +

{repliedMessage.content.filename}

+
+ )} +
+
+
+

{message.content.content}

+
+
+
+ : + isText ? + + + + : + + {isVoice ? + + : + + {typeLookup[attachmentExtention] === "image" ? + {message.content.filename} + : + typeLookup[attachmentExtention] === "video" ? + + : + + + +

{message.content.filename}

+

{calculateFileSize(message.content.data?.byteLength ?? 0)}

+
+
} + + +
} +
+ } + {message.reactionMessage && ( +

{ + if (!message.reactionMessage) return; + if (message.reactionMessage.senderAddress !== address) return; + handleEmojiSelect("", "removed") + }} + style={{ + position: 'absolute', + cursor: 'pointer', + bottom: '-1rem', + fontSize: '20px', + right: isReceiver ? '-12px' : 'auto', + left: isReceiver ? 'auto' : '-12px', + }} + >{findEmojiByName(message.reactionMessage.content.content)}

+ )} + +
+ + onReply(message)} /> + + {message.senderAddress !== address && + { + onReaction(message) + } + } /> + } + + +
+

{formatMessageSentTime(message.sentAt)}

+
+ ); +}; + +export default MessageCard; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx index 1f13604a..da02d3ac 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx @@ -1,5 +1,5 @@ import { CachedConversation, ContentTypeMetadata } from '@xmtp/react-sdk'; -import { Sheet, SheetContent } from '@justweb3/ui'; +import { Sheet, SheetContent, SheetTitle } from '@justweb3/ui'; import { Chat } from '../Chat'; export interface MessageSheetProps { @@ -21,8 +21,8 @@ export const MessageSheet: React.FC = ({ onOpenChange={(open) => !open && handleOpenChat(null)} > - Messages - {conversation && } + Messages + {conversation && handleOpenChat(null)} />} ); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSkeletonCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSkeletonCard/index.tsx new file mode 100644 index 00000000..0b18023f --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSkeletonCard/index.tsx @@ -0,0 +1,37 @@ +import { Skeleton, Flex } from '@justweb3/ui'; + +interface MessageSkeletonCardProps { + isReceiver: boolean; +} + +export const MessageSkeletonCard: React.FC = ({ isReceiver }) => { + return ( + + + + + ) +} \ No newline at end of file diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx new file mode 100644 index 00000000..244a9fe4 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx @@ -0,0 +1,459 @@ + +import type { Attachment } from '@xmtp/content-type-remote-attachment'; +import { CachedConversation, useClient } from '@xmtp/react-sdk'; +import React, { Dispatch, SetStateAction, useEffect, useMemo, useRef, useState } from 'react'; +import { MessageWithReaction } from '../../utils/filterReactionsMessages'; +import { useMountedAccount } from '@justaname.id/react'; +import { useAttachmentChange, useRecordingTimer, useRecordVoice, useSendAttachment, useSendMessages, useSendReplyMessage } from '../../hooks'; +import { AttachmentType, typeLookup } from '../../utils/attachments'; +import { Button, CloseIcon, Flex, Input, LoadingSpinner, P, AddImageIcon, AddVideoIcon, AddFolderIcon, DocumentIcon, SendIcon, StopIcon, MicIcon } from '@justweb3/ui'; +import { formatAddress } from '../../utils/formatAddress'; +import VoiceMessageCard from '../VoiceMessageCard'; +import { CustomPlayer } from '../CustomPlayer'; +import CustomVoicePreview from '../CustomVoicePreview'; + + +interface MessageTextFieldProps { + newConvo?: boolean; + disabled?: boolean; + conversation?: CachedConversation; + replyMessage?: MessageWithReaction | null; + onCancelReply?: () => void; + onNewConvo?: (message: string) => void; +} + +const MessageTextField: React.FC = ({ + newConvo, + disabled, + replyMessage, + onCancelReply, + conversation, + onNewConvo +}) => { + const [messageValue, setMessageValue] = React.useState(""); + const [attachment, setAttachment] = React.useState(); + const [attachmentPreview, setAttachmentPreview] = React.useState(); + const [isNewMessageLoading, setIsNewMessageLoading] = React.useState(false); + // const [selectingAttachment, setSelectingAttachment] = React.useState(false); + const { client } = useClient(); + const { address } = useMountedAccount(); + const { mutateAsync: sendMessage } = useSendMessages(conversation); + const { mutateAsync: sendReply } = useSendReplyMessage(conversation); + const { mutateAsync: sendAttachment } = useSendAttachment(conversation); + + const attachmentExtention = useMemo(() => { + return attachment?.mimeType.split("/")?.[1] || ""; + }, [attachment]); + + + // Attachments + const [acceptedTypes, setAcceptedTypes]: [ + string | string[] | undefined, + Dispatch>, + ] = useState(); + const inputFile = useRef(null); + const { onAttachmentChange } = useAttachmentChange({ + setAttachment, + setAttachmentPreview, + onError: (error) => { + // showToast("error", error); + } + }); + + // Recording + const { recording, startRecording, stopRecording } = useRecordVoice({ + setAttachment, + setAttachmentPreview, + }) + const { start, pause, reset, recordingValue } = useRecordingTimer({ + stopRecording, + status: recording ? "recording" : "idle", + }); + + // Sending text message + const handleSendMessage = async () => { + if (messageValue.length === 0) return; + if (!client) return; + if (disabled) return; + if (newConvo) { + setIsNewMessageLoading(true); + onNewConvo && onNewConvo(messageValue); + setIsNewMessageLoading(false); + } else { + if (replyMessage) { + sendReply({ + message: messageValue, + referenceId: replyMessage.id, + }) + onCancelReply && onCancelReply(); + } else { + sendMessage(messageValue); + } + } + setMessageValue(''); + } + + // Sending attachment + const handleSendAttachment = async () => { + if (!client) return; + if (!attachment) return; + if (disabled) return; + if (newConvo) { + onNewConvo && onNewConvo(messageValue); + } else { + sendAttachment(attachment); + } + setMessageValue(''); + setAttachment(undefined); + setAttachmentPreview(undefined); + // setSelectingAttachment(false); + } + + const handleCancelAttachment = () => { + setAttachment(undefined); + setAttachmentPreview(undefined); + } + + const onButtonClick = (contentType: AttachmentType) => { + if (contentType === "application") { + setAcceptedTypes("all"); + } else { + const acceptedFileTypeList = Object.keys(typeLookup).reduce( + (acc: string[], key: string) => { + if (typeLookup[key] === contentType) acc.push(`.${key}`); + return acc; + }, + [], + ); + setAcceptedTypes([...acceptedFileTypeList]); + } + }; + + // Reply message + const isSender = useMemo(() => { return address === replyMessage?.senderAddress }, [replyMessage, address]); + const isReplyVoice = useMemo(() => { + return replyMessage?.content.mimeType === "audio/wav"; + }, [replyMessage]); + + const isReplyText = useMemo(() => { + if (!replyMessage) return false; + return typeof replyMessage.content === "string" + }, [replyMessage]) + + const isReplyReply = useMemo(() => { + if (!replyMessage) return false; + return !!replyMessage.content.reference; + }, [replyMessage]); + + const replyAttachmentExtention = useMemo(() => { + if (!isReplyText && !!replyMessage && !isReplyReply) + return replyMessage.content.mimeType.split("/")?.[1] || ""; + }, [isReplyText, replyMessage, isReplyReply]); + + const navigateToRepliedMessage = () => { + if (!replyMessage) return; + const element = document.getElementById(replyMessage.id.toString()); + if (element) { + element.scrollIntoView({ + block: "end", + behavior: "smooth" + }); + } + } + + useEffect(() => { + if (acceptedTypes) { + inputFile?.current?.click(); + } + }, [acceptedTypes]); + + const isReplyVideoOrImage = useMemo(() => { + return typeLookup[replyAttachmentExtention] === "image" || typeLookup[replyAttachmentExtention] === "video"; + }, [replyAttachmentExtention]); + + return ( + + {!replyMessage} + {!newConvo && ( + + onButtonClick("image")} style={{ + cursor: 'pointer' + }} /> + onButtonClick("video")} style={{ + cursor: 'pointer' + }} /> + onButtonClick("application")} style={{ + cursor: 'pointer' + }} /> + + + )} +
+ {replyMessage && ( + + +

{isSender ? "YOU" : formatAddress(replyMessage.senderAddress)}

+ {(isReplyText || isReplyReply) ? ( +

{isReplyReply ? replyMessage.content.content : replyMessage.content}

+ ) : ( + isReplyVoice ? + + : + typeLookup[replyAttachmentExtention] === "image" ? + {replyMessage.content.filename} + : + typeLookup[replyAttachmentExtention] === "video" ? + + : + + +

{replyMessage.content.filename}

+
+ )} +
+ +
+ ) + } + { + attachmentPreview ? ( + + {attachment?.mimeType === "audio/wav" ? + + : + + {typeLookup[attachmentExtention] === "image" ? + {attachment?.filename} + : typeLookup[attachmentExtention] === "video" ? + + : + + +

{attachment?.filename ?? "Cannot preview"}

+
+ } + + + + +
+ } + { + if (disabled) return; + handleSendAttachment() + }} + /> +
+ ) : ( + recording ? ( + +

+ {recordingValue} +

+

RECORDING...

+ { + stopRecording(); + pause(); + reset(); + }} /> +
+ ) : ( + isNewMessageLoading ? + + + + : + { + if (disabled) return; + startRecording(); + start(); + }} />)} + right={ + { + if (disabled) return; + handleSendMessage() + }} + /> + } + disabled={disabled} + onKeyDown={(e) => { + if (e.key === "Enter") { + handleSendMessage(); + } + }} + onChange={(e) => setMessageValue(e.target.value)} + /> + ) + ) + } +
+
+ ); +}; + +export default MessageTextField; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx new file mode 100644 index 00000000..1739b43f --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx @@ -0,0 +1,145 @@ +import * as Slider from '@radix-ui/react-slider'; +import { DecodedMessage } from '@xmtp/xmtp-js'; +import { Flex, P, PauseIcon, PlayIcon } from '@justweb3/ui'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { MessageWithReaction } from '../../utils/filterReactionsMessages'; +import useGetAudioDuration from '../../hooks/useGetAudioDuration'; +import { formatTime } from '../../utils/formatVoiceTime'; + + +interface VoiceMessageCardProps { + message: MessageWithReaction | DecodedMessage; + style?: React.CSSProperties; + disabled?: boolean; +} + +const VoiceMessageCard: React.FC = ({ + message, + style, + disabled +}) => { + const [playing, setPlaying] = useState(false); + const [currentTime, setCurrentTime] = useState(0); + const audioRef = useRef(new Audio()); + + + const audioUrl = useMemo(() => { + const blob = new Blob([message.content.data], { type: message.content.mimeType }); + return URL.createObjectURL(blob); + }, [message.content]); + + const duration = useGetAudioDuration(audioUrl); + + useEffect(() => { + const audio = audioRef.current; + + const onTimeUpdate = () => { + setCurrentTime(audio.currentTime); + }; + + const onEnded = () => { + setPlaying(false); + setCurrentTime(0); + }; + + audio.src = audioUrl; + audio.preload = 'metadata'; + audio.addEventListener('timeupdate', onTimeUpdate); + audio.addEventListener('ended', onEnded); + + return () => { + audio.removeEventListener('timeupdate', onTimeUpdate); + audio.removeEventListener('ended', onEnded); + }; + }, [message.content, audioUrl]); + + + const handlePlayPause = () => { + if (disabled) return; + const audio = audioRef.current; + if (playing) { + audio.pause(); + } else { + audio.play(); + } + setPlaying(!playing); + }; + + const handleSliderChange = (value: number[]) => { + const audio = audioRef.current; + if (playing) { + audio.pause(); + setPlaying(false); + audio.currentTime = value[0]; + setCurrentTime(value[0]); + audio.play(); + setPlaying(true); + } else { + audio.currentTime = value[0]; + setCurrentTime(value[0]); + } + }; + + return ( + + {playing ? ( + + ) : ( + + )} + +

{playing || currentTime > 0 ? formatTime(currentTime) : formatTime(duration ?? 0)}

+ 0 ? audioRef.current.currentTime : 0]} max={duration ?? 0} step={0.01}> + + + + + +
+
+ ); +}; + +export default VoiceMessageCard; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts new file mode 100644 index 00000000..f61e9449 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts @@ -0,0 +1,8 @@ +export * from './sendAttachment'; +export * from './sendMessage'; +export * from './sendReactionMessage'; +export * from './sendReplyMessage'; +export * from './useAttachmentChange'; +export * from './useDebounced'; +export * from './useRecordingTimer'; +export * from './useVoiceRecording'; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendAttachment/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendAttachment/index.ts new file mode 100644 index 00000000..a39b4c82 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendAttachment/index.ts @@ -0,0 +1,38 @@ +import { useMutation } from '@tanstack/react-query'; +import { ContentTypeId } from '@xmtp/content-type-primitives'; +import type { Attachment } from '@xmtp/content-type-remote-attachment'; +import { ContentTypeAttachment } from '@xmtp/content-type-remote-attachment'; +import { + CachedConversation, + useSendMessage, + SendOptions, + DecodedMessage, +} from '@xmtp/react-sdk'; + +export const sendAttachment = async ( + conversation: CachedConversation, + attachment: Attachment, + sendMessage: ( + conversation: CachedConversation, + content: T, + contentType?: ContentTypeId, + sendOptions?: Omit + ) => Promise | undefined> +) => { + try { + await sendMessage(conversation, attachment, ContentTypeAttachment); + } catch (e) { + const error = e as Error; + } +}; + +export const useSendAttachment = (conversation?: CachedConversation) => { + const { sendMessage } = useSendMessage(); + + return useMutation({ + mutationFn: (attachment: Attachment) => { + if (!conversation) throw new Error('Conversation not found'); + return sendAttachment(conversation, attachment, sendMessage); + }, + }); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendMessage/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendMessage/index.ts new file mode 100644 index 00000000..4a89f1d9 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendMessage/index.ts @@ -0,0 +1,33 @@ +import { useMutation } from '@tanstack/react-query' +import { ContentTypeId } from '@xmtp/content-type-primitives' +import { + CachedConversation, + useSendMessage, + DecodedMessage, + SendOptions, +} from '@xmtp/react-sdk' + +export const sendMessages = async ( + conversation: CachedConversation, + message: string, + sendMessage: ( + conversation: CachedConversation, + content: T, + contentType?: ContentTypeId, + sendOptions?: Omit, + ) => Promise | undefined>, + contentType?: SendOptions, +) => { + await sendMessage(conversation, message, undefined, contentType) +} + +export const useSendMessages = (conversation?: CachedConversation) => { + const { sendMessage } = useSendMessage() + + return useMutation({ + mutationFn: (message: string, contentType?: SendOptions) => { + if (!conversation) throw new Error('Conversation not found') + return sendMessages(conversation, message, sendMessage, contentType) + }, + }) +} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendReactionMessage/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendReactionMessage/index.ts new file mode 100644 index 00000000..005c32b0 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendReactionMessage/index.ts @@ -0,0 +1,57 @@ +import { useMutation } from '@tanstack/react-query'; +import { ContentTypeId } from '@xmtp/content-type-primitives'; +import { ContentTypeReaction, Reaction } from '@xmtp/content-type-reaction'; +import { + CachedConversation, + DecodedMessage, + SendOptions, + useSendMessage, +} from '@xmtp/react-sdk'; + +export const sendReactionMessage = async ( + conversation: CachedConversation, + action: 'added' | 'removed', + content: string, + referenceId: string, + sendMessage: ( + conversation: CachedConversation, + content: T, + contentType?: ContentTypeId, + sendOptions?: Omit + ) => Promise | undefined> +) => { + const reaction: Reaction = { + reference: referenceId, + action: action, + content: content, + schema: 'custom', + }; + return await sendMessage(conversation, reaction, ContentTypeReaction); +}; + +type SendReactionMessageParams = { + action: 'added' | 'removed'; + content: string; + referenceId: string; +}; + +export const useSendReactionMessage = (conversation?: CachedConversation) => { + const { sendMessage } = useSendMessage(); + + return useMutation({ + mutationFn: ({ + action, + referenceId, + content, + }: SendReactionMessageParams) => { + if (!conversation) throw new Error('Conversation not found'); + return sendReactionMessage( + conversation, + action, + content, + referenceId, + sendMessage + ); + }, + }); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendReplyMessage/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendReplyMessage/index.ts new file mode 100644 index 00000000..a979f3f1 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendReplyMessage/index.ts @@ -0,0 +1,50 @@ +import { useMutation } from '@tanstack/react-query' +import { ContentTypeId } from '@xmtp/content-type-primitives' +import { ContentTypeReply, Reply } from '@xmtp/content-type-reply' +import { ContentTypeText } from '@xmtp/content-type-text' +import { + CachedConversation, + useSendMessage, + DecodedMessage, + SendOptions, +} from '@xmtp/react-sdk' + +export const sendReplyMessage = async ( + conversation: CachedConversation, + message: string, + referenceId: string, + sendMessage: ( + conversation: CachedConversation, + content: T, + contentType?: ContentTypeId, + sendOptions?: Omit, + ) => Promise | undefined>, +) => { + const reply: Reply = { + reference: referenceId, + contentType: ContentTypeText, + content: message, + } + return await sendMessage(conversation, reply, ContentTypeReply) +} + +type SendReplyMessageParams = { + message: string + referenceId: string +} + +export const useSendReplyMessage = (conversation?: CachedConversation) => { + const { sendMessage } = useSendMessage() + + return useMutation({ + mutationFn: ({ message, referenceId }: SendReplyMessageParams) => { + if (!conversation) throw new Error('Conversation not found') + return sendReplyMessage( + conversation, + message, + referenceId, + sendMessage, + ) + }, + }) +} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useAttachmentChange/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useAttachmentChange/index.tsx new file mode 100644 index 00000000..5c21a8d7 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useAttachmentChange/index.tsx @@ -0,0 +1,79 @@ +import type { Attachment } from "@xmtp/content-type-remote-attachment"; +import type { ChangeEvent } from "react"; +import { useCallback } from "react"; + +interface useAttachmentChangeProps { + setAttachment: (attachment: Attachment | undefined) => void; + setAttachmentPreview: (url: string | undefined) => void; + // setIsDragActive: (status: boolean) => void; + onError?: (error: string) => void; +} + +export const MAX_FILE_SIZE = 1 * 1024 * 1024; + +export const useAttachmentChange = ({ + setAttachment, + setAttachmentPreview, + // setIsDragActive, + onError, +}: useAttachmentChangeProps) => { + const onAttachmentChange = useCallback( + (e: ChangeEvent | React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + + const target = (e as ChangeEvent)?.target.files + ? (e as ChangeEvent)?.target + // TODO: if drag feature is needed, uncomment this line + // : (e as React.DragEvent)?.dataTransfer.files + // ? (e as React.DragEvent).dataTransfer + : undefined; + + if (target?.files?.length && setAttachment) { + const file = target.files[0]; + + if (file.size > MAX_FILE_SIZE) { + onError && onError("File too large!"); + // setIsDragActive(false); + } else { + const fileReader = new FileReader(); + fileReader.addEventListener("load", () => { + const data = fileReader.result; + + if (!(data instanceof ArrayBuffer)) { + return; + } + + const attachment: Attachment = { + filename: file.name, + mimeType: file.type, + data: new Uint8Array(data), + }; + + setAttachmentPreview( + URL.createObjectURL( + new Blob([Buffer.from(data)], { + type: attachment.mimeType, + }), + ), + ); + + setAttachment(attachment); + }); + + fileReader.readAsArrayBuffer(file); + (e as ChangeEvent).target.value = ""; + } + } else { + setAttachment(undefined); + setAttachmentPreview(undefined); + } + // setIsDragActive(false); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [setAttachment, setAttachmentPreview, onError], + ); + return { + onAttachmentChange, + }; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useDebounced/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useDebounced/index.ts new file mode 100644 index 00000000..d19ba15b --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useDebounced/index.ts @@ -0,0 +1,36 @@ +import { useEffect, useRef, useState } from 'react'; + +export const useDebounced = ( + value: T, + delay: number +): { value: T; isDebouncing: boolean } => { + const [debouncedValue, setDebouncedValue] = useState(value); + const [isDebouncing, setIsDebouncing] = useState(false); + const firstUpdate = useRef(true); + const prevValue = useRef(value); + + useEffect(() => { + if (firstUpdate.current || prevValue.current === value) { + firstUpdate.current = false; + prevValue.current = value; + return; + } + + setIsDebouncing(true); + const handler = setTimeout(() => { + setDebouncedValue(value); + setIsDebouncing(false); + }, delay); + + prevValue.current = value; + + return () => { + clearTimeout(handler); + }; + }, [value, delay]); + + return { + value: debouncedValue, + isDebouncing, + }; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useGetAudioDuration/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useGetAudioDuration/index.tsx new file mode 100644 index 00000000..ce7dc3c6 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useGetAudioDuration/index.tsx @@ -0,0 +1,41 @@ +import { useEffect, useState } from 'react'; + +const useGetAudioDuration = (url: string) => { + const [duration, setDuration] = useState(null); + + useEffect(() => { + if (!url) { + setDuration(null); + return; + } + + const getDuration = (url: string, next: (duration: number) => void) => { + const _player = new Audio(url); + const durationChangeHandler = function (this: HTMLAudioElement, e: Event) { + if (this.duration !== Infinity) { + const duration = this.duration; + _player.remove(); // Cleanup + next(duration); + } + }; + + _player.addEventListener('durationchange', durationChangeHandler, false); + _player.load(); + _player.currentTime = 24 * 60 * 60; + _player.volume = 0; + }; + + getDuration(url, (duration: number) => { + setDuration(duration); + }); + + return () => { + const _player = new Audio(url); + _player.remove(); + }; + }, [url]); + + return duration; +}; + +export default useGetAudioDuration; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useRecordingTimer/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useRecordingTimer/index.tsx new file mode 100644 index 00000000..bb41996e --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useRecordingTimer/index.tsx @@ -0,0 +1,46 @@ +import { useEffect } from "react"; +import type { StatusMessages } from "react-media-recorder-2"; +import { useStopwatch } from "react-timer-hook"; +import { getRecordingValue } from "../../utils/recordingValue"; + +interface useRecordingTimerProps { + stopRecording: () => void; + status: StatusMessages; +} + +export const useRecordingTimer = ({ + stopRecording, + status, +}: useRecordingTimerProps) => { + + const { start, pause, minutes, seconds, reset } = useStopwatch({ + autoStart: false, + }); + + useEffect(() => { + if (minutes === 10) { + stopRecording(); + pause(); + } + }, [stopRecording, pause, minutes]); + + useEffect(() => { + if (status === "idle") { + reset(); + pause(); + } + }, [status, pause, reset]) + + const recordingValue = getRecordingValue( + status, + minutes, + seconds, + ); + + return { + start, + pause, + reset, + recordingValue, + }; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useVoiceRecording/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useVoiceRecording/index.tsx new file mode 100644 index 00000000..474b3782 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useVoiceRecording/index.tsx @@ -0,0 +1,96 @@ +import type { Attachment } from "@xmtp/content-type-remote-attachment"; +import { useRef, useState } from "react"; + +interface useVoiceRecordingProps { + setAttachment: (attachment: Attachment | undefined) => void; + setAttachmentPreview: (url: string | undefined) => void; + onError?: (error: string) => void; +} + +export const useRecordVoice = ({ setAttachment, setAttachmentPreview, onError }: useVoiceRecordingProps) => { + const [mediaRecorder, setMediaRecorder] = useState(null); + const [mediaStream, setMediaStream] = useState(null); + const [recording, setRecording] = useState(false); + const chunks = useRef([]); + + const stopMediaStream = () => { + if (mediaStream) { + mediaStream.getTracks().forEach(track => track.stop()); + setMediaStream(null); + } + }; + + const startRecording = async () => { + if (!mediaStream) { + try { + const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); + setMediaStream(stream); + const newMediaRecorder = new MediaRecorder(stream); + + newMediaRecorder.onstart = () => { + chunks.current = []; + }; + + newMediaRecorder.ondataavailable = (ev) => { + chunks.current.push(ev.data); + }; + + newMediaRecorder.onstop = async () => { + const audioBlob = new Blob(chunks.current, { type: "audio/wav" }); + const blobUrl = URL.createObjectURL(audioBlob); + setAttachmentPreview(blobUrl); + + const arrayBuffer = await audioBlob.arrayBuffer(); + const uint8Array = new Uint8Array(arrayBuffer); + + const newAttachment = { + filename: "VoiceRecording.wav", + mimeType: "audio/wav", + data: uint8Array, + }; + setAttachment(newAttachment); + }; + + setMediaRecorder(newMediaRecorder); + setTimeout(() => { + try { + newMediaRecorder.start(); + setRecording(true); + } catch (error) { + console.error("Error starting the MediaRecorder.", error); + onError?.("Error starting the MediaRecorder."); + } + }, 10); + } catch (error) { + console.error("Error accessing media devices.", error); + onError?.("Error accessing media devices."); + } + } else if (mediaRecorder) { + try { + mediaRecorder.start(); + setRecording(true); + } catch (error) { + console.error("Error starting the MediaRecorder.", error); + onError?.("Error starting the MediaRecorder."); + } + } + }; + + const stopRecording = () => { + if (mediaRecorder) { + mediaRecorder.stop(); + setRecording(false); + stopMediaStream(); + } + }; + + // useEffect(() => { + // return () => { + // stopMediaStream(); + // }; + // }, [mediaStream, stopMediaStream]); + + return { + recording, startRecording, stopRecording + }; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx index d2f35b9b..c5e135b3 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx @@ -18,7 +18,7 @@ const contentTypeConfigs = [ replyContentTypeConfig, ]; -interface JustWeb3XMTPContextProps {} +interface JustWeb3XMTPContextProps { } const JustWeb3XMTPContext = React.createContext< JustWeb3XMTPContextProps | undefined diff --git a/packages/@justweb3/xmtp-plugin/src/lib/utils/attachments/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/utils/attachments/index.ts new file mode 100644 index 00000000..421ce496 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/utils/attachments/index.ts @@ -0,0 +1,14 @@ +export const typeLookup: Record = { + jpg: 'image', + jpeg: 'image', + png: 'image', + gif: 'image', + webp: 'image', + quicktime: 'video', + mov: 'video', + mp4: 'video', + pdf: 'application', + doc: 'application', +}; + +export type AttachmentType = 'image' | 'video' | 'application' | undefined; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/utils/calculateFileSize/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/utils/calculateFileSize/index.ts new file mode 100644 index 00000000..e42510ca --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/utils/calculateFileSize/index.ts @@ -0,0 +1,9 @@ +export const calculateFileSize = (bytes: number) => { + const kilobytes = bytes / 1024 + if (kilobytes < 1024) { + return kilobytes.toFixed(2) + ' KB' + } else { + const megabytes = kilobytes / 1024 + return megabytes.toFixed(2) + ' MB' + } +} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/utils/emojis/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/utils/emojis/index.ts new file mode 100644 index 00000000..046290f8 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/utils/emojis/index.ts @@ -0,0 +1,121 @@ +export type EmojiObject = { + name: string; + emoji: string; +}; + +export const emojis = [ + { name: 'grinningFace', emoji: '😀' }, + { name: 'grinningFaceWithBigEyes', emoji: '😃' }, + { name: 'grinningFaceWithSmilingEyes', emoji: '😄' }, + { name: 'beamingFaceWithSmilingEyes', emoji: '😁' }, + { name: 'grinningSquintingFace', emoji: '😆' }, + { name: 'grinningFaceWithSweat', emoji: '😅' }, + { name: 'faceWithTearsOfJoy', emoji: '😂' }, + { name: 'rollingOnTheFloorLaughing', emoji: '🤣' }, + { name: 'smilingFaceWithSmilingEyes', emoji: '😊' }, + { name: 'smilingFaceWithHalo', emoji: '😇' }, + { name: 'slightlySmilingFace', emoji: '🙂' }, + { name: 'upsideDownFace', emoji: '🙃' }, + { name: 'winkingFace', emoji: '😉' }, + { name: 'relievedFace', emoji: '😌' }, + { name: 'heartEyes', emoji: '😍' }, + { name: 'smilingFaceWithHearts', emoji: '🥰' }, + { name: 'starStruck', emoji: '🤩' }, + { name: 'faceBlowingAKiss', emoji: '😘' }, + { name: 'kissingFace', emoji: '😗' }, + { name: 'kissingFaceWithSmilingEyes', emoji: '😙' }, + { name: 'kissingFaceWithClosedEyes', emoji: '😚' }, + { name: 'faceSavouringFood', emoji: '😋' }, + { name: 'faceWithTongue', emoji: '😛' }, + { name: 'winkingFaceWithTongue', emoji: '😜' }, + { name: 'zanyFace', emoji: '🤪' }, + { name: 'squintingFaceWithTongue', emoji: '😝' }, + { name: 'moneyMouthFace', emoji: '🤑' }, + { name: 'huggingFace', emoji: '🤗' }, + { name: 'faceWithHandOverMouth', emoji: '🤭' }, + { name: 'shushingFace', emoji: '🤫' }, + { name: 'thinkingFace', emoji: '🤔' }, + { name: 'zipperMouthFace', emoji: '🤐' }, + { name: 'faceWithRaisedEyebrow', emoji: '🤨' }, + { name: 'neutralFace', emoji: '😐' }, + { name: 'expressionlessFace', emoji: '😑' }, + { name: 'faceWithoutMouth', emoji: '😶' }, + { name: 'smirkingFace', emoji: '😏' }, + { name: 'unamusedFace', emoji: '😒' }, + { name: 'faceWithRollingEyes', emoji: '🙄' }, + { name: 'grimacingFace', emoji: '😬' }, + { name: 'lyingFace', emoji: '🤥' }, + { name: 'pensiveFace', emoji: '😔' }, + { name: 'sleepyFace', emoji: '😪' }, + { name: 'droolingFace', emoji: '🤤' }, + { name: 'sleepingFace', emoji: '😴' }, + { name: 'faceWithMedicalMask', emoji: '😷' }, + { name: 'faceWithThermometer', emoji: '🤒' }, + { name: 'faceWithHeadBandage', emoji: '🤕' }, + { name: 'nauseatedFace', emoji: '🤢' }, + { name: 'faceVomiting', emoji: '🤮' }, + { name: 'sneezingFace', emoji: '🤧' }, + { name: 'hotFace', emoji: '🥵' }, + { name: 'coldFace', emoji: '🥶' }, + { name: 'woozyFace', emoji: '🥴' }, + { name: 'dizzyFace', emoji: '😵' }, + { name: 'explodingHead', emoji: '🤯' }, + { name: 'cowboyHatFace', emoji: '🤠' }, + { name: 'partyingFace', emoji: '🥳' }, + { name: 'smilingFaceWithSunglasses', emoji: '😎' }, + { name: 'nerdFace', emoji: '🤓' }, + { name: 'faceWithMonocle', emoji: '🧐' }, + { name: 'confusedFace', emoji: '😕' }, + { name: 'worriedFace', emoji: '😟' }, + { name: 'slightlyFrowningFace', emoji: '🙁' }, + { name: 'frowningFace', emoji: '☹' }, + { name: 'faceWithOpenMouth', emoji: '😮' }, + { name: 'hushedFace', emoji: '😯' }, + { name: 'astonishedFace', emoji: '😲' }, + { name: 'flushedFace', emoji: '😳' }, + { name: 'pleadingFace', emoji: '🥺' }, + { name: 'frowningFaceWithOpenMouth', emoji: '😦' }, + { name: 'anguishedFace', emoji: '😧' }, + { name: 'fearfulFace', emoji: '😨' }, + { name: 'anxiousFaceWithSweat', emoji: '😰' }, + { name: 'sadButRelievedFace', emoji: '😥' }, + { name: 'cryingFace', emoji: '😢' }, + { name: 'loudlyCryingFace', emoji: '😭' }, + { name: 'faceScreamingInFear', emoji: '😱' }, + { name: 'confoundedFace', emoji: '😖' }, + { name: 'perseveringFace', emoji: '😣' }, + { name: 'disappointedFace', emoji: '😞' }, + { name: 'downcastFaceWithSweat', emoji: '😓' }, + { name: 'wearyFace', emoji: '😩' }, + { name: 'tiredFace', emoji: '😫' }, + { name: 'faceWithSteamFromNose', emoji: '😤' }, + { name: 'poutingFace', emoji: '😡' }, + { name: 'angryFace', emoji: '😠' }, + { name: 'faceWithSymbolsOnMouth', emoji: '🤬' }, + { name: 'smilingFaceWithHorns', emoji: '😈' }, + { name: 'angryFaceWithHorns', emoji: '👿' }, + { name: 'skull', emoji: '💀' }, + { name: 'skullAndCrossbones', emoji: '☠' }, + { name: 'pileOfPoo', emoji: '💩' }, + { name: 'clownFace', emoji: '🤡' }, + { name: 'ogre', emoji: '👹' }, + { name: 'goblin', emoji: '👺' }, + { name: 'ghost', emoji: '👻' }, + { name: 'alien', emoji: '👽' }, + { name: 'alienMonster', emoji: '👾' }, + { name: 'robot', emoji: '🤖' }, + { name: 'grinningCat', emoji: '😺' }, + { name: 'grinningCatWithSmilingEyes', emoji: '😸' }, + { name: 'catWithTearsOfJoy', emoji: '😹' }, + { name: 'smilingCatWithHeartEyes', emoji: '😻' }, + { name: 'catWithWrySmile', emoji: '😼' }, + { name: 'kissingCat', emoji: '😽' }, + { name: 'wearyCat', emoji: '🙀' }, + { name: 'cryingCat', emoji: '😿' }, + { name: 'poutingCat', emoji: '😾' }, +]; + +export const findEmojiByName = (name: string) => { + const emojiObj = emojis.find((emoji) => emoji.name === name); + return emojiObj ? emojiObj.emoji : null; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/utils/filterReactionsMessages/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/utils/filterReactionsMessages/index.ts new file mode 100644 index 00000000..4fbc2f23 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/utils/filterReactionsMessages/index.ts @@ -0,0 +1,25 @@ +import { CachedMessage } from '@xmtp/react-sdk'; + +export type MessageWithReaction = CachedMessage & { + reactionMessage?: CachedMessage; +}; + +export const filterReactionsMessages = (messages: CachedMessage[]) => { + const messagesMap = new Map(); + for (const message of messages) { + if (message.contentType === 'xmtp.org/reaction:1.0') { + const referenceId = message.content.reference.toString(); + const reactionMessage = messagesMap.get(referenceId); + if (reactionMessage) { + const messageWithReaction: MessageWithReaction = { + ...reactionMessage, + reactionMessage: message, + }; + messagesMap.set(reactionMessage.id, messageWithReaction); + } + } else { + messagesMap.set(message.id, message); + } + } + return Array.from(messagesMap.values()); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/utils/formatAddress/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/utils/formatAddress/index.ts new file mode 100644 index 00000000..726343cd --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/utils/formatAddress/index.ts @@ -0,0 +1,5 @@ +export const formatAddress = (text: string) => { + const start = text.substring(0, 4); + const end = text.slice(-4); + return `${start}...${end}`; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/utils/formatVoiceTime/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/utils/formatVoiceTime/index.ts new file mode 100644 index 00000000..c74d31c1 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/utils/formatVoiceTime/index.ts @@ -0,0 +1,12 @@ +export const formatTime = (timeSeconds: number) => { + if (Number.isFinite(timeSeconds)) { + const date = new Date(timeSeconds * 1000); + const minutes = date.getUTCMinutes(); + const mins = minutes < 10 ? `0${minutes}` : minutes; + const seconds = date.getUTCSeconds(); + const secs = seconds < 10 ? `0${seconds}` : seconds; + return `${mins}:${secs}`; + } else { + return '00:00'; + } +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/utils/groupMessageByDate/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/utils/groupMessageByDate/index.ts new file mode 100644 index 00000000..c6a8b16f --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/utils/groupMessageByDate/index.ts @@ -0,0 +1,37 @@ +import { MessageWithReaction } from '../filterReactionsMessages' + +interface GroupedMessages { + [date: string]: MessageWithReaction[] +} + +const getFormattedDate = (date: Date): string => { + const options: Intl.DateTimeFormatOptions = { + weekday: 'long', + day: '2-digit', + month: 'short', + } + const formattedDate = date + .toLocaleDateString('en-US', options) + .toUpperCase() + const parts = formattedDate.split(' ') + return `${parts[0]} ${parts[1]} ${parts[2]}` +} + +export const groupMessagesByDate = ( + messages: MessageWithReaction[], +): GroupedMessages => { + const groupedMessages = messages.reduce((acc, message) => { + const date = new Date(message.sentAt) + const formattedDate = getFormattedDate(date) + + if (!acc[formattedDate]) { + acc[formattedDate] = [] + } + + acc[formattedDate].push(message) + + return acc + }, {}) + + return groupedMessages +} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/utils/messageTimeFormat/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/utils/messageTimeFormat/index.ts new file mode 100644 index 00000000..27e22c2a --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/utils/messageTimeFormat/index.ts @@ -0,0 +1,16 @@ +export const formatMessageSentTime = (date: Date) => { + // Get hours, minutes, and AM/PM + let hours = date.getHours(); + const minutes = date.getMinutes(); + const ampm = hours >= 12 ? 'PM' : 'AM'; + + // Convert 24h time to 12h format + hours = hours % 12; + hours = hours ? hours : 12; // the hour '0' should be '12' + + // Ensure minutes are two digits + const minutesStr = minutes < 10 ? '0' + minutes : minutes; + + // Format: "HH:MM AM/PM" + return `${hours}:${minutesStr} ${ampm}`; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/utils/recordingValue/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/utils/recordingValue/index.ts new file mode 100644 index 00000000..8e74f33b --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/utils/recordingValue/index.ts @@ -0,0 +1,12 @@ +import type { StatusMessages } from 'react-media-recorder-2'; + +export const getRecordingValue = ( + status: StatusMessages, + minutes: number, + seconds: number +): string | null => + status === 'recording' + ? `${minutes < 10 ? '0' : ''}${minutes}:${ + seconds < 10 ? '0' : '' + }${seconds}` + : null; diff --git a/yarn.lock b/yarn.lock index b4be1bad..cc819a24 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1672,7 +1672,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.10.4, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.19.4, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.22.6, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.10.4, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.19.4, @babel/runtime@npm:^7.20.0, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.22.6, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.24.4, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.25.6, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2": version: 7.26.0 resolution: "@babel/runtime@npm:7.26.0" dependencies: @@ -7058,6 +7058,13 @@ __metadata: languageName: node linkType: hard +"@radix-ui/number@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/number@npm:1.1.0" + checksum: 10c0/a48e34d5ff1484de1b7cf5d7317fefc831d49e96a2229f300fd37b657bd8cfb59c922830c00ec02838ab21de3b299a523474592e4f30882153412ed47edce6a4 + languageName: node + linkType: hard + "@radix-ui/primitive@npm:1.1.0": version: 1.1.0 resolution: "@radix-ui/primitive@npm:1.1.0" @@ -7596,6 +7603,35 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-slider@npm:^1.2.1": + version: 1.2.1 + resolution: "@radix-ui/react-slider@npm:1.2.1" + dependencies: + "@radix-ui/number": "npm:1.1.0" + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-collection": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.1" + "@radix-ui/react-direction": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-controllable-state": "npm:1.1.0" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + "@radix-ui/react-use-previous": "npm:1.1.0" + "@radix-ui/react-use-size": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/f39b67f019accc2fddebddb0d7f5bca7fc6ce8b370d294779e5139f7f36135ead9dff8672a9e4d5c771103280df9a05185ff17656d11e9eb88170e8f30e5efb4 + languageName: node + linkType: hard + "@radix-ui/react-slot@npm:1.1.0": version: 1.1.0 resolution: "@radix-ui/react-slot@npm:1.1.0" @@ -15229,6 +15265,16 @@ __metadata: languageName: node linkType: hard +"automation-events@npm:^7.0.9": + version: 7.1.4 + resolution: "automation-events@npm:7.1.4" + dependencies: + "@babel/runtime": "npm:^7.26.0" + tslib: "npm:^2.8.1" + checksum: 10c0/422e6b9046640d6d527ec9662b07c4fa9c04f26ef56c6fa418fcfcd7e41b3e2a48b2ae72f8255fca64982f232155653aa814346fc963cb0f1adc61c00470bf81 + languageName: node + linkType: hard + "autoprefixer@npm:^10.4.20, autoprefixer@npm:^10.4.9": version: 10.4.20 resolution: "autoprefixer@npm:10.4.20" @@ -15970,6 +16016,18 @@ __metadata: languageName: node linkType: hard +"broker-factory@npm:^3.0.107, broker-factory@npm:^3.0.97": + version: 3.0.107 + resolution: "broker-factory@npm:3.0.107" + dependencies: + "@babel/runtime": "npm:^7.26.0" + fast-unique-numbers: "npm:^9.0.14" + tslib: "npm:^2.8.1" + worker-factory: "npm:^7.0.34" + checksum: 10c0/f0dd17dd86471e9b89b36fcb4e2dac2dc1457ed17e548fc65f95942e54f8330911666e226f077583fff33575200cedb07959658db86b64c4974fe3f3f792b5b2 + languageName: node + linkType: hard + "brorand@npm:^1.0.1, brorand@npm:^1.1.0": version: 1.1.0 resolution: "brorand@npm:1.1.0" @@ -21260,6 +21318,56 @@ __metadata: languageName: node linkType: hard +"extendable-media-recorder-wav-encoder-broker@npm:^7.0.100, extendable-media-recorder-wav-encoder-broker@npm:^7.0.111": + version: 7.0.111 + resolution: "extendable-media-recorder-wav-encoder-broker@npm:7.0.111" + dependencies: + "@babel/runtime": "npm:^7.26.0" + broker-factory: "npm:^3.0.107" + extendable-media-recorder-wav-encoder-worker: "npm:^8.0.108" + tslib: "npm:^2.8.1" + checksum: 10c0/ecbfd6f600dbfa87d87332efc1eaedae5bdba90b60f6941178ebde5636aaa6b0bbfca3b17d611e8887c9fc52a5babf0f6b0737f8e0c2d4fc78b3d2c1ed3efe34 + languageName: node + linkType: hard + +"extendable-media-recorder-wav-encoder-worker@npm:^8.0.108": + version: 8.0.108 + resolution: "extendable-media-recorder-wav-encoder-worker@npm:8.0.108" + dependencies: + "@babel/runtime": "npm:^7.26.0" + tslib: "npm:^2.8.1" + worker-factory: "npm:^7.0.34" + checksum: 10c0/06cab89e1fe0d7e5f8113a4dab6ccb11a4083412eab2b64f02cc76e0637c7b6dcdad3731fef8533813fa716f789beff08a875f82a43d1b409a59d5ebc9591b2d + languageName: node + linkType: hard + +"extendable-media-recorder-wav-encoder@npm:^7.0.85": + version: 7.0.121 + resolution: "extendable-media-recorder-wav-encoder@npm:7.0.121" + dependencies: + "@babel/runtime": "npm:^7.26.0" + extendable-media-recorder-wav-encoder-broker: "npm:^7.0.111" + extendable-media-recorder-wav-encoder-worker: "npm:^8.0.108" + tslib: "npm:^2.8.1" + checksum: 10c0/3afd95e9986214630dfe0e9ed55bb0cba5639ab3b98e15a8b97f58d2ba10e40d9eb3ef0c24cbd43cd44bef17fcfd1632b76734344ff514742b7171ad3c1c9499 + languageName: node + linkType: hard + +"extendable-media-recorder@npm:^7.1.9": + version: 7.1.22 + resolution: "extendable-media-recorder@npm:7.1.22" + dependencies: + "@babel/runtime": "npm:^7.22.6" + media-encoder-host: "npm:^8.0.98" + multi-buffer-data-view: "npm:^5.0.7" + recorder-audio-worklet: "npm:^6.0.12" + standardized-audio-context: "npm:^25.3.54" + subscribable-things: "npm:^2.1.22" + tslib: "npm:^2.6.0" + checksum: 10c0/ae7631708bf32feeb59ff058b6b1f09e75befb6c8d6c12b86e4a515f36e174f8d8d96b96658ea900201778622cfa5f39ca020c92ea53df2ae3cf548f2d1ab562 + languageName: node + linkType: hard + "extension-port-stream@npm:^3.0.0": version: 3.0.0 resolution: "extension-port-stream@npm:3.0.0" @@ -21408,6 +21516,16 @@ __metadata: languageName: node linkType: hard +"fast-unique-numbers@npm:^9.0.14, fast-unique-numbers@npm:^9.0.4": + version: 9.0.14 + resolution: "fast-unique-numbers@npm:9.0.14" + dependencies: + "@babel/runtime": "npm:^7.26.0" + tslib: "npm:^2.8.1" + checksum: 10c0/cb9316e207f29ddc79ce6b893a86663883c2627a119226446b11086a9a31f990203097b3eb645c0de02937188866cdb419b8e0d41e83cbe1510b504539b36dda + languageName: node + linkType: hard + "fast-uri@npm:^3.0.1": version: 3.0.3 resolution: "fast-uri@npm:3.0.3" @@ -26575,6 +26693,7 @@ __metadata: "@radix-ui/react-label": "npm:^2.1.0" "@radix-ui/react-popover": "npm:^1.1.1" "@radix-ui/react-radio-group": "npm:^1.2.1" + "@radix-ui/react-slider": "npm:^1.2.1" "@radix-ui/react-switch": "npm:^1.1.1" "@radix-ui/react-tabs": "npm:^1.1.1" "@radix-ui/react-tooltip": "npm:^1.1.4" @@ -26702,6 +26821,7 @@ __metadata: react-code-blocks: "npm:^0.1.6" react-dom: "npm:18.3.1" react-hook-form: "npm:^7.53.0" + react-media-recorder-2: "npm:^1.6.23" react-native: "npm:0.73.2" react-native-svg: "npm:14.1.0" react-native-svg-transformer: "npm:1.2.0" @@ -26711,6 +26831,7 @@ __metadata: react-router-dom: "npm:6.11.2" react-split: "npm:^2.0.14" react-test-renderer: "npm:18.2.0" + react-timer-hook: "npm:^3.0.8" react-tiny-popover: "npm:^8.0.4" rollup: "npm:^4.24.0" rollup-plugin-postcss: "npm:^4.0.2" @@ -28090,6 +28211,43 @@ __metadata: languageName: node linkType: hard +"media-encoder-host-broker@npm:^7.1.0": + version: 7.1.0 + resolution: "media-encoder-host-broker@npm:7.1.0" + dependencies: + "@babel/runtime": "npm:^7.24.4" + broker-factory: "npm:^3.0.97" + fast-unique-numbers: "npm:^9.0.4" + media-encoder-host-worker: "npm:^9.2.0" + tslib: "npm:^2.6.2" + checksum: 10c0/0387ef42930aa757377fb90542feb8dc0bac5a1f0baec97688fad9061afde0dbf1c75f4fe8f04412a087739c738f2556ca03d0d8a1dd5f064d0cad29c5c15c38 + languageName: node + linkType: hard + +"media-encoder-host-worker@npm:^9.2.0": + version: 9.2.0 + resolution: "media-encoder-host-worker@npm:9.2.0" + dependencies: + "@babel/runtime": "npm:^7.24.4" + extendable-media-recorder-wav-encoder-broker: "npm:^7.0.100" + tslib: "npm:^2.6.2" + worker-factory: "npm:^7.0.24" + checksum: 10c0/5fd1464898ec198e35877ead3e38998c7132425c35e49336986edce048088c1f2d5d3e15baac619cc217904090e8cf0d2a3ca44d6487244fbba3e62f1e58613b + languageName: node + linkType: hard + +"media-encoder-host@npm:^8.0.98": + version: 8.1.0 + resolution: "media-encoder-host@npm:8.1.0" + dependencies: + "@babel/runtime": "npm:^7.24.4" + media-encoder-host-broker: "npm:^7.1.0" + media-encoder-host-worker: "npm:^9.2.0" + tslib: "npm:^2.6.2" + checksum: 10c0/e274c446f20a175897ab593bd5bcb9d62dd65e6851a35bb9d117f3ada568cbcea91d878ebbd9a946f1abfb92286d626f02901777b8b478c74733201004c81c19 + languageName: node + linkType: hard + "media-query-parser@npm:^2.0.2": version: 2.0.2 resolution: "media-query-parser@npm:2.0.2" @@ -28937,6 +29095,16 @@ __metadata: languageName: node linkType: hard +"multi-buffer-data-view@npm:^5.0.7": + version: 5.0.14 + resolution: "multi-buffer-data-view@npm:5.0.14" + dependencies: + "@babel/runtime": "npm:^7.23.8" + tslib: "npm:^2.6.2" + checksum: 10c0/64722bff9c1d095feda26682a29587bb8ecad0ffbfcd8d89e90668f738ebc704612f88186f8af859af12bd8dfbac8933dcd1f27d96f772c9bb6154cc9b6fabbd + languageName: node + linkType: hard + "multicast-dns@npm:^7.2.5": version: 7.2.5 resolution: "multicast-dns@npm:7.2.5" @@ -33060,6 +33228,16 @@ __metadata: languageName: node linkType: hard +"react-media-recorder-2@npm:^1.6.23": + version: 1.6.23 + resolution: "react-media-recorder-2@npm:1.6.23" + dependencies: + extendable-media-recorder: "npm:^7.1.9" + extendable-media-recorder-wav-encoder: "npm:^7.0.85" + checksum: 10c0/fd922d6e40a39abb2b04001569c9309334ba747bd9c6ed190042e012142ebfd8cb44cae73fae685a46bda1d9ee49bdb11377a6286a41f96240e1b92fd3c5daa1 + languageName: node + linkType: hard + "react-native-svg-transformer@npm:1.2.0": version: 1.2.0 resolution: "react-native-svg-transformer@npm:1.2.0" @@ -33330,6 +33508,15 @@ __metadata: languageName: node linkType: hard +"react-timer-hook@npm:^3.0.8": + version: 3.0.8 + resolution: "react-timer-hook@npm:3.0.8" + peerDependencies: + react: ">=16.8.0" + checksum: 10c0/3ee67def88bbe5d848ac02c9a795e49bc2bd248357e6119b26ad5ee1d98d66e5be21431d33e0e457da8bf2919c7cc5a3438f792e4fb5e44e8b80664f309af93e + languageName: node + linkType: hard + "react-tiny-popover@npm:^8.0.4": version: 8.1.2 resolution: "react-tiny-popover@npm:8.1.2" @@ -33557,6 +33744,32 @@ __metadata: languageName: node linkType: hard +"recorder-audio-worklet-processor@npm:^5.0.29": + version: 5.0.29 + resolution: "recorder-audio-worklet-processor@npm:5.0.29" + dependencies: + "@babel/runtime": "npm:^7.26.0" + tslib: "npm:^2.8.1" + checksum: 10c0/5485b3a84f1a5970fac35ce35315540367b286716246239d81ebb977c251c42386508df8ae01abe6e4f697312002c07d16ee0626fe0db95e2d794d05e88801f8 + languageName: node + linkType: hard + +"recorder-audio-worklet@npm:^6.0.12": + version: 6.0.39 + resolution: "recorder-audio-worklet@npm:6.0.39" + dependencies: + "@babel/runtime": "npm:^7.26.0" + broker-factory: "npm:^3.0.107" + fast-unique-numbers: "npm:^9.0.14" + recorder-audio-worklet-processor: "npm:^5.0.29" + standardized-audio-context: "npm:^25.3.77" + subscribable-things: "npm:^2.1.45" + tslib: "npm:^2.8.1" + worker-factory: "npm:^7.0.34" + checksum: 10c0/38ec13a988a130b2e65a62a54cbd8e37c77c5638f47ef8b3df85787311df4c6eb0024da1fb8e170ec8dedb2e477f83cf4faaf070d40bc46c87c7b81da51bda80 + languageName: node + linkType: hard + "redent@npm:^3.0.0": version: 3.0.0 resolution: "redent@npm:3.0.0" @@ -34305,6 +34518,13 @@ __metadata: languageName: node linkType: hard +"rxjs-interop@npm:^2.0.0": + version: 2.0.0 + resolution: "rxjs-interop@npm:2.0.0" + checksum: 10c0/609d4766630624af138b4def9dcc435b5e2118f72e2e84cda6213315585c7160b40c5d3a88c2c166997f5c28f5ea03451c73d86d240e92e7be5fce25b37b5028 + languageName: node + linkType: hard + "rxjs@npm:^6.6.3": version: 6.6.7 resolution: "rxjs@npm:6.6.7" @@ -35539,6 +35759,17 @@ __metadata: languageName: node linkType: hard +"standardized-audio-context@npm:^25.3.54, standardized-audio-context@npm:^25.3.77": + version: 25.3.77 + resolution: "standardized-audio-context@npm:25.3.77" + dependencies: + "@babel/runtime": "npm:^7.25.6" + automation-events: "npm:^7.0.9" + tslib: "npm:^2.7.0" + checksum: 10c0/41d5e3a64b881691fecd709313045ab9bddb864ed79c6eb51490056cec080e808e9f5b3ef94d734567b9da88f9c95e68cc63a3a0343374b2f865b1a961fb46ef + languageName: node + linkType: hard + "statuses@npm:2.0.1": version: 2.0.1 resolution: "statuses@npm:2.0.1" @@ -36166,6 +36397,17 @@ __metadata: languageName: node linkType: hard +"subscribable-things@npm:^2.1.22, subscribable-things@npm:^2.1.45": + version: 2.1.45 + resolution: "subscribable-things@npm:2.1.45" + dependencies: + "@babel/runtime": "npm:^7.26.0" + rxjs-interop: "npm:^2.0.0" + tslib: "npm:^2.8.1" + checksum: 10c0/6e2151b5ce0fdd1db671a139c4b878656ed4615525942f69501b9c0c37b955c13bdb566be3430cc29d89aedbdefae81bf61b473d54e68ab4b4185220096c5200 + languageName: node + linkType: hard + "sucrase@npm:3.34.0": version: 3.34.0 resolution: "sucrase@npm:3.34.0" @@ -37153,6 +37395,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^2.7.0, tslib@npm:^2.8.1": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 + languageName: node + linkType: hard + "tsscmp@npm:1.0.6": version: 1.0.6 resolution: "tsscmp@npm:1.0.6" @@ -39391,6 +39640,17 @@ __metadata: languageName: node linkType: hard +"worker-factory@npm:^7.0.24, worker-factory@npm:^7.0.34": + version: 7.0.34 + resolution: "worker-factory@npm:7.0.34" + dependencies: + "@babel/runtime": "npm:^7.26.0" + fast-unique-numbers: "npm:^9.0.14" + tslib: "npm:^2.8.1" + checksum: 10c0/699b1141ca6262f315f2e54dc018da8b44ff3a4851c88f068cf524ae5988ebffb5a121bd48588dee58160ea6b84fbad28c6aded68e56d01a27141b2b4a0951f4 + languageName: node + linkType: hard + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" From 9369bfb5a665ecb7bb72dcec68fd45aa306333a7 Mon Sep 17 00:00:00 2001 From: anthony2399 Date: Wed, 27 Nov 2024 17:35:04 +0200 Subject: [PATCH 05/29] feat: finalizing xmtp widget --- packages/@justweb3/ui/.svgrrc.js | 16 +- .../src/lib/icons/components/general/Add.tsx | 7 +- .../icons/components/general/AddCircle.tsx | 4 +- .../icons/components/general/AddFolder.tsx | 2 +- .../lib/icons/components/general/AddImage.tsx | 2 +- .../lib/icons/components/general/AddVideo.tsx | 2 +- .../lib/icons/components/general/Address.tsx | 2 +- .../lib/icons/components/general/Arrow.tsx | 2 +- .../icons/components/general/Attachment.tsx | 2 +- .../lib/icons/components/general/Avatar.tsx | 2 +- .../lib/icons/components/general/Banner.tsx | 2 +- .../components/general/BlockedAccount.tsx | 7 +- .../components/general/CalendarClock.tsx | 7 +- .../components/general/CalendarMonth.tsx | 7 +- .../src/lib/icons/components/general/Clip.tsx | 2 +- .../lib/icons/components/general/Close.tsx | 2 +- .../lib/icons/components/general/Comic.tsx | 2 +- .../lib/icons/components/general/Contacts.tsx | 2 +- .../lib/icons/components/general/Copied.tsx | 2 +- .../src/lib/icons/components/general/Copy.tsx | 2 +- .../lib/icons/components/general/Document.tsx | 2 +- .../lib/icons/components/general/Download.tsx | 2 +- .../src/lib/icons/components/general/Edit.tsx | 2 +- .../lib/icons/components/general/General.tsx | 2 +- .../lib/icons/components/general/Location.tsx | 2 +- .../icons/components/general/LocationOn.tsx | 7 +- .../lib/icons/components/general/Logout.tsx | 2 +- .../src/lib/icons/components/general/Mapp.tsx | 2 +- .../lib/icons/components/general/Maximize.tsx | 2 +- .../src/lib/icons/components/general/Mic.tsx | 2 +- .../lib/icons/components/general/Minimize.tsx | 2 +- .../lib/icons/components/general/Minus.tsx | 2 +- .../lib/icons/components/general/Nickname.tsx | 2 +- .../icons/components/general/Notification.tsx | 2 +- .../lib/icons/components/general/Pause.tsx | 7 +- .../src/lib/icons/components/general/Pen.tsx | 2 +- .../icons/components/general/PersonEdit.tsx | 2 +- .../src/lib/icons/components/general/Play.tsx | 5 +- .../lib/icons/components/general/Profile.tsx | 7 +- .../icons/components/general/ProfileEdit.tsx | 2 +- .../lib/icons/components/general/Reaction.tsx | 7 +- .../lib/icons/components/general/Reply.tsx | 7 +- .../src/lib/icons/components/general/Send.tsx | 2 +- .../lib/icons/components/general/Social.tsx | 2 +- .../src/lib/icons/components/general/Stop.tsx | 2 +- .../src/lib/icons/components/general/Tune.tsx | 2 +- .../components/general/Verifications.tsx | 2 +- .../lib/icons/components/general/Wallet.tsx | 2 +- .../src/lib/components/Chat/index.tsx | 329 +++++++++--------- .../src/lib/components/MessageCard/index.tsx | 83 +++-- .../src/lib/components/MessageSheet/index.tsx | 2 +- .../lib/components/MessageTextField/index.tsx | 18 +- .../lib/components/VoiceMessageCard/index.tsx | 80 +++-- 53 files changed, 392 insertions(+), 280 deletions(-) diff --git a/packages/@justweb3/ui/.svgrrc.js b/packages/@justweb3/ui/.svgrrc.js index 1bf9583a..b264fa39 100644 --- a/packages/@justweb3/ui/.svgrrc.js +++ b/packages/@justweb3/ui/.svgrrc.js @@ -1,6 +1,10 @@ -module.exports ={ - "typescript": true, - "template": require("./src/template/template.js"), - "dimensions": false, - "svgo": true -} +module.exports = { + typescript: true, + dimensions: false, + svgo: true, + replaceAttrValues: { + 'var(--justweb3-primary-color)': + '{props.fill || "var(--justweb3-primary-color)"}', + }, + template: require('./src/template/template.js'), +}; diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Add.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Add.tsx index 614d1e14..d968f3a4 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Add.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Add.tsx @@ -18,11 +18,14 @@ export default function Add(props: SVGProps) { maskType: 'alpha', }} > - + diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/AddCircle.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/AddCircle.tsx index 62eb2d7f..c7faf525 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/AddCircle.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/AddCircle.tsx @@ -22,14 +22,14 @@ export default function AddCircle(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/AddFolder.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/AddFolder.tsx index 66192730..65a9c283 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/AddFolder.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/AddFolder.tsx @@ -22,7 +22,7 @@ export default function AddFolder(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/AddImage.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/AddImage.tsx index 7839c549..ade75bb6 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/AddImage.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/AddImage.tsx @@ -22,7 +22,7 @@ export default function AddImage(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/AddVideo.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/AddVideo.tsx index 6e10e959..b42bf101 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/AddVideo.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/AddVideo.tsx @@ -22,7 +22,7 @@ export default function AddVideo(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Address.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Address.tsx index 659a982b..55bb06ed 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Address.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Address.tsx @@ -22,7 +22,7 @@ export default function Address(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Arrow.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Arrow.tsx index f18c8261..38c8dda0 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Arrow.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Arrow.tsx @@ -22,7 +22,7 @@ export default function Arrow(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Attachment.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Attachment.tsx index c1074914..25ff8005 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Attachment.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Attachment.tsx @@ -22,7 +22,7 @@ export default function Attachment(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Avatar.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Avatar.tsx index a9757970..1b9bdf62 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Avatar.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Avatar.tsx @@ -22,7 +22,7 @@ export default function Avatar(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Banner.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Banner.tsx index cec9a989..78f724b1 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Banner.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Banner.tsx @@ -8,7 +8,7 @@ export default function Banner(props: SVGProps) { {...props} > ) { maskType: 'alpha', }} > - + diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/CalendarClock.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/CalendarClock.tsx index 7fcf37ba..76f23453 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/CalendarClock.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/CalendarClock.tsx @@ -18,11 +18,14 @@ export default function CalendarClock(props: SVGProps) { maskType: 'alpha', }} > - + diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/CalendarMonth.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/CalendarMonth.tsx index 2b9263ef..2518d2da 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/CalendarMonth.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/CalendarMonth.tsx @@ -18,11 +18,14 @@ export default function CalendarMonth(props: SVGProps) { maskType: 'alpha', }} > - + diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Clip.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Clip.tsx index 52d2e0f6..7660ab5b 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Clip.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Clip.tsx @@ -22,7 +22,7 @@ export default function Clip(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Close.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Close.tsx index ea8e2fc3..96ee530f 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Close.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Close.tsx @@ -22,7 +22,7 @@ export default function Close(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Comic.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Comic.tsx index 2a08ea6a..c70cb595 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Comic.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Comic.tsx @@ -22,7 +22,7 @@ export default function Comic(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Contacts.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Contacts.tsx index 23524180..6ecdaf8a 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Contacts.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Contacts.tsx @@ -22,7 +22,7 @@ export default function Contacts(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Copied.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Copied.tsx index 3cc0719b..344b6eaf 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Copied.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Copied.tsx @@ -3,7 +3,7 @@ export default function Copied(props: SVGProps) { return ( diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Copy.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Copy.tsx index 47edc5a3..9727f365 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Copy.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Copy.tsx @@ -22,7 +22,7 @@ export default function Copy(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Document.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Document.tsx index dd1985b3..9f24bc61 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Document.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Document.tsx @@ -22,7 +22,7 @@ export default function Document(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Download.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Download.tsx index 7e7ab106..c825c9b4 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Download.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Download.tsx @@ -23,7 +23,7 @@ export default function Download(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Edit.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Edit.tsx index 4eae2d41..b2bb95e0 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Edit.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Edit.tsx @@ -22,7 +22,7 @@ export default function Edit(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/General.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/General.tsx index e09c8192..39558bd4 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/General.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/General.tsx @@ -22,7 +22,7 @@ export default function General(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Location.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Location.tsx index 99f813d5..41dbbd3c 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Location.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Location.tsx @@ -8,7 +8,7 @@ export default function Location(props: SVGProps) { {...props} > diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/LocationOn.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/LocationOn.tsx index 4efd89d9..9508decc 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/LocationOn.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/LocationOn.tsx @@ -18,11 +18,14 @@ export default function LocationOn(props: SVGProps) { maskType: 'alpha', }} > - + diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Logout.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Logout.tsx index c018acf3..c5189f12 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Logout.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Logout.tsx @@ -22,7 +22,7 @@ export default function Logout(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Mapp.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Mapp.tsx index 2f9a1d15..9797920a 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Mapp.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Mapp.tsx @@ -22,7 +22,7 @@ export default function Mapp(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Maximize.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Maximize.tsx index 51153190..f1c57ca0 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Maximize.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Maximize.tsx @@ -22,7 +22,7 @@ export default function Maximize(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Mic.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Mic.tsx index 09f22fad..abbd33f9 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Mic.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Mic.tsx @@ -22,7 +22,7 @@ export default function Mic(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Minimize.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Minimize.tsx index 026395c6..370e58bc 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Minimize.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Minimize.tsx @@ -22,7 +22,7 @@ export default function Minimize(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Minus.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Minus.tsx index 5611eda9..63a744d0 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Minus.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Minus.tsx @@ -3,7 +3,7 @@ export default function Minus(props: SVGProps) { return ( diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Nickname.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Nickname.tsx index 5dc52442..c74f560f 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Nickname.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Nickname.tsx @@ -22,7 +22,7 @@ export default function Nickname(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Notification.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Notification.tsx index 3e42a0ed..b36c1c84 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Notification.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Notification.tsx @@ -22,7 +22,7 @@ export default function Notification(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Pause.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Pause.tsx index 3a194831..895a8538 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Pause.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Pause.tsx @@ -19,11 +19,14 @@ export default function Pause(props: SVGProps) { maskType: 'alpha', }} > - + diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Pen.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Pen.tsx index 6b80a65c..4414f16d 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Pen.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Pen.tsx @@ -22,7 +22,7 @@ export default function Pen(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/PersonEdit.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/PersonEdit.tsx index da07a76d..eca5c4ed 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/PersonEdit.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/PersonEdit.tsx @@ -22,7 +22,7 @@ export default function PersonEdit(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Play.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Play.tsx index 415d1286..d9b432f0 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Play.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Play.tsx @@ -21,7 +21,10 @@ export default function Play(props: SVGProps) { - + ); diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Profile.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Profile.tsx index fb8b81ba..d1996dd7 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Profile.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Profile.tsx @@ -18,11 +18,14 @@ export default function Profile(props: SVGProps) { maskType: 'alpha', }} > - + diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/ProfileEdit.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/ProfileEdit.tsx index f74fd798..0ba0eb43 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/ProfileEdit.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/ProfileEdit.tsx @@ -22,7 +22,7 @@ export default function ProfileEdit(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Reaction.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Reaction.tsx index 1c06f3c0..a2fd735f 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Reaction.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Reaction.tsx @@ -18,11 +18,14 @@ export default function Reaction(props: SVGProps) { maskType: 'alpha', }} > - + diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Reply.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Reply.tsx index f27a79eb..df7af654 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Reply.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Reply.tsx @@ -18,11 +18,14 @@ export default function Reply(props: SVGProps) { maskType: 'alpha', }} > - + diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Send.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Send.tsx index 8984fec6..25e91911 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Send.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Send.tsx @@ -22,7 +22,7 @@ export default function Send(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Social.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Social.tsx index f9e09e0d..07147867 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Social.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Social.tsx @@ -22,7 +22,7 @@ export default function Social(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Stop.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Stop.tsx index 4a89de68..8df3b34e 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Stop.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Stop.tsx @@ -23,7 +23,7 @@ export default function Stop(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Tune.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Tune.tsx index 339fd4fc..99bd357c 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Tune.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Tune.tsx @@ -22,7 +22,7 @@ export default function Tune(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Verifications.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Verifications.tsx index e13f2775..b4651923 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Verifications.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Verifications.tsx @@ -22,7 +22,7 @@ export default function Verifications(props: SVGProps) { diff --git a/packages/@justweb3/ui/src/lib/icons/components/general/Wallet.tsx b/packages/@justweb3/ui/src/lib/icons/components/general/Wallet.tsx index 26247360..a0555b56 100644 --- a/packages/@justweb3/ui/src/lib/icons/components/general/Wallet.tsx +++ b/packages/@justweb3/ui/src/lib/icons/components/general/Wallet.tsx @@ -22,7 +22,7 @@ export default function Wallet(props: SVGProps) { diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx index a836bfff..0c0e8803 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx @@ -73,24 +73,20 @@ export const Chat: React.FC = ({ conversation, onBack }) => { useStreamMessages(conversation); - console.log(messages) // Memo const filteredMessages = useMemo(() => { const messagesWithoutRead = messages.filter((message) => !(message.contentType === "xmtp.org/readReceipt:1.0")); - console.log('messages without read', messagesWithoutRead) const res = filterReactionsMessages(messagesWithoutRead); return res; }, [messages]); - console.log("filtered msg", filteredMessages) const groupedMessages = useMemo(() => { return groupMessagesByDate(filteredMessages ?? []); }, [filteredMessages]); - console.log("grouped messages", groupedMessages) useEffect(() => { @@ -142,7 +138,7 @@ export const Chat: React.FC = ({ conversation, onBack }) => { return ( - @@ -170,13 +166,27 @@ export const Chat: React.FC = ({ conversation, onBack }) => { replica?.remove(); }} >
- + - - + backgroundColor: 'var(--justweb3-foreground-color-4)' + }} onClick={onBack}> + + + = ({ conversation, onBack }) => { }} >

{primaryName ? primaryName : formatAddress(conversation.peerAddress)}

- {(!!primaryName) && ( + {/* {(!!primaryName) && (

{formatAddress(conversation.peerAddress)}

- )} + )} */}
@@ -249,151 +259,158 @@ export const Chat: React.FC = ({ conversation, onBack }) => {
-
- { - isCanMessageLoading || isLoading ? ( - - {[...Array(5)].map((_, index) => ( - - ))} - - ) : ( - - {canMessage ? ( - - {groupedMessages && Object.keys(groupedMessages).map((date, index) => ( - -

{date}

- {groupedMessages[date].map((message) => - setReplyMessage(msg)} - message={message} - peerAddress={conversation.peerAddress} - key={`message-${message.id}`} - onReaction={(message) => { - setReactionMessage(message); - - const element = document.getElementById(message.id.toString()); - if (!element) return; - const replica = element?.cloneNode(true) as HTMLElement; - replica.id = `${message.id}-replica`; - replica.style.position = 'absolute'; - replica.style.top = element?.offsetTop + 'px'; - replica.style.top = '100px'; - replica.style.zIndex = '90'; - element?.parentElement?.appendChild(replica); - replica.classList.add('replica-animate'); - setEmojiSelectorTop(100 + element.getBoundingClientRect().height); - }} - /> - )} -
- ))} - { - reactionMessage && ( -
- { - handleEmojiSelect(emoji); - setReactionMessage(null); - const replica = document.getElementById(`${reactionMessage?.id}-replica`); - replica?.remove(); + + { + isCanMessageLoading || isLoading ? ( + + {[...Array(5)].map((_, index) => ( + + ))} + + ) : ( + + {canMessage ? ( + + {groupedMessages && Object.keys(groupedMessages).map((date, index) => ( + +

{date}

+ {groupedMessages[date].map((message) => + setReplyMessage(msg)} + message={message} + peerAddress={conversation.peerAddress} + key={`message-${message.id}`} + onReaction={(message) => { + setReactionMessage(message); + + const element = document.getElementById(message.id.toString()); + if (!element) return; + const replica = element?.cloneNode(true) as HTMLElement; + replica.id = `${message.id}-replica`; + replica.style.position = 'absolute'; + replica.style.top = element?.offsetTop + 'px'; + replica.style.top = '100px'; + replica.style.zIndex = '90'; + element?.parentElement?.appendChild(replica); + replica.classList.add('replica-animate'); + setEmojiSelectorTop(100 + element.getBoundingClientRect().height); + }} + /> + )} +
+ ))} + { + reactionMessage && ( +
-
- ) - } + > + { + handleEmojiSelect(emoji); + setReactionMessage(null); + const replica = document.getElementById(`${reactionMessage?.id}-replica`); + replica?.remove(); + }} + + /> +
+ ) + } +
+ ) : ( +
+

Cannot message {conversation.peerAddress}

+
+ )} +
+ ) + } + + { + isRequest ? ( + isRequestChangeLoading ? + + - ) : ( -
-

Cannot message {conversation.peerAddress}

-
- )} - - ) - } - - {isRequest ? ( - isRequestChangeLoading ? - - - - : - - - - - ) : ( - - {isMessagesSenderOnly && ( - + + + + ) : ( + -

Message in user’s Requests

-

This user has not accepted your message request yet

+ {isMessagesSenderOnly && ( + +

Message in user’s Requests

+

This user has not accepted your message request yet

+
+ )} + setReplyMessage(null)} conversation={conversation} replyMessage={replyMessage} />
- )} - setReplyMessage(null)} conversation={conversation} replyMessage={replyMessage} /> -
- )} - + ) + } + + ); }; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx index c653ed11..f63cce4d 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx @@ -25,12 +25,12 @@ interface MessageCardProps { onReaction: (message: MessageWithReaction) => void; } -const MeasureAndHyphenateText: React.FC<{ text: string; maxWidth: number }> = ({ text, maxWidth }) => { +const MeasureAndHyphenateText: React.FC<{ text: string; maxWidth: number, isReceiver: boolean }> = ({ text, maxWidth, isReceiver }) => { const [processedText, setProcessedText] = useState(''); useEffect(() => { // Function to measure text width - const measureText = (text = '', font = '16px Arial') => { + const measureText = (text = '', font = '10px Inter') => { const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); if (!context) return 0; @@ -83,7 +83,12 @@ const MeasureAndHyphenateText: React.FC<{ text: string; maxWidth: number }> = ({ return (
+            style={{
+                whiteSpace: 'pre-wrap',
+                wordBreak: 'break-word',
+                margin: 0,
+                color: isReceiver ? 'var(--justweb3-foreground-color-2)' : 'var(--justweb3-foreground-color-4)'
+            }}>
             {processedText}
         
); @@ -97,6 +102,7 @@ const MessageCard: React.FC = ({ onReaction }) => { const { address } = useMountedAccount(); + const [hovered, setHovered] = useState(false) const [repliedMessage, setRepliedMessage] = React.useState(null); const divRef = useRef(null); const { mutateAsync: sendReaction } = useSendReactionMessage(conversation); @@ -106,6 +112,27 @@ const MessageCard: React.FC = ({ }, [message.content]) + useEffect(() => { + function handleMouseEnter() { + setHovered(true) + } + function handleMouseLeave() { + setHovered(false) + } + const divElement = divRef.current; + if (divElement) { + divElement.addEventListener('mouseenter', handleMouseEnter); + divElement.addEventListener('mouseleave', handleMouseLeave); + } + return () => { + if (divElement) { + divElement.removeEventListener('mouseenter', handleMouseEnter); + divElement.removeEventListener('mouseleave', handleMouseLeave); + } + }; + }, []); + + const attachmentExtention = useMemo(() => { if (!isText && message.content.mimeType) return message.content.mimeType.split("/")?.[1] || ""; @@ -149,7 +176,7 @@ const MessageCard: React.FC = ({ if (!repliedMessage) return; const element = document.getElementById(repliedMessage.id); if (element) { - element.scrollIntoView({ behavior: "smooth" }); + element.scrollIntoView({ behavior: "smooth", block: "center" }); } } @@ -200,11 +227,12 @@ const MessageCard: React.FC = ({ lineHeight: '14px', padding: isReply ? '4px' : '5px', borderRadius: '5px', - backgroundColor: isReceiver ? '#F5F5F5' : '#ffffff', - border: '1px solid black', - borderLeft: isReceiver ? 'none' : '1px solid black', - borderRight: isReceiver ? '1px solid black' : 'none', + backgroundColor: isReceiver ? 'var(--justweb3-foreground-color-4)' : 'var(--justweb3-primary-color)', + borderBottomLeftRadius: isReceiver ? '0px' : '5px', + borderBottomRightRadius: !isReceiver ? '0px' : '5px', + }} + gap="5px" id={message.id} data-message={JSON.stringify({ id: message.id, @@ -235,11 +263,10 @@ const MessageCard: React.FC = ({ fontSize: '14px', lineHeight: '14px', padding: '10px', - border: '0.5px solid #E0E0E0', - backgroundColor: isReceiver ? '#FFFFFF' : '#F5F5F5', + backgroundColor: isReceiver ? 'var(--justweb3-primary-color)' : 'var(--justweb3-foreground-color-4)', borderRadius: '5px', - borderLeft: isReceiver ? 'none' : '0.5px solid #E0E0E0', - borderRight: isReceiver ? '0.5px solid #E0E0E0' : 'none', + borderBottomLeftRadius: isReceiver ? '0px' : '5px', + borderBottomRightRadius: isReceiver ? '5px' : '0px', }} onClick={navigateToRepliedMessage} > @@ -248,8 +275,8 @@ const MessageCard: React.FC = ({ fontSize: '12px', fontWeight: '600', lineHeight: '100%', - color: 'var(--justweb3-primary-color)', textTransform: 'uppercase', + color: isReceiver ? 'var(--justweb3-foreground-color-4)' : 'var(--justweb3-foreground-color-2)' }} >{repliedMessage?.senderAddress === address ? "YOU" : formatAddress(repliedMessage?.senderAddress ?? "")}

{(isReplyText || isReplyReply) ? ( @@ -261,10 +288,11 @@ const MessageCard: React.FC = ({ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', + color: isReceiver ? 'var(--justweb3-foreground-color-4)' : 'var(--justweb3-foreground-color-2)' }} >{isReplyReply ? repliedMessage.content.content : repliedMessage.content}

) : ( isReplyVoice ? - = ({

= ({ width: 'fit-content', lineHeight: 1, letterSpacing: 0.6, + color: isReceiver ? 'var(--justweb3-foreground-color-2)' : 'var(--justweb3-foreground-color-4)', wordBreak: 'break-all' }} >{message.content.content}

@@ -319,12 +348,12 @@ const MessageCard: React.FC = ({ : isText ? - + : {isVoice ? - + : {typeLookup[attachmentExtention] === "image" ? @@ -370,7 +399,7 @@ const MessageCard: React.FC = ({ style={{ position: 'absolute', cursor: 'pointer', - bottom: '-1rem', + bottom: '-0.5rem', fontSize: '20px', right: isReceiver ? '-12px' : 'auto', left: isReceiver ? 'auto' : '-12px', @@ -378,9 +407,19 @@ const MessageCard: React.FC = ({ >{findEmojiByName(message.reactionMessage.content.content)}

)} + {!isVoice && ( +

{formatMessageSentTime(message.sentAt)}

)}
+ = ({
-

{formatMessageSentTime(message.sentAt)}

+ ); }; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx index da02d3ac..f39ebfbf 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx @@ -20,7 +20,7 @@ export const MessageSheet: React.FC = ({ open={openChat} onOpenChange={(open) => !open && handleOpenChat(null)} > - + Messages {conversation && handleOpenChat(null)} />} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx index 244a9fe4..d90b3d05 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx @@ -240,7 +240,7 @@ const MessageTextField: React.FC = ({ }} >{isReplyReply ? replyMessage.content.content : replyMessage.content}

) : ( isReplyVoice ? - = ({ : = ({ (!replyMessage && !newConvo) && ( { if (disabled) return; startRecording(); start(); - }} />)} + }} /> + )} right={ = ({ message, style, - disabled + disabled, + isReceiver, + isReply }) => { const [playing, setPlaying] = useState(false); const [currentTime, setCurrentTime] = useState(0); @@ -81,62 +86,83 @@ const VoiceMessageCard: React.FC = ({ }; return ( - {playing ? ( - + ) : ( - + )} -

{playing || currentTime > 0 ? formatTime(currentTime) : formatTime(duration ?? 0)}

+ 0 ? audioRef.current.currentTime : 0]} max={duration ?? 0} step={0.01}> + +

{playing || currentTime > 0 ? formatTime(currentTime) : formatTime(duration ?? 0)}

+ {!isReply && ( +

{formatMessageSentTime(message.sentAt)}

+ )} +
); From 9536e98d7c7c381835dd2194283b1d535d8ed817 Mon Sep 17 00:00:00 2001 From: anthony2399 Date: Wed, 27 Nov 2024 17:47:19 +0200 Subject: [PATCH 06/29] fix: message textfield fix when replying --- .../xmtp-plugin/src/lib/components/Chat/index.tsx | 4 ++-- .../src/lib/components/MessageTextField/index.tsx | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx index 0c0e8803..79e0a0b6 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx @@ -270,7 +270,7 @@ export const Chat: React.FC = ({ conversation, onBack }) => { {[...Array(5)].map((_, index) => ( @@ -279,7 +279,7 @@ export const Chat: React.FC = ({ conversation, onBack }) => { ) : ( {canMessage ? ( = ({ {replyMessage && ( = ({ : typeLookup[replyAttachmentExtention] === "image" ? {replyMessage.content.filename} = ({ : Date: Thu, 28 Nov 2024 14:08:59 +0200 Subject: [PATCH 07/29] fix: xmtp build --- packages/@justweb3/ui/project.json | 2 +- .../lib/components/JustWeb3Button/index.tsx | 2 +- packages/@justweb3/xmtp-plugin/project.json | 2 +- .../src/lib/components/Chat/index.tsx | 545 +++++++++++------- .../lib/components/VoiceMessageCard/index.tsx | 342 ++++++----- .../src/lib/hooks/sendAttachment/index.ts | 6 +- .../xmtp-plugin/src/stories/xmtp.stories.tsx | 16 +- 7 files changed, 549 insertions(+), 366 deletions(-) diff --git a/packages/@justweb3/ui/project.json b/packages/@justweb3/ui/project.json index 0983136a..b10f9627 100644 --- a/packages/@justweb3/ui/project.json +++ b/packages/@justweb3/ui/project.json @@ -40,7 +40,7 @@ "command": "node update-package-json.js" }, { - "command": "rmdir /s /q node_modules" + "command": "npx rimraf node_modules" } ], "cwd": "packages/@justweb3/ui", diff --git a/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx b/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx index 1932a888..c16067a0 100644 --- a/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx @@ -1,4 +1,4 @@ -import { FC, Fragment, ReactNode, useContext, useMemo, useState } from 'react'; +import { FC, ReactNode, useContext, useMemo, useState } from 'react'; import { JustWeb3Context, useJustWeb3 } from '../../providers'; import { ArrowIcon, diff --git a/packages/@justweb3/xmtp-plugin/project.json b/packages/@justweb3/xmtp-plugin/project.json index d235f090..9fceb79c 100644 --- a/packages/@justweb3/xmtp-plugin/project.json +++ b/packages/@justweb3/xmtp-plugin/project.json @@ -40,7 +40,7 @@ "command": "node update-package-json.js" }, { - "command": "rm -rf node_modules || rmdir /s /q node_modules" + "command": "npx rimraf node_modules" } ], "cwd": "packages/@justweb3/xmtp-plugin", diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx index 79e0a0b6..dffcbedf 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx @@ -1,5 +1,22 @@ -import { useEnsAvatar, useMountedAccount, usePrimaryName, useRecords } from '@justaname.id/react'; -import { ArrowIcon, Avatar, BlockedAccountIcon, Button, CloseIcon, Flex, LoadingSpinner, P, Popover, PopoverContent, PopoverTrigger, TuneIcon } from '@justweb3/ui'; +import { + useEnsAvatar, + useMountedAccount, + usePrimaryName, + useRecords, +} from '@justaname.id/react'; +import { + ArrowIcon, + Avatar, + BlockedAccountIcon, + Button, + Flex, + LoadingSpinner, + P, + Popover, + PopoverContent, + PopoverTrigger, + TuneIcon, +} from '@justweb3/ui'; import { CachedConversation, ContentTypeMetadata, @@ -7,11 +24,14 @@ import { useClient, useConsent, useMessages, - useStreamMessages + useStreamMessages, } from '@xmtp/react-sdk'; import React, { useEffect, useMemo } from 'react'; import { useSendReactionMessage } from '../../hooks'; -import { filterReactionsMessages, MessageWithReaction } from '../../utils/filterReactionsMessages'; +import { + filterReactionsMessages, + MessageWithReaction, +} from '../../utils/filterReactionsMessages'; import { formatAddress } from '../../utils/formatAddress'; import { groupMessagesByDate } from '../../utils/groupMessageByDate'; import MessageCard from '../MessageCard'; @@ -25,11 +45,14 @@ export interface ChatProps { } export const Chat: React.FC = ({ conversation, onBack }) => { - const [replyMessage, setReplyMessage] = React.useState(null); - const [reactionMessage, setReactionMessage] = React.useState(null); + const [replyMessage, setReplyMessage] = + React.useState(null); + const [reactionMessage, setReactionMessage] = + React.useState(null); const [emojiSelectorTop, setEmojiSelectorTop] = React.useState(0); const [isRequest, setIsRequest] = React.useState(false); - const [isRequestChangeLoading, setIsRequestChangeLoading] = React.useState(false); + const [isRequestChangeLoading, setIsRequestChangeLoading] = + React.useState(false); const { entries, allow, refreshConsentList, deny } = useConsent(); const { mutateAsync: sendReaction } = useSendReactionMessage(conversation); @@ -46,49 +69,44 @@ export const Chat: React.FC = ({ conversation, onBack }) => { const [canMessage, setCanMessage] = React.useState(true); - const { messages, isLoading } = useMessages(conversation) - + const { messages, isLoading } = useMessages(conversation); // Queries const blockAddress = async (peerAddress: string) => { setIsRequestChangeLoading(true); - await refreshConsentList() - await deny([peerAddress]) - await refreshConsentList() + await refreshConsentList(); + await deny([peerAddress]); + await refreshConsentList(); setIsRequestChangeLoading(false); onBack(); - } - + }; - const { canMessage: canMessageFn, isLoading: isCanMessageLoading } = useCanMessage(); + const { canMessage: canMessageFn, isLoading: isCanMessageLoading } = + useCanMessage(); useEffect(() => { if (isCanMessageLoading) return; canMessageFn(conversation.peerAddress).then((result) => { setCanMessage(result); - }) - }, [isCanMessageLoading, conversation, canMessageFn]) - + }); + }, [isCanMessageLoading, conversation, canMessageFn]); useStreamMessages(conversation); - - // Memo const filteredMessages = useMemo(() => { - const messagesWithoutRead = messages.filter((message) => !(message.contentType === "xmtp.org/readReceipt:1.0")); + const messagesWithoutRead = messages.filter( + (message) => !(message.contentType === 'xmtp.org/readReceipt:1.0') + ); const res = filterReactionsMessages(messagesWithoutRead); return res; }, [messages]); - const groupedMessages = useMemo(() => { return groupMessagesByDate(filteredMessages ?? []); }, [filteredMessages]); - - useEffect(() => { const convoConsentState = entries[conversation.peerAddress]?.permissionType; if (convoConsentState === 'unknown' || convoConsentState === undefined) { @@ -99,19 +117,20 @@ export const Chat: React.FC = ({ conversation, onBack }) => { }, [entries, conversation.peerAddress]); const isMessagesSenderOnly = useMemo(() => { - return filteredMessages.every((message) => message.senderAddress === address); + return filteredMessages.every( + (message) => message.senderAddress === address + ); }, [filteredMessages, address]); - const handleAllowAddress = async () => { setIsRequestChangeLoading(true); - await refreshConsentList() - await allow([conversation.peerAddress]) - void refreshConsentList() + await refreshConsentList(); + await allow([conversation.peerAddress]); + void refreshConsentList(); // TODO: check if this is needed // onRequestAllowed(); setIsRequestChangeLoading(false); - } + }; const handleEmojiSelect = (emoji: string) => { if (!reactionMessage) return; @@ -120,7 +139,7 @@ export const Chat: React.FC = ({ conversation, onBack }) => { content: emoji, referenceId: reactionMessage.id, }); - } + }; useEffect(() => { if (messages.length == 0) return; @@ -128,21 +147,22 @@ export const Chat: React.FC = ({ conversation, onBack }) => { const lastMessageId = messages[messages.length - 1]?.id; const element = document.getElementById(lastMessageId); if (element) { - element.scrollIntoView({ behavior: "smooth" }); + element.scrollIntoView({ behavior: 'smooth' }); } }, 500); // await checkMessageIfRead(); - }, [messages, conversation]); - return ( - - +
= ({ conversation, onBack }) => { backgroundColor: 'rgba(255, 255, 255, 0.05)', borderRadius: '16px', - backdropFilter: reactionMessage ? "blur(5px)" : "none", - pointerEvents: reactionMessage ? 'auto' : 'none' + backdropFilter: reactionMessage ? 'blur(5px)' : 'none', + pointerEvents: reactionMessage ? 'auto' : 'none', }} onClick={() => { setReactionMessage(null); - const replica = document.getElementById(`${reactionMessage?.id}-replica`); + const replica = document.getElementById( + `${reactionMessage?.id}-replica` + ); replica?.remove(); }} >
- - - + padding: '10px 1.5rem', + boxShadow: '0px 4px 4px 0px rgba(0, 0, 0, 0.05)', + }} + > + + + - + = ({ conversation, onBack }) => { height: 30, }} /> - -

{primaryName ? primaryName : formatAddress(conversation.peerAddress)}

+ +

+ {primaryName + ? primaryName + : formatAddress(conversation.peerAddress)} +

{/* {(!!primaryName) && (

= ({ conversation, onBack }) => { - + - + - - - + blockAddress(conversation.peerAddress)} > -

Block

- + + gap: '10px', + }} + onClick={() => blockAddress(conversation.peerAddress)} + > +

+ Block +

+
- +
- - { - isCanMessageLoading || isLoading ? ( - + {isCanMessageLoading || isLoading ? ( + - {[...Array(5)].map((_, index) => ( - - ))} - - ) : ( - + {[...Array(5)].map((_, index) => ( + + ))} + + ) : ( + - {canMessage ? ( - + {canMessage ? ( + - {groupedMessages && Object.keys(groupedMessages).map((date, index) => ( - -

{date}

- {groupedMessages[date].map((message) => + flexShrink: 1, + }} + > + {groupedMessages && + Object.keys(groupedMessages).map((date, index) => ( + +

+ {date} +

+ {groupedMessages[date].map((message) => ( setReplyMessage(msg)} @@ -311,9 +402,13 @@ export const Chat: React.FC = ({ conversation, onBack }) => { onReaction={(message) => { setReactionMessage(message); - const element = document.getElementById(message.id.toString()); + const element = document.getElementById( + message.id.toString() + ); if (!element) return; - const replica = element?.cloneNode(true) as HTMLElement; + const replica = element?.cloneNode( + true + ) as HTMLElement; replica.id = `${message.id}-replica`; replica.style.position = 'absolute'; replica.style.top = element?.offsetTop + 'px'; @@ -321,96 +416,124 @@ export const Chat: React.FC = ({ conversation, onBack }) => { replica.style.zIndex = '90'; element?.parentElement?.appendChild(replica); replica.classList.add('replica-animate'); - setEmojiSelectorTop(100 + element.getBoundingClientRect().height); + setEmojiSelectorTop( + 100 + element.getBoundingClientRect().height + ); }} /> - )} + ))}
))} - { - reactionMessage && ( -
- { - handleEmojiSelect(emoji); - setReactionMessage(null); - const replica = document.getElementById(`${reactionMessage?.id}-replica`); - replica?.remove(); - }} - - /> -
- ) - } -
- ) : ( -
-

Cannot message {conversation.peerAddress}

-
- )} -
- ) - } - - { - isRequest ? ( - isRequestChangeLoading ? - - - - : - - - + {reactionMessage && ( +
+ { + handleEmojiSelect(emoji); + setReactionMessage(null); + const replica = document.getElementById( + `${reactionMessage?.id}-replica` + ); + replica?.remove(); + }} + /> +
+ )}
+ ) : ( +
+

Cannot message {conversation.peerAddress}

+
+ )} +
+ )} + + {isRequest ? ( + isRequestChangeLoading ? ( + + + ) : ( - - {isMessagesSenderOnly && ( - + + + + ) + ) : ( + + {isMessagesSenderOnly && ( + -

+

Message in user’s Requests

-

This user has not accepted your message request yet

-
- )} - setReplyMessage(null)} conversation={conversation} replyMessage={replyMessage} /> -
- ) - } + }} + > + Message in user’s Requests +

+

This user has not accepted your message request yet

+
+ )} + setReplyMessage(null)} + conversation={conversation} + replyMessage={replyMessage} + /> +
+ )}
-
+
); }; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx index c4b1f0f3..7fe843ae 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx @@ -1,171 +1,217 @@ import * as Slider from '@radix-ui/react-slider'; import { DecodedMessage } from '@xmtp/xmtp-js'; -import { Flex, P, PauseIcon, PlayIcon } from '@justweb3/ui'; +import { Flex, PauseIcon, PlayIcon } from '@justweb3/ui'; import React, { useEffect, useMemo, useRef, useState } from 'react'; import { MessageWithReaction } from '../../utils/filterReactionsMessages'; import useGetAudioDuration from '../../hooks/useGetAudioDuration'; -import { formatTime } from '../../utils/formatVoiceTime'; -import { formatMessageSentTime } from '../../utils/messageTimeFormat'; - interface VoiceMessageCardProps { - message: MessageWithReaction | DecodedMessage; - style?: React.CSSProperties; - disabled?: boolean; - isReceiver: boolean; - isReply?: boolean; + message: MessageWithReaction | DecodedMessage; + style?: React.CSSProperties; + disabled?: boolean; + isReceiver: boolean; + isReply?: boolean; } const VoiceMessageCard: React.FC = ({ - message, - style, - disabled, - isReceiver, - isReply + message, + style, + disabled, + isReceiver, + isReply, }) => { - const [playing, setPlaying] = useState(false); - const [currentTime, setCurrentTime] = useState(0); - const audioRef = useRef(new Audio()); - - - const audioUrl = useMemo(() => { - const blob = new Blob([message.content.data], { type: message.content.mimeType }); - return URL.createObjectURL(blob); - }, [message.content]); - - const duration = useGetAudioDuration(audioUrl); - - useEffect(() => { - const audio = audioRef.current; + const [playing, setPlaying] = useState(false); + const [currentTime, setCurrentTime] = useState(0); + const audioRef = useRef(new Audio()); - const onTimeUpdate = () => { - setCurrentTime(audio.currentTime); - }; + const audioUrl = useMemo(() => { + const blob = new Blob([message.content.data], { + type: message.content.mimeType, + }); + return URL.createObjectURL(blob); + }, [message.content]); - const onEnded = () => { - setPlaying(false); - setCurrentTime(0); - }; + const duration = useGetAudioDuration(audioUrl); - audio.src = audioUrl; - audio.preload = 'metadata'; - audio.addEventListener('timeupdate', onTimeUpdate); - audio.addEventListener('ended', onEnded); + useEffect(() => { + const audio = audioRef.current; - return () => { - audio.removeEventListener('timeupdate', onTimeUpdate); - audio.removeEventListener('ended', onEnded); - }; - }, [message.content, audioUrl]); - - - const handlePlayPause = () => { - if (disabled) return; - const audio = audioRef.current; - if (playing) { - audio.pause(); - } else { - audio.play(); - } - setPlaying(!playing); + const onTimeUpdate = () => { + setCurrentTime(audio.currentTime); }; - const handleSliderChange = (value: number[]) => { - const audio = audioRef.current; - if (playing) { - audio.pause(); - setPlaying(false); - audio.currentTime = value[0]; - setCurrentTime(value[0]); - audio.play(); - setPlaying(true); - } else { - audio.currentTime = value[0]; - setCurrentTime(value[0]); - } + const onEnded = () => { + setPlaying(false); + setCurrentTime(0); }; - return ( - - {playing ? ( - - ) : ( - - )} - + audio.src = audioUrl; + audio.preload = 'metadata'; + audio.addEventListener('timeupdate', onTimeUpdate); + audio.addEventListener('ended', onEnded); - 0 ? audioRef.current.currentTime : 0]} max={duration ?? 0} step={0.01}> - - - - - - -

{playing || currentTime > 0 ? formatTime(currentTime) : formatTime(duration ?? 0)}

- {!isReply && ( -

{formatMessageSentTime(message.sentAt)}

- )} -
-
-
- ); + return () => { + audio.removeEventListener('timeupdate', onTimeUpdate); + audio.removeEventListener('ended', onEnded); + }; + }, [message.content, audioUrl]); + + const handlePlayPause = () => { + if (disabled) return; + const audio = audioRef.current; + if (playing) { + audio.pause(); + } else { + audio.play(); + } + setPlaying(!playing); + }; + + const handleSliderChange = (value: number[]) => { + const audio = audioRef.current; + if (playing) { + audio.pause(); + setPlaying(false); + audio.currentTime = value[0]; + setCurrentTime(value[0]); + audio.play(); + setPlaying(true); + } else { + audio.currentTime = value[0]; + setCurrentTime(value[0]); + } + }; + + return ( + + {playing ? ( + + ) : ( + + )} + + 0 ? audioRef.current.currentTime : 0, + ]} + max={duration ?? 0} + step={0.01} + > + + + + + + {/**/} + {/*

{playing || currentTime > 0 ? formatTime(currentTime) : formatTime(duration ?? 0)}

*/} + {/* {!isReply && (*/} + {/*

{formatMessageSentTime(message.sentAt)}

*/} + {/* )}*/} + {/*
*/} +
+
+ ); }; export default VoiceMessageCard; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendAttachment/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendAttachment/index.ts index a39b4c82..df0f8a14 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendAttachment/index.ts +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendAttachment/index.ts @@ -4,9 +4,9 @@ import type { Attachment } from '@xmtp/content-type-remote-attachment'; import { ContentTypeAttachment } from '@xmtp/content-type-remote-attachment'; import { CachedConversation, - useSendMessage, - SendOptions, DecodedMessage, + SendOptions, + useSendMessage, } from '@xmtp/react-sdk'; export const sendAttachment = async ( @@ -22,7 +22,7 @@ export const sendAttachment = async ( try { await sendMessage(conversation, attachment, ContentTypeAttachment); } catch (e) { - const error = e as Error; + // const error = e as Error; } }; diff --git a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx index 42b6fef5..a622ef32 100644 --- a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx +++ b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx @@ -17,6 +17,10 @@ import { mainnet, sepolia } from 'wagmi/chains'; import { XMTPPlugin } from '../lib'; import { ChainId } from '@justaname.id/sdk'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; +import { EFPPlugin } from '@justweb3/efp-plugin'; +import { POAPPlugin } from '@justweb3/poap-plugin'; +import { TalentProtocolPlugin } from '@justweb3/talent-protocol-plugin'; +import { JustVerifiedPlugin } from '@justverified/plugin'; const queryClient = new QueryClient(); @@ -46,7 +50,17 @@ const JustWeb3Config: JustWeb3ProviderConfig = { openOnWalletConnect: false, allowedEns: 'all', dev: import.meta.env.STORYBOOK_APP_DEV === 'true', - plugins: [XMTPPlugin], + plugins: [ + XMTPPlugin, + EFPPlugin, + POAPPlugin({ + apiKey: import.meta.env.STORYBOOK_APP_POAP_KEY, + }), + TalentProtocolPlugin({ + apiKey: import.meta.env.STORYBOOK_APP_TALENT_PROTOCOL_API_KEY, + }), + JustVerifiedPlugin(['email', 'telegram', 'twitter', 'discord']), + ], // color: { // primary: '#FF00FF', // background: '#000000', From 9f972d52fd0a39a529262052c91573c8c45332f3 Mon Sep 17 00:00:00 2001 From: Ghadi8 Date: Fri, 29 Nov 2024 13:42:09 +0000 Subject: [PATCH 08/29] chore(release): publish [skip ci] - project: @justaname.id/sdk 0.2.147 - project: @justaname.id/react 0.3.150 - project: @justaname.id/siwens 0.0.80 - project: @justweb3/ui 0.0.86 - project: @justweb3/widget 0.0.86 - project: @justverified/plugin 0.0.85 - project: @justweb3/efp-plugin 0.1.46 - project: @justweb3/poap-plugin 0.0.4 - project: @justweb3/talent-protocol-plugin 0.0.4 --- packages/@justaname.id/react/CHANGELOG.md | 43 ++++++++++++++ packages/@justaname.id/react/package.json | 4 +- packages/@justaname.id/sdk/CHANGELOG.md | 35 +++++++++++ packages/@justaname.id/sdk/package.json | 4 +- packages/@justaname.id/siwens/CHANGELOG.md | 22 +++++++ packages/@justaname.id/siwens/package.json | 2 +- packages/@justverified/plugin/CHANGELOG.md | 35 +++++++++++ packages/@justverified/plugin/package.json | 2 +- packages/@justweb3/efp-plugin/CHANGELOG.md | 28 +++++++++ packages/@justweb3/efp-plugin/package.json | 2 +- packages/@justweb3/poap-plugin/package.json | 2 +- .../talent-protocol-plugin/package.json | 2 +- packages/@justweb3/ui/CHANGELOG.md | 39 +++++++++++++ packages/@justweb3/ui/package.json | 2 +- packages/@justweb3/widget/CHANGELOG.md | 58 +++++++++++++++++++ packages/@justweb3/widget/package.json | 8 +-- yarn.lock | 18 +++--- 17 files changed, 283 insertions(+), 23 deletions(-) diff --git a/packages/@justaname.id/react/CHANGELOG.md b/packages/@justaname.id/react/CHANGELOG.md index 5944fd22..c4546fc0 100644 --- a/packages/@justaname.id/react/CHANGELOG.md +++ b/packages/@justaname.id/react/CHANGELOG.md @@ -1,3 +1,46 @@ +## 0.3.150 (2024-11-29) + + +### 🚀 Features + +- remove mapps from justverified ([2898c521](https://github.com/JustaName-id/JustaName-sdk/commit/2898c521)) + +- efp ([36fcc153](https://github.com/JustaName-id/JustaName-sdk/commit/36fcc153)) + +- efp and storybook for react sdk ([f0c5c7a0](https://github.com/JustaName-id/JustaName-sdk/commit/f0c5c7a0)) + +- console fixes ([358b3a0e](https://github.com/JustaName-id/JustaName-sdk/commit/358b3a0e)) + +- added docs and the sign in should only show ens set to default resolver or justaname resolver only ([a3bcecaa](https://github.com/JustaName-id/JustaName-sdk/commit/a3bcecaa)) + +- enabled in hooks and siwens fix and coinbase fix ([c3fb455e](https://github.com/JustaName-id/JustaName-sdk/commit/c3fb455e)) + +- retryOnMount false ([bec00ba8](https://github.com/JustaName-id/JustaName-sdk/commit/bec00ba8)) + + +### 🩹 Fixes + +- packages ([6dd450f5](https://github.com/JustaName-id/JustaName-sdk/commit/6dd450f5)) + +- lint fix on react and package json of projects ([b29cd296](https://github.com/JustaName-id/JustaName-sdk/commit/b29cd296)) + +- error from useEnsWalletClient ([67043376](https://github.com/JustaName-id/JustaName-sdk/commit/67043376)) + +- update rest call and ui fixes ([81b05f29](https://github.com/JustaName-id/JustaName-sdk/commit/81b05f29)) + +- poap default options ([eb5d1c36](https://github.com/JustaName-id/JustaName-sdk/commit/eb5d1c36)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.147 + + +### ❤️ Thank You + +- anthony2399 @anthony23991 +- HadiKhai + ## 0.3.149 (2024-11-15) diff --git a/packages/@justaname.id/react/package.json b/packages/@justaname.id/react/package.json index c7e321d5..96b3d268 100644 --- a/packages/@justaname.id/react/package.json +++ b/packages/@justaname.id/react/package.json @@ -1,9 +1,9 @@ { "name": "@justaname.id/react", - "version": "0.3.149", + "version": "0.3.150", "dependencies": { "@ensdomains/ensjs": "4.0.2", - "@justaname.id/sdk": "0.2.146", + "@justaname.id/sdk": "0.2.147", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/sdk/CHANGELOG.md b/packages/@justaname.id/sdk/CHANGELOG.md index c520ec0c..c35dc818 100644 --- a/packages/@justaname.id/sdk/CHANGELOG.md +++ b/packages/@justaname.id/sdk/CHANGELOG.md @@ -1,3 +1,38 @@ +## 0.2.147 (2024-11-29) + + +### 🚀 Features + +- efp ([36fcc153](https://github.com/JustaName-id/JustaName-sdk/commit/36fcc153)) + +- console fixes ([358b3a0e](https://github.com/JustaName-id/JustaName-sdk/commit/358b3a0e)) + +- added docs and the sign in should only show ens set to default resolver or justaname resolver only ([a3bcecaa](https://github.com/JustaName-id/JustaName-sdk/commit/a3bcecaa)) + +- sdk signin fix for aa wallets ([52944a72](https://github.com/JustaName-id/JustaName-sdk/commit/52944a72)) + +- enabled in hooks and siwens fix and coinbase fix ([c3fb455e](https://github.com/JustaName-id/JustaName-sdk/commit/c3fb455e)) + +- cache provider url to reduce calls ([d4943d0b](https://github.com/JustaName-id/JustaName-sdk/commit/d4943d0b)) + + +### 🩹 Fixes + +- update rest call and ui fixes ([81b05f29](https://github.com/JustaName-id/JustaName-sdk/commit/81b05f29)) + +- justaname network and widget package json ([6afe04ce](https://github.com/JustaName-id/JustaName-sdk/commit/6afe04ce)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/siwens to 0.0.80 + + +### ❤️ Thank You + +- anthony2399 @anthony23991 +- HadiKhai + ## 0.2.146 (2024-11-15) diff --git a/packages/@justaname.id/sdk/package.json b/packages/@justaname.id/sdk/package.json index a03d998a..380be8fe 100644 --- a/packages/@justaname.id/sdk/package.json +++ b/packages/@justaname.id/sdk/package.json @@ -1,8 +1,8 @@ { "name": "@justaname.id/sdk", - "version": "0.2.146", + "version": "0.2.147", "dependencies": { - "@justaname.id/siwens": "0.0.79", + "@justaname.id/siwens": "0.0.80", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/siwens/CHANGELOG.md b/packages/@justaname.id/siwens/CHANGELOG.md index 29c21301..4bd723ad 100644 --- a/packages/@justaname.id/siwens/CHANGELOG.md +++ b/packages/@justaname.id/siwens/CHANGELOG.md @@ -1,3 +1,25 @@ +## 0.0.80 (2024-11-29) + + +### 🚀 Features + +- added docs and the sign in should only show ens set to default resolver or justaname resolver only ([a3bcecaa](https://github.com/JustaName-id/JustaName-sdk/commit/a3bcecaa)) + +- sdk signin fix for aa wallets ([52944a72](https://github.com/JustaName-id/JustaName-sdk/commit/52944a72)) + +- enabled in hooks and siwens fix and coinbase fix ([c3fb455e](https://github.com/JustaName-id/JustaName-sdk/commit/c3fb455e)) + + +### 🩹 Fixes + +- update rest call and ui fixes ([81b05f29](https://github.com/JustaName-id/JustaName-sdk/commit/81b05f29)) + + +### ❤️ Thank You + +- anthony2399 @anthony23991 +- HadiKhai + ## 0.0.79 (2024-11-15) This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. diff --git a/packages/@justaname.id/siwens/package.json b/packages/@justaname.id/siwens/package.json index f9bd6a16..ffa15859 100644 --- a/packages/@justaname.id/siwens/package.json +++ b/packages/@justaname.id/siwens/package.json @@ -1,6 +1,6 @@ { "name": "@justaname.id/siwens", - "version": "0.0.79", + "version": "0.0.80", "peerDependencies": { "ethers": ">=6.0.0", "siwe": ">=2.0.0" diff --git a/packages/@justverified/plugin/CHANGELOG.md b/packages/@justverified/plugin/CHANGELOG.md index 32447882..60b73a84 100644 --- a/packages/@justverified/plugin/CHANGELOG.md +++ b/packages/@justverified/plugin/CHANGELOG.md @@ -1,3 +1,38 @@ +## 0.0.85 (2024-11-29) + + +### 🚀 Features + +- remove mapps from justverified ([2898c521](https://github.com/JustaName-id/JustaName-sdk/commit/2898c521)) + +- efp ([36fcc153](https://github.com/JustaName-id/JustaName-sdk/commit/36fcc153)) + +- efp and storybook for react sdk ([f0c5c7a0](https://github.com/JustaName-id/JustaName-sdk/commit/f0c5c7a0)) + +- console fixes ([358b3a0e](https://github.com/JustaName-id/JustaName-sdk/commit/358b3a0e)) + +- added docs and the sign in should only show ens set to default resolver or justaname resolver only ([a3bcecaa](https://github.com/JustaName-id/JustaName-sdk/commit/a3bcecaa)) + +- move justweb3 to peer dep in the plugins ([316047cb](https://github.com/JustaName-id/JustaName-sdk/commit/316047cb)) + +- rainbow and privy examples ([fb2aa7dc](https://github.com/JustaName-id/JustaName-sdk/commit/fb2aa7dc)) + +- dialog fixes and logo needs to be fixed ([fad47312](https://github.com/JustaName-id/JustaName-sdk/commit/fad47312)) + +- **widget:** mobile dialogs ([#51](https://github.com/JustaName-id/JustaName-sdk/pull/51)) + + +### 🩹 Fixes + +- update rest call and ui fixes ([81b05f29](https://github.com/JustaName-id/JustaName-sdk/commit/81b05f29)) + + +### ❤️ Thank You + +- Anthony Khoury @anthony23991 +- anthony2399 @anthony23991 +- HadiKhai + ## 0.0.84 (2024-11-15) This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. diff --git a/packages/@justverified/plugin/package.json b/packages/@justverified/plugin/package.json index ea512de6..a168eba0 100644 --- a/packages/@justverified/plugin/package.json +++ b/packages/@justverified/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justverified/plugin", - "version": "0.0.84", + "version": "0.0.85", "dependencies": { "axios": "^1.6.0", "lodash": "4.17.21", diff --git a/packages/@justweb3/efp-plugin/CHANGELOG.md b/packages/@justweb3/efp-plugin/CHANGELOG.md index fa5523e5..c3431875 100644 --- a/packages/@justweb3/efp-plugin/CHANGELOG.md +++ b/packages/@justweb3/efp-plugin/CHANGELOG.md @@ -1,3 +1,31 @@ +## 0.1.46 (2024-11-29) + + +### 🚀 Features + +- move justweb3 to peer dep in the plugins ([316047cb](https://github.com/JustaName-id/JustaName-sdk/commit/316047cb)) + +- sdk signin fix for aa wallets ([52944a72](https://github.com/JustaName-id/JustaName-sdk/commit/52944a72)) + +- enabled in hooks and siwens fix and coinbase fix ([c3fb455e](https://github.com/JustaName-id/JustaName-sdk/commit/c3fb455e)) + + +### 🩹 Fixes + +- lint fix on react and package json of projects ([b29cd296](https://github.com/JustaName-id/JustaName-sdk/commit/b29cd296)) + +- update rest call and ui fixes ([81b05f29](https://github.com/JustaName-id/JustaName-sdk/commit/81b05f29)) + +- yarn lock ([98e8b8b2](https://github.com/JustaName-id/JustaName-sdk/commit/98e8b8b2)) + +- justweb3button infinite loading ([465453ca](https://github.com/JustaName-id/JustaName-sdk/commit/465453ca)) + + +### ❤️ Thank You + +- anthony2399 @anthony23991 +- HadiKhai + ## 0.1.45 (2024-11-15) This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/efp-plugin/package.json b/packages/@justweb3/efp-plugin/package.json index 1f362b62..920ff7f8 100644 --- a/packages/@justweb3/efp-plugin/package.json +++ b/packages/@justweb3/efp-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/efp-plugin", - "version": "0.1.45", + "version": "0.1.46", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/poap-plugin/package.json b/packages/@justweb3/poap-plugin/package.json index bfea4b4d..0a4c4985 100644 --- a/packages/@justweb3/poap-plugin/package.json +++ b/packages/@justweb3/poap-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/poap-plugin", - "version": "0.0.3", + "version": "0.0.4", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/talent-protocol-plugin/package.json b/packages/@justweb3/talent-protocol-plugin/package.json index 10fd0f85..21eff532 100644 --- a/packages/@justweb3/talent-protocol-plugin/package.json +++ b/packages/@justweb3/talent-protocol-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/talent-protocol-plugin", - "version": "0.0.3", + "version": "0.0.4", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/ui/CHANGELOG.md b/packages/@justweb3/ui/CHANGELOG.md index a31b9d96..8cdedb89 100644 --- a/packages/@justweb3/ui/CHANGELOG.md +++ b/packages/@justweb3/ui/CHANGELOG.md @@ -1,3 +1,42 @@ +## 0.0.86 (2024-11-29) + + +### 🚀 Features + +- remove mapps from justverified ([2898c521](https://github.com/JustaName-id/JustaName-sdk/commit/2898c521)) + +- efp ([36fcc153](https://github.com/JustaName-id/JustaName-sdk/commit/36fcc153)) + +- efp and storybook for react sdk ([f0c5c7a0](https://github.com/JustaName-id/JustaName-sdk/commit/f0c5c7a0)) + +- added docs and the sign in should only show ens set to default resolver or justaname resolver only ([a3bcecaa](https://github.com/JustaName-id/JustaName-sdk/commit/a3bcecaa)) + +- move justweb3 to peer dep in the plugins ([316047cb](https://github.com/JustaName-id/JustaName-sdk/commit/316047cb)) + +- sdk signin fix for aa wallets ([52944a72](https://github.com/JustaName-id/JustaName-sdk/commit/52944a72)) + +- rainbow and privy examples ([fb2aa7dc](https://github.com/JustaName-id/JustaName-sdk/commit/fb2aa7dc)) + +- dialog fixes and logo needs to be fixed ([fad47312](https://github.com/JustaName-id/JustaName-sdk/commit/fad47312)) + +- expandableCard ([#54](https://github.com/JustaName-id/JustaName-sdk/pull/54)) + +- packagejson fixes ([873f9967](https://github.com/JustaName-id/JustaName-sdk/commit/873f9967)) + +- **widget:** mobile dialogs ([#51](https://github.com/JustaName-id/JustaName-sdk/pull/51)) + + +### 🩹 Fixes + +- update rest call and ui fixes ([81b05f29](https://github.com/JustaName-id/JustaName-sdk/commit/81b05f29)) + + +### ❤️ Thank You + +- Anthony Khoury @anthony23991 +- anthony2399 @anthony23991 +- HadiKhai + ## 0.0.85 (2024-11-15) This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/ui/package.json b/packages/@justweb3/ui/package.json index a59b2553..ba6bf1ec 100644 --- a/packages/@justweb3/ui/package.json +++ b/packages/@justweb3/ui/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/ui", - "version": "0.0.85", + "version": "0.0.86", "dependencies": { "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dialog": "^1.1.1", diff --git a/packages/@justweb3/widget/CHANGELOG.md b/packages/@justweb3/widget/CHANGELOG.md index 43ac416b..dff100bc 100644 --- a/packages/@justweb3/widget/CHANGELOG.md +++ b/packages/@justweb3/widget/CHANGELOG.md @@ -1,3 +1,61 @@ +## 0.0.86 (2024-11-29) + + +### 🚀 Features + +- remove mapps from justverified ([2898c521](https://github.com/JustaName-id/JustaName-sdk/commit/2898c521)) + +- efp ([36fcc153](https://github.com/JustaName-id/JustaName-sdk/commit/36fcc153)) + +- efp and storybook for react sdk ([f0c5c7a0](https://github.com/JustaName-id/JustaName-sdk/commit/f0c5c7a0)) + +- console fixes ([358b3a0e](https://github.com/JustaName-id/JustaName-sdk/commit/358b3a0e)) + +- added docs and the sign in should only show ens set to default resolver or justaname resolver only ([a3bcecaa](https://github.com/JustaName-id/JustaName-sdk/commit/a3bcecaa)) + +- sdk signin fix for aa wallets ([52944a72](https://github.com/JustaName-id/JustaName-sdk/commit/52944a72)) + +- rainbow and privy examples ([fb2aa7dc](https://github.com/JustaName-id/JustaName-sdk/commit/fb2aa7dc)) + +- remove currentChain ([43e8b6d6](https://github.com/JustaName-id/JustaName-sdk/commit/43e8b6d6)) + +- dialog fixes and logo needs to be fixed ([fad47312](https://github.com/JustaName-id/JustaName-sdk/commit/fad47312)) + +- expandableCard ([#54](https://github.com/JustaName-id/JustaName-sdk/pull/54)) + +- community members tab ([#55](https://github.com/JustaName-id/JustaName-sdk/pull/55)) + +- enabled in hooks and siwens fix and coinbase fix ([c3fb455e](https://github.com/JustaName-id/JustaName-sdk/commit/c3fb455e)) + +- community button and release action ([0015df77](https://github.com/JustaName-id/JustaName-sdk/commit/0015df77)) + +- **widget:** mobile dialogs ([#51](https://github.com/JustaName-id/JustaName-sdk/pull/51)) + + +### 🩹 Fixes + +- error from useEnsWalletClient ([67043376](https://github.com/JustaName-id/JustaName-sdk/commit/67043376)) + +- update rest call and ui fixes ([81b05f29](https://github.com/JustaName-id/JustaName-sdk/commit/81b05f29)) + +- justweb3button infinite loading ([465453ca](https://github.com/JustaName-id/JustaName-sdk/commit/465453ca)) + +- justaname network and widget package json ([6afe04ce](https://github.com/JustaName-id/JustaName-sdk/commit/6afe04ce)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.147 +- Updated @justaname.id/react to 0.3.150 +- Updated @justweb3/ui to 0.0.86 + + +### ❤️ Thank You + +- Anthony Khoury @anthony23991 +- anthony2399 @anthony23991 +- HadiKhai + ## 0.0.85 (2024-11-15) diff --git a/packages/@justweb3/widget/package.json b/packages/@justweb3/widget/package.json index 7a307ae9..e3e7013b 100644 --- a/packages/@justweb3/widget/package.json +++ b/packages/@justweb3/widget/package.json @@ -1,12 +1,12 @@ { "name": "@justweb3/widget", - "version": "0.0.85", + "version": "0.0.86", "dependencies": { "@ensdomains/address-encoder": "^1.1.2", "@hookform/resolvers": "^3.9.0", - "@justaname.id/react": "0.3.149", - "@justaname.id/sdk": "0.2.146", - "@justweb3/ui": "^0.0.85", + "@justaname.id/react": "0.3.150", + "@justaname.id/sdk": "0.2.147", + "@justweb3/ui": "^0.0.86", "clsx": "1.2.1", "cropperjs": "^1.6.2", "lodash": "4.17.21", diff --git a/yarn.lock b/yarn.lock index 25fd2303..19d37095 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4514,12 +4514,12 @@ __metadata: languageName: node linkType: hard -"@justaname.id/react@npm:0.3.149, @justaname.id/react@workspace:packages/@justaname.id/react": +"@justaname.id/react@npm:0.3.150, @justaname.id/react@workspace:packages/@justaname.id/react": version: 0.0.0-use.local resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" dependencies: "@ensdomains/ensjs": "npm:4.0.2" - "@justaname.id/sdk": "npm:0.2.146" + "@justaname.id/sdk": "npm:0.2.147" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4532,11 +4532,11 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/sdk@npm:0.2.146, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": +"@justaname.id/sdk@npm:0.2.147, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": version: 0.0.0-use.local resolution: "@justaname.id/sdk@workspace:packages/@justaname.id/sdk" dependencies: - "@justaname.id/siwens": "npm:0.0.79" + "@justaname.id/siwens": "npm:0.0.80" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4547,7 +4547,7 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/siwens@npm:0.0.79, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": +"@justaname.id/siwens@npm:0.0.80, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": version: 0.0.0-use.local resolution: "@justaname.id/siwens@workspace:packages/@justaname.id/siwens" peerDependencies: @@ -4607,7 +4607,7 @@ __metadata: languageName: unknown linkType: soft -"@justweb3/ui@npm:^0.0.85, @justweb3/ui@workspace:packages/@justweb3/ui": +"@justweb3/ui@npm:^0.0.86, @justweb3/ui@workspace:packages/@justweb3/ui": version: 0.0.0-use.local resolution: "@justweb3/ui@workspace:packages/@justweb3/ui" dependencies: @@ -4635,9 +4635,9 @@ __metadata: dependencies: "@ensdomains/address-encoder": "npm:^1.1.2" "@hookform/resolvers": "npm:^3.9.0" - "@justaname.id/react": "npm:0.3.149" - "@justaname.id/sdk": "npm:0.2.146" - "@justweb3/ui": "npm:^0.0.85" + "@justaname.id/react": "npm:0.3.150" + "@justaname.id/sdk": "npm:0.2.147" + "@justweb3/ui": "npm:^0.0.86" clsx: "npm:1.2.1" cropperjs: "npm:^1.6.2" lodash: "npm:4.17.21" From 4fb3c2aec12a75663351bd2acbc59c1467e0d88d Mon Sep 17 00:00:00 2001 From: Ghadi8 Date: Fri, 29 Nov 2024 13:49:18 +0000 Subject: [PATCH 09/29] chore(release): publish [skip ci] - project: @justaname.id/sdk 0.2.148 - project: @justaname.id/react 0.3.151 - project: @justaname.id/siwens 0.0.81 - project: @justweb3/ui 0.0.87 - project: @justweb3/widget 0.0.87 - project: @justverified/plugin 0.0.86 - project: @justweb3/efp-plugin 0.1.47 - project: @justweb3/poap-plugin 0.0.5 - project: @justweb3/talent-protocol-plugin 0.0.5 --- packages/@justaname.id/react/CHANGELOG.md | 7 +++++++ packages/@justaname.id/react/package.json | 4 ++-- packages/@justaname.id/sdk/CHANGELOG.md | 7 +++++++ packages/@justaname.id/sdk/package.json | 4 ++-- packages/@justaname.id/siwens/CHANGELOG.md | 4 ++++ packages/@justaname.id/siwens/package.json | 2 +- packages/@justverified/plugin/CHANGELOG.md | 4 ++++ packages/@justverified/plugin/package.json | 2 +- packages/@justweb3/efp-plugin/CHANGELOG.md | 4 ++++ packages/@justweb3/efp-plugin/package.json | 2 +- packages/@justweb3/poap-plugin/package.json | 2 +- .../talent-protocol-plugin/package.json | 2 +- packages/@justweb3/ui/CHANGELOG.md | 4 ++++ packages/@justweb3/ui/package.json | 2 +- packages/@justweb3/widget/CHANGELOG.md | 9 +++++++++ packages/@justweb3/widget/package.json | 8 ++++---- yarn.lock | 18 +++++++++--------- 17 files changed, 62 insertions(+), 23 deletions(-) diff --git a/packages/@justaname.id/react/CHANGELOG.md b/packages/@justaname.id/react/CHANGELOG.md index c4546fc0..8594993d 100644 --- a/packages/@justaname.id/react/CHANGELOG.md +++ b/packages/@justaname.id/react/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.3.151 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.148 + ## 0.3.150 (2024-11-29) diff --git a/packages/@justaname.id/react/package.json b/packages/@justaname.id/react/package.json index 96b3d268..cd859807 100644 --- a/packages/@justaname.id/react/package.json +++ b/packages/@justaname.id/react/package.json @@ -1,9 +1,9 @@ { "name": "@justaname.id/react", - "version": "0.3.150", + "version": "0.3.151", "dependencies": { "@ensdomains/ensjs": "4.0.2", - "@justaname.id/sdk": "0.2.147", + "@justaname.id/sdk": "0.2.148", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/sdk/CHANGELOG.md b/packages/@justaname.id/sdk/CHANGELOG.md index c35dc818..c368d6e2 100644 --- a/packages/@justaname.id/sdk/CHANGELOG.md +++ b/packages/@justaname.id/sdk/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.2.148 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/siwens to 0.0.81 + ## 0.2.147 (2024-11-29) diff --git a/packages/@justaname.id/sdk/package.json b/packages/@justaname.id/sdk/package.json index 380be8fe..85ecde81 100644 --- a/packages/@justaname.id/sdk/package.json +++ b/packages/@justaname.id/sdk/package.json @@ -1,8 +1,8 @@ { "name": "@justaname.id/sdk", - "version": "0.2.147", + "version": "0.2.148", "dependencies": { - "@justaname.id/siwens": "0.0.80", + "@justaname.id/siwens": "0.0.81", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/siwens/CHANGELOG.md b/packages/@justaname.id/siwens/CHANGELOG.md index 4bd723ad..707ac808 100644 --- a/packages/@justaname.id/siwens/CHANGELOG.md +++ b/packages/@justaname.id/siwens/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.81 (2024-11-29) + +This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. + ## 0.0.80 (2024-11-29) diff --git a/packages/@justaname.id/siwens/package.json b/packages/@justaname.id/siwens/package.json index ffa15859..d40afdbd 100644 --- a/packages/@justaname.id/siwens/package.json +++ b/packages/@justaname.id/siwens/package.json @@ -1,6 +1,6 @@ { "name": "@justaname.id/siwens", - "version": "0.0.80", + "version": "0.0.81", "peerDependencies": { "ethers": ">=6.0.0", "siwe": ">=2.0.0" diff --git a/packages/@justverified/plugin/CHANGELOG.md b/packages/@justverified/plugin/CHANGELOG.md index 60b73a84..16790ccb 100644 --- a/packages/@justverified/plugin/CHANGELOG.md +++ b/packages/@justverified/plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.86 (2024-11-29) + +This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. + ## 0.0.85 (2024-11-29) diff --git a/packages/@justverified/plugin/package.json b/packages/@justverified/plugin/package.json index a168eba0..747acdcc 100644 --- a/packages/@justverified/plugin/package.json +++ b/packages/@justverified/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justverified/plugin", - "version": "0.0.85", + "version": "0.0.86", "dependencies": { "axios": "^1.6.0", "lodash": "4.17.21", diff --git a/packages/@justweb3/efp-plugin/CHANGELOG.md b/packages/@justweb3/efp-plugin/CHANGELOG.md index c3431875..c588e44f 100644 --- a/packages/@justweb3/efp-plugin/CHANGELOG.md +++ b/packages/@justweb3/efp-plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.47 (2024-11-29) + +This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. + ## 0.1.46 (2024-11-29) diff --git a/packages/@justweb3/efp-plugin/package.json b/packages/@justweb3/efp-plugin/package.json index 920ff7f8..439df8aa 100644 --- a/packages/@justweb3/efp-plugin/package.json +++ b/packages/@justweb3/efp-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/efp-plugin", - "version": "0.1.46", + "version": "0.1.47", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/poap-plugin/package.json b/packages/@justweb3/poap-plugin/package.json index 0a4c4985..98d7cf62 100644 --- a/packages/@justweb3/poap-plugin/package.json +++ b/packages/@justweb3/poap-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/poap-plugin", - "version": "0.0.4", + "version": "0.0.5", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/talent-protocol-plugin/package.json b/packages/@justweb3/talent-protocol-plugin/package.json index 21eff532..4467fb5f 100644 --- a/packages/@justweb3/talent-protocol-plugin/package.json +++ b/packages/@justweb3/talent-protocol-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/talent-protocol-plugin", - "version": "0.0.4", + "version": "0.0.5", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/ui/CHANGELOG.md b/packages/@justweb3/ui/CHANGELOG.md index 8cdedb89..b3e5bbb9 100644 --- a/packages/@justweb3/ui/CHANGELOG.md +++ b/packages/@justweb3/ui/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.87 (2024-11-29) + +This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. + ## 0.0.86 (2024-11-29) diff --git a/packages/@justweb3/ui/package.json b/packages/@justweb3/ui/package.json index ba6bf1ec..5014ef52 100644 --- a/packages/@justweb3/ui/package.json +++ b/packages/@justweb3/ui/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/ui", - "version": "0.0.86", + "version": "0.0.87", "dependencies": { "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dialog": "^1.1.1", diff --git a/packages/@justweb3/widget/CHANGELOG.md b/packages/@justweb3/widget/CHANGELOG.md index dff100bc..42f24e21 100644 --- a/packages/@justweb3/widget/CHANGELOG.md +++ b/packages/@justweb3/widget/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.0.87 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.148 +- Updated @justaname.id/react to 0.3.151 +- Updated @justweb3/ui to 0.0.87 + ## 0.0.86 (2024-11-29) diff --git a/packages/@justweb3/widget/package.json b/packages/@justweb3/widget/package.json index e3e7013b..4d6d7f52 100644 --- a/packages/@justweb3/widget/package.json +++ b/packages/@justweb3/widget/package.json @@ -1,12 +1,12 @@ { "name": "@justweb3/widget", - "version": "0.0.86", + "version": "0.0.87", "dependencies": { "@ensdomains/address-encoder": "^1.1.2", "@hookform/resolvers": "^3.9.0", - "@justaname.id/react": "0.3.150", - "@justaname.id/sdk": "0.2.147", - "@justweb3/ui": "^0.0.86", + "@justaname.id/react": "0.3.151", + "@justaname.id/sdk": "0.2.148", + "@justweb3/ui": "^0.0.87", "clsx": "1.2.1", "cropperjs": "^1.6.2", "lodash": "4.17.21", diff --git a/yarn.lock b/yarn.lock index 19d37095..9307c585 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4514,12 +4514,12 @@ __metadata: languageName: node linkType: hard -"@justaname.id/react@npm:0.3.150, @justaname.id/react@workspace:packages/@justaname.id/react": +"@justaname.id/react@npm:0.3.151, @justaname.id/react@workspace:packages/@justaname.id/react": version: 0.0.0-use.local resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" dependencies: "@ensdomains/ensjs": "npm:4.0.2" - "@justaname.id/sdk": "npm:0.2.147" + "@justaname.id/sdk": "npm:0.2.148" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4532,11 +4532,11 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/sdk@npm:0.2.147, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": +"@justaname.id/sdk@npm:0.2.148, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": version: 0.0.0-use.local resolution: "@justaname.id/sdk@workspace:packages/@justaname.id/sdk" dependencies: - "@justaname.id/siwens": "npm:0.0.80" + "@justaname.id/siwens": "npm:0.0.81" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4547,7 +4547,7 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/siwens@npm:0.0.80, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": +"@justaname.id/siwens@npm:0.0.81, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": version: 0.0.0-use.local resolution: "@justaname.id/siwens@workspace:packages/@justaname.id/siwens" peerDependencies: @@ -4607,7 +4607,7 @@ __metadata: languageName: unknown linkType: soft -"@justweb3/ui@npm:^0.0.86, @justweb3/ui@workspace:packages/@justweb3/ui": +"@justweb3/ui@npm:^0.0.87, @justweb3/ui@workspace:packages/@justweb3/ui": version: 0.0.0-use.local resolution: "@justweb3/ui@workspace:packages/@justweb3/ui" dependencies: @@ -4635,9 +4635,9 @@ __metadata: dependencies: "@ensdomains/address-encoder": "npm:^1.1.2" "@hookform/resolvers": "npm:^3.9.0" - "@justaname.id/react": "npm:0.3.150" - "@justaname.id/sdk": "npm:0.2.147" - "@justweb3/ui": "npm:^0.0.86" + "@justaname.id/react": "npm:0.3.151" + "@justaname.id/sdk": "npm:0.2.148" + "@justweb3/ui": "npm:^0.0.87" clsx: "npm:1.2.1" cropperjs: "npm:^1.6.2" lodash: "npm:4.17.21" From af15cbfe58574c6f21ab51fee4e152dd2dce2c7e Mon Sep 17 00:00:00 2001 From: Ghadi8 Date: Fri, 29 Nov 2024 14:00:22 +0000 Subject: [PATCH 10/29] chore(release): publish [skip ci] - project: @justaname.id/sdk 0.2.149 - project: @justaname.id/react 0.3.152 - project: @justaname.id/siwens 0.0.82 - project: @justweb3/ui 0.0.88 - project: @justweb3/widget 0.0.88 - project: @justverified/plugin 0.0.87 - project: @justweb3/efp-plugin 0.1.48 - project: @justweb3/poap-plugin 0.0.6 - project: @justweb3/talent-protocol-plugin 0.0.6 --- packages/@justaname.id/react/CHANGELOG.md | 7 +++++++ packages/@justaname.id/react/package.json | 4 ++-- packages/@justaname.id/sdk/CHANGELOG.md | 7 +++++++ packages/@justaname.id/sdk/package.json | 4 ++-- packages/@justaname.id/siwens/CHANGELOG.md | 4 ++++ packages/@justaname.id/siwens/package.json | 2 +- packages/@justverified/plugin/CHANGELOG.md | 4 ++++ packages/@justverified/plugin/package.json | 2 +- packages/@justweb3/efp-plugin/CHANGELOG.md | 4 ++++ packages/@justweb3/efp-plugin/package.json | 2 +- packages/@justweb3/poap-plugin/package.json | 2 +- .../talent-protocol-plugin/package.json | 2 +- packages/@justweb3/ui/CHANGELOG.md | 4 ++++ packages/@justweb3/ui/package.json | 2 +- packages/@justweb3/widget/CHANGELOG.md | 9 +++++++++ packages/@justweb3/widget/package.json | 8 ++++---- yarn.lock | 18 +++++++++--------- 17 files changed, 62 insertions(+), 23 deletions(-) diff --git a/packages/@justaname.id/react/CHANGELOG.md b/packages/@justaname.id/react/CHANGELOG.md index 8594993d..97b83795 100644 --- a/packages/@justaname.id/react/CHANGELOG.md +++ b/packages/@justaname.id/react/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.3.152 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.149 + ## 0.3.151 (2024-11-29) diff --git a/packages/@justaname.id/react/package.json b/packages/@justaname.id/react/package.json index cd859807..bc947547 100644 --- a/packages/@justaname.id/react/package.json +++ b/packages/@justaname.id/react/package.json @@ -1,9 +1,9 @@ { "name": "@justaname.id/react", - "version": "0.3.151", + "version": "0.3.152", "dependencies": { "@ensdomains/ensjs": "4.0.2", - "@justaname.id/sdk": "0.2.148", + "@justaname.id/sdk": "0.2.149", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/sdk/CHANGELOG.md b/packages/@justaname.id/sdk/CHANGELOG.md index c368d6e2..6370ed00 100644 --- a/packages/@justaname.id/sdk/CHANGELOG.md +++ b/packages/@justaname.id/sdk/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.2.149 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/siwens to 0.0.82 + ## 0.2.148 (2024-11-29) diff --git a/packages/@justaname.id/sdk/package.json b/packages/@justaname.id/sdk/package.json index 85ecde81..a87a3acd 100644 --- a/packages/@justaname.id/sdk/package.json +++ b/packages/@justaname.id/sdk/package.json @@ -1,8 +1,8 @@ { "name": "@justaname.id/sdk", - "version": "0.2.148", + "version": "0.2.149", "dependencies": { - "@justaname.id/siwens": "0.0.81", + "@justaname.id/siwens": "0.0.82", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/siwens/CHANGELOG.md b/packages/@justaname.id/siwens/CHANGELOG.md index 707ac808..84c3675e 100644 --- a/packages/@justaname.id/siwens/CHANGELOG.md +++ b/packages/@justaname.id/siwens/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.82 (2024-11-29) + +This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. + ## 0.0.81 (2024-11-29) This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. diff --git a/packages/@justaname.id/siwens/package.json b/packages/@justaname.id/siwens/package.json index d40afdbd..7b73c55a 100644 --- a/packages/@justaname.id/siwens/package.json +++ b/packages/@justaname.id/siwens/package.json @@ -1,6 +1,6 @@ { "name": "@justaname.id/siwens", - "version": "0.0.81", + "version": "0.0.82", "peerDependencies": { "ethers": ">=6.0.0", "siwe": ">=2.0.0" diff --git a/packages/@justverified/plugin/CHANGELOG.md b/packages/@justverified/plugin/CHANGELOG.md index 16790ccb..af1cc6fd 100644 --- a/packages/@justverified/plugin/CHANGELOG.md +++ b/packages/@justverified/plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.87 (2024-11-29) + +This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. + ## 0.0.86 (2024-11-29) This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. diff --git a/packages/@justverified/plugin/package.json b/packages/@justverified/plugin/package.json index 747acdcc..4d6f6138 100644 --- a/packages/@justverified/plugin/package.json +++ b/packages/@justverified/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justverified/plugin", - "version": "0.0.86", + "version": "0.0.87", "dependencies": { "axios": "^1.6.0", "lodash": "4.17.21", diff --git a/packages/@justweb3/efp-plugin/CHANGELOG.md b/packages/@justweb3/efp-plugin/CHANGELOG.md index c588e44f..30e70ae1 100644 --- a/packages/@justweb3/efp-plugin/CHANGELOG.md +++ b/packages/@justweb3/efp-plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.48 (2024-11-29) + +This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. + ## 0.1.47 (2024-11-29) This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/efp-plugin/package.json b/packages/@justweb3/efp-plugin/package.json index 439df8aa..b20b41d6 100644 --- a/packages/@justweb3/efp-plugin/package.json +++ b/packages/@justweb3/efp-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/efp-plugin", - "version": "0.1.47", + "version": "0.1.48", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/poap-plugin/package.json b/packages/@justweb3/poap-plugin/package.json index 98d7cf62..53acc6d5 100644 --- a/packages/@justweb3/poap-plugin/package.json +++ b/packages/@justweb3/poap-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/poap-plugin", - "version": "0.0.5", + "version": "0.0.6", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/talent-protocol-plugin/package.json b/packages/@justweb3/talent-protocol-plugin/package.json index 4467fb5f..97606f71 100644 --- a/packages/@justweb3/talent-protocol-plugin/package.json +++ b/packages/@justweb3/talent-protocol-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/talent-protocol-plugin", - "version": "0.0.5", + "version": "0.0.6", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/ui/CHANGELOG.md b/packages/@justweb3/ui/CHANGELOG.md index b3e5bbb9..096f5eac 100644 --- a/packages/@justweb3/ui/CHANGELOG.md +++ b/packages/@justweb3/ui/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.88 (2024-11-29) + +This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. + ## 0.0.87 (2024-11-29) This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/ui/package.json b/packages/@justweb3/ui/package.json index 5014ef52..3251f65f 100644 --- a/packages/@justweb3/ui/package.json +++ b/packages/@justweb3/ui/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/ui", - "version": "0.0.87", + "version": "0.0.88", "dependencies": { "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dialog": "^1.1.1", diff --git a/packages/@justweb3/widget/CHANGELOG.md b/packages/@justweb3/widget/CHANGELOG.md index 42f24e21..b864c343 100644 --- a/packages/@justweb3/widget/CHANGELOG.md +++ b/packages/@justweb3/widget/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.0.88 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.149 +- Updated @justaname.id/react to 0.3.152 +- Updated @justweb3/ui to 0.0.88 + ## 0.0.87 (2024-11-29) diff --git a/packages/@justweb3/widget/package.json b/packages/@justweb3/widget/package.json index 4d6d7f52..57f2d135 100644 --- a/packages/@justweb3/widget/package.json +++ b/packages/@justweb3/widget/package.json @@ -1,12 +1,12 @@ { "name": "@justweb3/widget", - "version": "0.0.87", + "version": "0.0.88", "dependencies": { "@ensdomains/address-encoder": "^1.1.2", "@hookform/resolvers": "^3.9.0", - "@justaname.id/react": "0.3.151", - "@justaname.id/sdk": "0.2.148", - "@justweb3/ui": "^0.0.87", + "@justaname.id/react": "0.3.152", + "@justaname.id/sdk": "0.2.149", + "@justweb3/ui": "^0.0.88", "clsx": "1.2.1", "cropperjs": "^1.6.2", "lodash": "4.17.21", diff --git a/yarn.lock b/yarn.lock index 9307c585..7d91fa5f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4514,12 +4514,12 @@ __metadata: languageName: node linkType: hard -"@justaname.id/react@npm:0.3.151, @justaname.id/react@workspace:packages/@justaname.id/react": +"@justaname.id/react@npm:0.3.152, @justaname.id/react@workspace:packages/@justaname.id/react": version: 0.0.0-use.local resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" dependencies: "@ensdomains/ensjs": "npm:4.0.2" - "@justaname.id/sdk": "npm:0.2.148" + "@justaname.id/sdk": "npm:0.2.149" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4532,11 +4532,11 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/sdk@npm:0.2.148, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": +"@justaname.id/sdk@npm:0.2.149, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": version: 0.0.0-use.local resolution: "@justaname.id/sdk@workspace:packages/@justaname.id/sdk" dependencies: - "@justaname.id/siwens": "npm:0.0.81" + "@justaname.id/siwens": "npm:0.0.82" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4547,7 +4547,7 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/siwens@npm:0.0.81, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": +"@justaname.id/siwens@npm:0.0.82, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": version: 0.0.0-use.local resolution: "@justaname.id/siwens@workspace:packages/@justaname.id/siwens" peerDependencies: @@ -4607,7 +4607,7 @@ __metadata: languageName: unknown linkType: soft -"@justweb3/ui@npm:^0.0.87, @justweb3/ui@workspace:packages/@justweb3/ui": +"@justweb3/ui@npm:^0.0.88, @justweb3/ui@workspace:packages/@justweb3/ui": version: 0.0.0-use.local resolution: "@justweb3/ui@workspace:packages/@justweb3/ui" dependencies: @@ -4635,9 +4635,9 @@ __metadata: dependencies: "@ensdomains/address-encoder": "npm:^1.1.2" "@hookform/resolvers": "npm:^3.9.0" - "@justaname.id/react": "npm:0.3.151" - "@justaname.id/sdk": "npm:0.2.148" - "@justweb3/ui": "npm:^0.0.87" + "@justaname.id/react": "npm:0.3.152" + "@justaname.id/sdk": "npm:0.2.149" + "@justweb3/ui": "npm:^0.0.88" clsx: "npm:1.2.1" cropperjs: "npm:^1.6.2" lodash: "npm:4.17.21" From 27d02b48d77bf654618ded83971788e4a869e064 Mon Sep 17 00:00:00 2001 From: Ghadi8 Date: Fri, 29 Nov 2024 15:06:23 +0000 Subject: [PATCH 11/29] chore(release): publish [skip ci] - project: @justaname.id/sdk 0.2.150 - project: @justaname.id/react 0.3.153 - project: @justaname.id/siwens 0.0.83 - project: @justweb3/ui 0.0.89 - project: @justweb3/widget 0.0.89 - project: @justverified/plugin 0.0.88 - project: @justweb3/efp-plugin 0.1.49 - project: @justweb3/poap-plugin 0.0.7 - project: @justweb3/talent-protocol-plugin 0.0.7 --- packages/@justaname.id/react/CHANGELOG.md | 7 +++++++ packages/@justaname.id/react/package.json | 4 ++-- packages/@justaname.id/sdk/CHANGELOG.md | 7 +++++++ packages/@justaname.id/sdk/package.json | 4 ++-- packages/@justaname.id/siwens/CHANGELOG.md | 4 ++++ packages/@justaname.id/siwens/package.json | 2 +- packages/@justverified/plugin/CHANGELOG.md | 4 ++++ packages/@justverified/plugin/package.json | 2 +- packages/@justweb3/efp-plugin/CHANGELOG.md | 4 ++++ packages/@justweb3/efp-plugin/package.json | 2 +- packages/@justweb3/poap-plugin/package.json | 2 +- .../talent-protocol-plugin/package.json | 2 +- packages/@justweb3/ui/CHANGELOG.md | 4 ++++ packages/@justweb3/ui/package.json | 2 +- packages/@justweb3/widget/CHANGELOG.md | 9 +++++++++ packages/@justweb3/widget/package.json | 8 ++++---- yarn.lock | 18 +++++++++--------- 17 files changed, 62 insertions(+), 23 deletions(-) diff --git a/packages/@justaname.id/react/CHANGELOG.md b/packages/@justaname.id/react/CHANGELOG.md index 97b83795..74da1032 100644 --- a/packages/@justaname.id/react/CHANGELOG.md +++ b/packages/@justaname.id/react/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.3.153 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.150 + ## 0.3.152 (2024-11-29) diff --git a/packages/@justaname.id/react/package.json b/packages/@justaname.id/react/package.json index bc947547..e1826fe1 100644 --- a/packages/@justaname.id/react/package.json +++ b/packages/@justaname.id/react/package.json @@ -1,9 +1,9 @@ { "name": "@justaname.id/react", - "version": "0.3.152", + "version": "0.3.153", "dependencies": { "@ensdomains/ensjs": "4.0.2", - "@justaname.id/sdk": "0.2.149", + "@justaname.id/sdk": "0.2.150", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/sdk/CHANGELOG.md b/packages/@justaname.id/sdk/CHANGELOG.md index 6370ed00..02417e4d 100644 --- a/packages/@justaname.id/sdk/CHANGELOG.md +++ b/packages/@justaname.id/sdk/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.2.150 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/siwens to 0.0.83 + ## 0.2.149 (2024-11-29) diff --git a/packages/@justaname.id/sdk/package.json b/packages/@justaname.id/sdk/package.json index a87a3acd..4c03faed 100644 --- a/packages/@justaname.id/sdk/package.json +++ b/packages/@justaname.id/sdk/package.json @@ -1,8 +1,8 @@ { "name": "@justaname.id/sdk", - "version": "0.2.149", + "version": "0.2.150", "dependencies": { - "@justaname.id/siwens": "0.0.82", + "@justaname.id/siwens": "0.0.83", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/siwens/CHANGELOG.md b/packages/@justaname.id/siwens/CHANGELOG.md index 84c3675e..8e31aea1 100644 --- a/packages/@justaname.id/siwens/CHANGELOG.md +++ b/packages/@justaname.id/siwens/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.83 (2024-11-29) + +This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. + ## 0.0.82 (2024-11-29) This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. diff --git a/packages/@justaname.id/siwens/package.json b/packages/@justaname.id/siwens/package.json index 7b73c55a..06061859 100644 --- a/packages/@justaname.id/siwens/package.json +++ b/packages/@justaname.id/siwens/package.json @@ -1,6 +1,6 @@ { "name": "@justaname.id/siwens", - "version": "0.0.82", + "version": "0.0.83", "peerDependencies": { "ethers": ">=6.0.0", "siwe": ">=2.0.0" diff --git a/packages/@justverified/plugin/CHANGELOG.md b/packages/@justverified/plugin/CHANGELOG.md index af1cc6fd..20c34fa2 100644 --- a/packages/@justverified/plugin/CHANGELOG.md +++ b/packages/@justverified/plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.88 (2024-11-29) + +This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. + ## 0.0.87 (2024-11-29) This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. diff --git a/packages/@justverified/plugin/package.json b/packages/@justverified/plugin/package.json index 4d6f6138..c75c24ca 100644 --- a/packages/@justverified/plugin/package.json +++ b/packages/@justverified/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justverified/plugin", - "version": "0.0.87", + "version": "0.0.88", "dependencies": { "axios": "^1.6.0", "lodash": "4.17.21", diff --git a/packages/@justweb3/efp-plugin/CHANGELOG.md b/packages/@justweb3/efp-plugin/CHANGELOG.md index 30e70ae1..e1da8f66 100644 --- a/packages/@justweb3/efp-plugin/CHANGELOG.md +++ b/packages/@justweb3/efp-plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.49 (2024-11-29) + +This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. + ## 0.1.48 (2024-11-29) This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/efp-plugin/package.json b/packages/@justweb3/efp-plugin/package.json index b20b41d6..0281f3c9 100644 --- a/packages/@justweb3/efp-plugin/package.json +++ b/packages/@justweb3/efp-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/efp-plugin", - "version": "0.1.48", + "version": "0.1.49", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/poap-plugin/package.json b/packages/@justweb3/poap-plugin/package.json index 53acc6d5..f2a56181 100644 --- a/packages/@justweb3/poap-plugin/package.json +++ b/packages/@justweb3/poap-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/poap-plugin", - "version": "0.0.6", + "version": "0.0.7", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/talent-protocol-plugin/package.json b/packages/@justweb3/talent-protocol-plugin/package.json index 97606f71..7f793eb6 100644 --- a/packages/@justweb3/talent-protocol-plugin/package.json +++ b/packages/@justweb3/talent-protocol-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/talent-protocol-plugin", - "version": "0.0.6", + "version": "0.0.7", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/ui/CHANGELOG.md b/packages/@justweb3/ui/CHANGELOG.md index 096f5eac..8cc61ef6 100644 --- a/packages/@justweb3/ui/CHANGELOG.md +++ b/packages/@justweb3/ui/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.89 (2024-11-29) + +This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. + ## 0.0.88 (2024-11-29) This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/ui/package.json b/packages/@justweb3/ui/package.json index 3251f65f..002177df 100644 --- a/packages/@justweb3/ui/package.json +++ b/packages/@justweb3/ui/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/ui", - "version": "0.0.88", + "version": "0.0.89", "dependencies": { "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dialog": "^1.1.1", diff --git a/packages/@justweb3/widget/CHANGELOG.md b/packages/@justweb3/widget/CHANGELOG.md index b864c343..af779a7a 100644 --- a/packages/@justweb3/widget/CHANGELOG.md +++ b/packages/@justweb3/widget/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.0.89 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.150 +- Updated @justaname.id/react to 0.3.153 +- Updated @justweb3/ui to 0.0.89 + ## 0.0.88 (2024-11-29) diff --git a/packages/@justweb3/widget/package.json b/packages/@justweb3/widget/package.json index 57f2d135..0edf8063 100644 --- a/packages/@justweb3/widget/package.json +++ b/packages/@justweb3/widget/package.json @@ -1,12 +1,12 @@ { "name": "@justweb3/widget", - "version": "0.0.88", + "version": "0.0.89", "dependencies": { "@ensdomains/address-encoder": "^1.1.2", "@hookform/resolvers": "^3.9.0", - "@justaname.id/react": "0.3.152", - "@justaname.id/sdk": "0.2.149", - "@justweb3/ui": "^0.0.88", + "@justaname.id/react": "0.3.153", + "@justaname.id/sdk": "0.2.150", + "@justweb3/ui": "^0.0.89", "clsx": "1.2.1", "cropperjs": "^1.6.2", "lodash": "4.17.21", diff --git a/yarn.lock b/yarn.lock index 7d91fa5f..79b5f93a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4514,12 +4514,12 @@ __metadata: languageName: node linkType: hard -"@justaname.id/react@npm:0.3.152, @justaname.id/react@workspace:packages/@justaname.id/react": +"@justaname.id/react@npm:0.3.153, @justaname.id/react@workspace:packages/@justaname.id/react": version: 0.0.0-use.local resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" dependencies: "@ensdomains/ensjs": "npm:4.0.2" - "@justaname.id/sdk": "npm:0.2.149" + "@justaname.id/sdk": "npm:0.2.150" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4532,11 +4532,11 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/sdk@npm:0.2.149, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": +"@justaname.id/sdk@npm:0.2.150, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": version: 0.0.0-use.local resolution: "@justaname.id/sdk@workspace:packages/@justaname.id/sdk" dependencies: - "@justaname.id/siwens": "npm:0.0.82" + "@justaname.id/siwens": "npm:0.0.83" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4547,7 +4547,7 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/siwens@npm:0.0.82, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": +"@justaname.id/siwens@npm:0.0.83, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": version: 0.0.0-use.local resolution: "@justaname.id/siwens@workspace:packages/@justaname.id/siwens" peerDependencies: @@ -4607,7 +4607,7 @@ __metadata: languageName: unknown linkType: soft -"@justweb3/ui@npm:^0.0.88, @justweb3/ui@workspace:packages/@justweb3/ui": +"@justweb3/ui@npm:^0.0.89, @justweb3/ui@workspace:packages/@justweb3/ui": version: 0.0.0-use.local resolution: "@justweb3/ui@workspace:packages/@justweb3/ui" dependencies: @@ -4635,9 +4635,9 @@ __metadata: dependencies: "@ensdomains/address-encoder": "npm:^1.1.2" "@hookform/resolvers": "npm:^3.9.0" - "@justaname.id/react": "npm:0.3.152" - "@justaname.id/sdk": "npm:0.2.149" - "@justweb3/ui": "npm:^0.0.88" + "@justaname.id/react": "npm:0.3.153" + "@justaname.id/sdk": "npm:0.2.150" + "@justweb3/ui": "npm:^0.0.89" clsx: "npm:1.2.1" cropperjs: "npm:^1.6.2" lodash: "npm:4.17.21" From 26bdae9746bfe914d12538377309f6e7ddb8dc1d Mon Sep 17 00:00:00 2001 From: Ghadi8 Date: Fri, 29 Nov 2024 15:48:56 +0000 Subject: [PATCH 12/29] chore(release): publish [skip ci] - project: @justaname.id/sdk 0.2.151 - project: @justaname.id/react 0.3.154 - project: @justaname.id/siwens 0.0.84 - project: @justweb3/ui 0.0.90 - project: @justweb3/widget 0.0.90 - project: @justverified/plugin 0.0.89 - project: @justweb3/efp-plugin 0.1.50 - project: @justweb3/poap-plugin 0.0.8 - project: @justweb3/talent-protocol-plugin 0.0.8 --- packages/@justaname.id/react/CHANGELOG.md | 7 +++++++ packages/@justaname.id/react/package.json | 4 ++-- packages/@justaname.id/sdk/CHANGELOG.md | 7 +++++++ packages/@justaname.id/sdk/package.json | 4 ++-- packages/@justaname.id/siwens/CHANGELOG.md | 4 ++++ packages/@justaname.id/siwens/package.json | 2 +- packages/@justverified/plugin/CHANGELOG.md | 4 ++++ packages/@justverified/plugin/package.json | 2 +- packages/@justweb3/efp-plugin/CHANGELOG.md | 4 ++++ packages/@justweb3/efp-plugin/package.json | 2 +- packages/@justweb3/poap-plugin/package.json | 2 +- .../talent-protocol-plugin/package.json | 2 +- packages/@justweb3/ui/CHANGELOG.md | 4 ++++ packages/@justweb3/ui/package.json | 2 +- packages/@justweb3/widget/CHANGELOG.md | 9 +++++++++ packages/@justweb3/widget/package.json | 8 ++++---- yarn.lock | 18 +++++++++--------- 17 files changed, 62 insertions(+), 23 deletions(-) diff --git a/packages/@justaname.id/react/CHANGELOG.md b/packages/@justaname.id/react/CHANGELOG.md index 74da1032..785ad8d4 100644 --- a/packages/@justaname.id/react/CHANGELOG.md +++ b/packages/@justaname.id/react/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.3.154 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.151 + ## 0.3.153 (2024-11-29) diff --git a/packages/@justaname.id/react/package.json b/packages/@justaname.id/react/package.json index e1826fe1..9e73acad 100644 --- a/packages/@justaname.id/react/package.json +++ b/packages/@justaname.id/react/package.json @@ -1,9 +1,9 @@ { "name": "@justaname.id/react", - "version": "0.3.153", + "version": "0.3.154", "dependencies": { "@ensdomains/ensjs": "4.0.2", - "@justaname.id/sdk": "0.2.150", + "@justaname.id/sdk": "0.2.151", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/sdk/CHANGELOG.md b/packages/@justaname.id/sdk/CHANGELOG.md index 02417e4d..d608d746 100644 --- a/packages/@justaname.id/sdk/CHANGELOG.md +++ b/packages/@justaname.id/sdk/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.2.151 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/siwens to 0.0.84 + ## 0.2.150 (2024-11-29) diff --git a/packages/@justaname.id/sdk/package.json b/packages/@justaname.id/sdk/package.json index 4c03faed..9115f781 100644 --- a/packages/@justaname.id/sdk/package.json +++ b/packages/@justaname.id/sdk/package.json @@ -1,8 +1,8 @@ { "name": "@justaname.id/sdk", - "version": "0.2.150", + "version": "0.2.151", "dependencies": { - "@justaname.id/siwens": "0.0.83", + "@justaname.id/siwens": "0.0.84", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/siwens/CHANGELOG.md b/packages/@justaname.id/siwens/CHANGELOG.md index 8e31aea1..5266510a 100644 --- a/packages/@justaname.id/siwens/CHANGELOG.md +++ b/packages/@justaname.id/siwens/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.84 (2024-11-29) + +This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. + ## 0.0.83 (2024-11-29) This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. diff --git a/packages/@justaname.id/siwens/package.json b/packages/@justaname.id/siwens/package.json index 06061859..fcb2de08 100644 --- a/packages/@justaname.id/siwens/package.json +++ b/packages/@justaname.id/siwens/package.json @@ -1,6 +1,6 @@ { "name": "@justaname.id/siwens", - "version": "0.0.83", + "version": "0.0.84", "peerDependencies": { "ethers": ">=6.0.0", "siwe": ">=2.0.0" diff --git a/packages/@justverified/plugin/CHANGELOG.md b/packages/@justverified/plugin/CHANGELOG.md index 20c34fa2..ef593ba1 100644 --- a/packages/@justverified/plugin/CHANGELOG.md +++ b/packages/@justverified/plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.89 (2024-11-29) + +This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. + ## 0.0.88 (2024-11-29) This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. diff --git a/packages/@justverified/plugin/package.json b/packages/@justverified/plugin/package.json index c75c24ca..ab783ec3 100644 --- a/packages/@justverified/plugin/package.json +++ b/packages/@justverified/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justverified/plugin", - "version": "0.0.88", + "version": "0.0.89", "dependencies": { "axios": "^1.6.0", "lodash": "4.17.21", diff --git a/packages/@justweb3/efp-plugin/CHANGELOG.md b/packages/@justweb3/efp-plugin/CHANGELOG.md index e1da8f66..6953f7af 100644 --- a/packages/@justweb3/efp-plugin/CHANGELOG.md +++ b/packages/@justweb3/efp-plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.50 (2024-11-29) + +This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. + ## 0.1.49 (2024-11-29) This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/efp-plugin/package.json b/packages/@justweb3/efp-plugin/package.json index 0281f3c9..310594b0 100644 --- a/packages/@justweb3/efp-plugin/package.json +++ b/packages/@justweb3/efp-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/efp-plugin", - "version": "0.1.49", + "version": "0.1.50", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/poap-plugin/package.json b/packages/@justweb3/poap-plugin/package.json index f2a56181..641b2224 100644 --- a/packages/@justweb3/poap-plugin/package.json +++ b/packages/@justweb3/poap-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/poap-plugin", - "version": "0.0.7", + "version": "0.0.8", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/talent-protocol-plugin/package.json b/packages/@justweb3/talent-protocol-plugin/package.json index 7f793eb6..35293589 100644 --- a/packages/@justweb3/talent-protocol-plugin/package.json +++ b/packages/@justweb3/talent-protocol-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/talent-protocol-plugin", - "version": "0.0.7", + "version": "0.0.8", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/ui/CHANGELOG.md b/packages/@justweb3/ui/CHANGELOG.md index 8cc61ef6..014eed9c 100644 --- a/packages/@justweb3/ui/CHANGELOG.md +++ b/packages/@justweb3/ui/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.90 (2024-11-29) + +This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. + ## 0.0.89 (2024-11-29) This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/ui/package.json b/packages/@justweb3/ui/package.json index 002177df..2d620777 100644 --- a/packages/@justweb3/ui/package.json +++ b/packages/@justweb3/ui/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/ui", - "version": "0.0.89", + "version": "0.0.90", "dependencies": { "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dialog": "^1.1.1", diff --git a/packages/@justweb3/widget/CHANGELOG.md b/packages/@justweb3/widget/CHANGELOG.md index af779a7a..ca42e73c 100644 --- a/packages/@justweb3/widget/CHANGELOG.md +++ b/packages/@justweb3/widget/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.0.90 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.151 +- Updated @justaname.id/react to 0.3.154 +- Updated @justweb3/ui to 0.0.90 + ## 0.0.89 (2024-11-29) diff --git a/packages/@justweb3/widget/package.json b/packages/@justweb3/widget/package.json index 0edf8063..48b11930 100644 --- a/packages/@justweb3/widget/package.json +++ b/packages/@justweb3/widget/package.json @@ -1,12 +1,12 @@ { "name": "@justweb3/widget", - "version": "0.0.89", + "version": "0.0.90", "dependencies": { "@ensdomains/address-encoder": "^1.1.2", "@hookform/resolvers": "^3.9.0", - "@justaname.id/react": "0.3.153", - "@justaname.id/sdk": "0.2.150", - "@justweb3/ui": "^0.0.89", + "@justaname.id/react": "0.3.154", + "@justaname.id/sdk": "0.2.151", + "@justweb3/ui": "^0.0.90", "clsx": "1.2.1", "cropperjs": "^1.6.2", "lodash": "4.17.21", diff --git a/yarn.lock b/yarn.lock index 79b5f93a..eee2b721 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4514,12 +4514,12 @@ __metadata: languageName: node linkType: hard -"@justaname.id/react@npm:0.3.153, @justaname.id/react@workspace:packages/@justaname.id/react": +"@justaname.id/react@npm:0.3.154, @justaname.id/react@workspace:packages/@justaname.id/react": version: 0.0.0-use.local resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" dependencies: "@ensdomains/ensjs": "npm:4.0.2" - "@justaname.id/sdk": "npm:0.2.150" + "@justaname.id/sdk": "npm:0.2.151" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4532,11 +4532,11 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/sdk@npm:0.2.150, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": +"@justaname.id/sdk@npm:0.2.151, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": version: 0.0.0-use.local resolution: "@justaname.id/sdk@workspace:packages/@justaname.id/sdk" dependencies: - "@justaname.id/siwens": "npm:0.0.83" + "@justaname.id/siwens": "npm:0.0.84" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4547,7 +4547,7 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/siwens@npm:0.0.83, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": +"@justaname.id/siwens@npm:0.0.84, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": version: 0.0.0-use.local resolution: "@justaname.id/siwens@workspace:packages/@justaname.id/siwens" peerDependencies: @@ -4607,7 +4607,7 @@ __metadata: languageName: unknown linkType: soft -"@justweb3/ui@npm:^0.0.89, @justweb3/ui@workspace:packages/@justweb3/ui": +"@justweb3/ui@npm:^0.0.90, @justweb3/ui@workspace:packages/@justweb3/ui": version: 0.0.0-use.local resolution: "@justweb3/ui@workspace:packages/@justweb3/ui" dependencies: @@ -4635,9 +4635,9 @@ __metadata: dependencies: "@ensdomains/address-encoder": "npm:^1.1.2" "@hookform/resolvers": "npm:^3.9.0" - "@justaname.id/react": "npm:0.3.153" - "@justaname.id/sdk": "npm:0.2.150" - "@justweb3/ui": "npm:^0.0.89" + "@justaname.id/react": "npm:0.3.154" + "@justaname.id/sdk": "npm:0.2.151" + "@justweb3/ui": "npm:^0.0.90" clsx: "npm:1.2.1" cropperjs: "npm:^1.6.2" lodash: "npm:4.17.21" From 578f44733cd96af9b57fb5d6cac8409758aa8f94 Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Fri, 29 Nov 2024 17:54:00 +0200 Subject: [PATCH 13/29] chore(release): publish [skip ci] - project: @justaname.id/sdk 0.2.152 - project: @justaname.id/react 0.3.155 - project: @justaname.id/siwens 0.0.85 - project: @justweb3/ui 0.0.91 - project: @justweb3/widget 0.0.91 - project: @justverified/plugin 0.0.90 - project: @justweb3/efp-plugin 0.1.51 - project: @justweb3/poap-plugin 0.0.9 - project: @justweb3/talent-protocol-plugin 0.0.9 --- packages/@justaname.id/react/CHANGELOG.md | 7 +++++++ packages/@justaname.id/react/package.json | 4 ++-- packages/@justaname.id/sdk/CHANGELOG.md | 7 +++++++ packages/@justaname.id/sdk/package.json | 4 ++-- packages/@justaname.id/siwens/CHANGELOG.md | 4 ++++ packages/@justaname.id/siwens/package.json | 2 +- packages/@justverified/plugin/CHANGELOG.md | 4 ++++ packages/@justverified/plugin/package.json | 2 +- packages/@justweb3/efp-plugin/CHANGELOG.md | 4 ++++ packages/@justweb3/efp-plugin/package.json | 2 +- packages/@justweb3/poap-plugin/package.json | 2 +- .../talent-protocol-plugin/package.json | 2 +- packages/@justweb3/ui/CHANGELOG.md | 4 ++++ packages/@justweb3/ui/package.json | 2 +- packages/@justweb3/widget/CHANGELOG.md | 9 +++++++++ packages/@justweb3/widget/package.json | 8 ++++---- yarn.lock | 18 +++++++++--------- 17 files changed, 62 insertions(+), 23 deletions(-) diff --git a/packages/@justaname.id/react/CHANGELOG.md b/packages/@justaname.id/react/CHANGELOG.md index 785ad8d4..26ad1bfe 100644 --- a/packages/@justaname.id/react/CHANGELOG.md +++ b/packages/@justaname.id/react/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.3.155 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.152 + ## 0.3.154 (2024-11-29) diff --git a/packages/@justaname.id/react/package.json b/packages/@justaname.id/react/package.json index 9e73acad..879fdcdf 100644 --- a/packages/@justaname.id/react/package.json +++ b/packages/@justaname.id/react/package.json @@ -1,9 +1,9 @@ { "name": "@justaname.id/react", - "version": "0.3.154", + "version": "0.3.155", "dependencies": { "@ensdomains/ensjs": "4.0.2", - "@justaname.id/sdk": "0.2.151", + "@justaname.id/sdk": "0.2.152", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/sdk/CHANGELOG.md b/packages/@justaname.id/sdk/CHANGELOG.md index d608d746..2b4a989e 100644 --- a/packages/@justaname.id/sdk/CHANGELOG.md +++ b/packages/@justaname.id/sdk/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.2.152 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/siwens to 0.0.85 + ## 0.2.151 (2024-11-29) diff --git a/packages/@justaname.id/sdk/package.json b/packages/@justaname.id/sdk/package.json index 9115f781..f8ea24bd 100644 --- a/packages/@justaname.id/sdk/package.json +++ b/packages/@justaname.id/sdk/package.json @@ -1,8 +1,8 @@ { "name": "@justaname.id/sdk", - "version": "0.2.151", + "version": "0.2.152", "dependencies": { - "@justaname.id/siwens": "0.0.84", + "@justaname.id/siwens": "0.0.85", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/siwens/CHANGELOG.md b/packages/@justaname.id/siwens/CHANGELOG.md index 5266510a..4180e99b 100644 --- a/packages/@justaname.id/siwens/CHANGELOG.md +++ b/packages/@justaname.id/siwens/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.85 (2024-11-29) + +This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. + ## 0.0.84 (2024-11-29) This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. diff --git a/packages/@justaname.id/siwens/package.json b/packages/@justaname.id/siwens/package.json index fcb2de08..e01effc2 100644 --- a/packages/@justaname.id/siwens/package.json +++ b/packages/@justaname.id/siwens/package.json @@ -1,6 +1,6 @@ { "name": "@justaname.id/siwens", - "version": "0.0.84", + "version": "0.0.85", "peerDependencies": { "ethers": ">=6.0.0", "siwe": ">=2.0.0" diff --git a/packages/@justverified/plugin/CHANGELOG.md b/packages/@justverified/plugin/CHANGELOG.md index ef593ba1..e0177be2 100644 --- a/packages/@justverified/plugin/CHANGELOG.md +++ b/packages/@justverified/plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.90 (2024-11-29) + +This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. + ## 0.0.89 (2024-11-29) This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. diff --git a/packages/@justverified/plugin/package.json b/packages/@justverified/plugin/package.json index ab783ec3..7b454ba7 100644 --- a/packages/@justverified/plugin/package.json +++ b/packages/@justverified/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justverified/plugin", - "version": "0.0.89", + "version": "0.0.90", "dependencies": { "axios": "^1.6.0", "lodash": "4.17.21", diff --git a/packages/@justweb3/efp-plugin/CHANGELOG.md b/packages/@justweb3/efp-plugin/CHANGELOG.md index 6953f7af..722cb01e 100644 --- a/packages/@justweb3/efp-plugin/CHANGELOG.md +++ b/packages/@justweb3/efp-plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.51 (2024-11-29) + +This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. + ## 0.1.50 (2024-11-29) This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/efp-plugin/package.json b/packages/@justweb3/efp-plugin/package.json index 310594b0..ae26a786 100644 --- a/packages/@justweb3/efp-plugin/package.json +++ b/packages/@justweb3/efp-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/efp-plugin", - "version": "0.1.50", + "version": "0.1.51", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/poap-plugin/package.json b/packages/@justweb3/poap-plugin/package.json index 641b2224..a5276346 100644 --- a/packages/@justweb3/poap-plugin/package.json +++ b/packages/@justweb3/poap-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/poap-plugin", - "version": "0.0.8", + "version": "0.0.9", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/talent-protocol-plugin/package.json b/packages/@justweb3/talent-protocol-plugin/package.json index 35293589..9303f74a 100644 --- a/packages/@justweb3/talent-protocol-plugin/package.json +++ b/packages/@justweb3/talent-protocol-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/talent-protocol-plugin", - "version": "0.0.8", + "version": "0.0.9", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/ui/CHANGELOG.md b/packages/@justweb3/ui/CHANGELOG.md index 014eed9c..24c4c2d6 100644 --- a/packages/@justweb3/ui/CHANGELOG.md +++ b/packages/@justweb3/ui/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.91 (2024-11-29) + +This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. + ## 0.0.90 (2024-11-29) This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/ui/package.json b/packages/@justweb3/ui/package.json index 2d620777..8d530420 100644 --- a/packages/@justweb3/ui/package.json +++ b/packages/@justweb3/ui/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/ui", - "version": "0.0.90", + "version": "0.0.91", "dependencies": { "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dialog": "^1.1.1", diff --git a/packages/@justweb3/widget/CHANGELOG.md b/packages/@justweb3/widget/CHANGELOG.md index ca42e73c..2632c8d4 100644 --- a/packages/@justweb3/widget/CHANGELOG.md +++ b/packages/@justweb3/widget/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.0.91 (2024-11-29) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.152 +- Updated @justaname.id/react to 0.3.155 +- Updated @justweb3/ui to 0.0.91 + ## 0.0.90 (2024-11-29) diff --git a/packages/@justweb3/widget/package.json b/packages/@justweb3/widget/package.json index 48b11930..6f84d53f 100644 --- a/packages/@justweb3/widget/package.json +++ b/packages/@justweb3/widget/package.json @@ -1,12 +1,12 @@ { "name": "@justweb3/widget", - "version": "0.0.90", + "version": "0.0.91", "dependencies": { "@ensdomains/address-encoder": "^1.1.2", "@hookform/resolvers": "^3.9.0", - "@justaname.id/react": "0.3.154", - "@justaname.id/sdk": "0.2.151", - "@justweb3/ui": "^0.0.90", + "@justaname.id/react": "0.3.155", + "@justaname.id/sdk": "0.2.152", + "@justweb3/ui": "^0.0.91", "clsx": "1.2.1", "cropperjs": "^1.6.2", "lodash": "4.17.21", diff --git a/yarn.lock b/yarn.lock index eee2b721..90201bcc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4514,12 +4514,12 @@ __metadata: languageName: node linkType: hard -"@justaname.id/react@npm:0.3.154, @justaname.id/react@workspace:packages/@justaname.id/react": +"@justaname.id/react@npm:0.3.155, @justaname.id/react@workspace:packages/@justaname.id/react": version: 0.0.0-use.local resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" dependencies: "@ensdomains/ensjs": "npm:4.0.2" - "@justaname.id/sdk": "npm:0.2.151" + "@justaname.id/sdk": "npm:0.2.152" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4532,11 +4532,11 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/sdk@npm:0.2.151, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": +"@justaname.id/sdk@npm:0.2.152, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": version: 0.0.0-use.local resolution: "@justaname.id/sdk@workspace:packages/@justaname.id/sdk" dependencies: - "@justaname.id/siwens": "npm:0.0.84" + "@justaname.id/siwens": "npm:0.0.85" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4547,7 +4547,7 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/siwens@npm:0.0.84, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": +"@justaname.id/siwens@npm:0.0.85, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": version: 0.0.0-use.local resolution: "@justaname.id/siwens@workspace:packages/@justaname.id/siwens" peerDependencies: @@ -4607,7 +4607,7 @@ __metadata: languageName: unknown linkType: soft -"@justweb3/ui@npm:^0.0.90, @justweb3/ui@workspace:packages/@justweb3/ui": +"@justweb3/ui@npm:^0.0.91, @justweb3/ui@workspace:packages/@justweb3/ui": version: 0.0.0-use.local resolution: "@justweb3/ui@workspace:packages/@justweb3/ui" dependencies: @@ -4635,9 +4635,9 @@ __metadata: dependencies: "@ensdomains/address-encoder": "npm:^1.1.2" "@hookform/resolvers": "npm:^3.9.0" - "@justaname.id/react": "npm:0.3.154" - "@justaname.id/sdk": "npm:0.2.151" - "@justweb3/ui": "npm:^0.0.90" + "@justaname.id/react": "npm:0.3.155" + "@justaname.id/sdk": "npm:0.2.152" + "@justweb3/ui": "npm:^0.0.91" clsx: "npm:1.2.1" cropperjs: "npm:^1.6.2" lodash: "npm:4.17.21" From f82ab13c8eaea8acc6b3ee293890cf568ea51893 Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Sun, 1 Dec 2024 02:48:28 +0200 Subject: [PATCH 14/29] feat: support ethers 5 and ethers 6 --- packages/@justaname.id/react/package.json | 2 +- .../react/src/lib/helpers/ethersCompat.ts | 42 +++++++++++ .../useSetNameHashJustaNameResolver.ts | 28 +++---- packages/@justaname.id/sdk/package.json | 2 +- .../sdk/src/lib/justaname/index.ts | 12 +-- .../src/lib/types/justaname/configuration.ts | 2 +- .../sdk/src/lib/utils/ethersCompat.ts | 42 +++++++++++ packages/@justaname.id/siwens/README.md | 62 +++++++++------- packages/@justaname.id/siwens/package.json | 2 +- .../siwens/src/lib/siwens/siwens.ts | 8 +- .../siwens/src/lib/utils/ethersCompat.ts | 42 +++++++++++ .../lib/components/ClickableItem/index.tsx | 3 +- .../JustEnsCard/JustEnsCard.module.css | 5 +- .../xmtp-plugin/src/stories/xmtp.stories.tsx | 73 ++++++++++--------- 14 files changed, 226 insertions(+), 99 deletions(-) create mode 100644 packages/@justaname.id/react/src/lib/helpers/ethersCompat.ts create mode 100644 packages/@justaname.id/sdk/src/lib/utils/ethersCompat.ts create mode 100644 packages/@justaname.id/siwens/src/lib/utils/ethersCompat.ts diff --git a/packages/@justaname.id/react/package.json b/packages/@justaname.id/react/package.json index 879fdcdf..1d4ee357 100644 --- a/packages/@justaname.id/react/package.json +++ b/packages/@justaname.id/react/package.json @@ -9,7 +9,7 @@ }, "peerDependencies": { "@tanstack/react-query": "^5.x", - "ethers": "^6.x", + "ethers": "^5.6.8 || ^6.0.8", "react": ">=17", "viem": "2.x", "wagmi": "2.x" diff --git a/packages/@justaname.id/react/src/lib/helpers/ethersCompat.ts b/packages/@justaname.id/react/src/lib/helpers/ethersCompat.ts new file mode 100644 index 00000000..dcc041b5 --- /dev/null +++ b/packages/@justaname.id/react/src/lib/helpers/ethersCompat.ts @@ -0,0 +1,42 @@ +// inspired by spruceid siwe: https://github.com/spruceid/siwe/blob/main/packages/siwe/lib/ethersCompat.ts + +import { ethers } from 'ethers'; +// @ts-expect-error -- compatibility hack +type ProviderV5 = ethers.providers.Provider; +type ProviderV6 = ethers.Provider; +// @ts-expect-error -- compatibility hack +type JsonRpcProviderV5 = ethers.providers.JsonRpcProvider; +type JsonRpcProviderV6 = ethers.JsonRpcProvider; + +export type Provider = ProviderV6 extends undefined ? ProviderV5 : ProviderV6; +export type JsonRpcProvider = JsonRpcProviderV6 extends undefined + ? JsonRpcProviderV5 + : JsonRpcProviderV6; + +export const getJsonRpcProvider = ( + providerUrl?: string | undefined, + chainId?: number +): JsonRpcProvider => { + try { + return new ethers.JsonRpcProvider(providerUrl, chainId); + } catch { + // @ts-expect-error -- compatibility hack + return new ethers.providers.JsonRpcProvider(providerUrl, chainId); + } +}; + +let ethersNamehash = null; +let ethersGetAddress = null; + +try { + // @ts-expect-error -- compatibility hack + ethersNamehash = ethers.utils.namehash; + // @ts-expect-error -- compatibility hack + ethersGetAddress = ethers.utils.getAddress; +} catch { + ethersNamehash = ethers.namehash as (message: Uint8Array | string) => string; + + ethersGetAddress = ethers.getAddress as (address: string) => string; +} +export const namehash = ethersNamehash as (name: string) => string; +export const getAddress = ethersGetAddress as (address: string) => string; diff --git a/packages/@justaname.id/react/src/lib/hooks/resolver/useSetNameHashJustaNameResolver.ts b/packages/@justaname.id/react/src/lib/hooks/resolver/useSetNameHashJustaNameResolver.ts index 6bc1e94f..b20ef502 100644 --- a/packages/@justaname.id/react/src/lib/hooks/resolver/useSetNameHashJustaNameResolver.ts +++ b/packages/@justaname.id/react/src/lib/hooks/resolver/useSetNameHashJustaNameResolver.ts @@ -1,7 +1,6 @@ 'use client'; import { useMutation } from '@tanstack/react-query'; -import { ethers } from 'ethers'; import { useEffect, useMemo } from 'react'; import { useReadContract, @@ -11,6 +10,7 @@ import { } from 'wagmi'; import { useOffchainResolvers } from '../offchainResolver/useOffchainResolvers'; import { useMountedAccount } from '../account/useMountedAccount'; +import { getAddress, namehash } from '../../helpers/ethersCompat'; const REGISTRY_ADDRESS = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'; const SEPOLIA_REGISTRAR_ADDRESS = '0xA0a1AbcDAe1a2a4A2EF8e9113Ff0e02DD81DC0C6'; @@ -120,12 +120,14 @@ export const useSetNameHashJustaNameResolver = < T = any >(): UseSetNameHashJustaNameResolver => { const { chainId, address } = useMountedAccount(); - const { offchainResolvers, isOffchainResolversPending } = useOffchainResolvers(); + const { offchainResolvers, isOffchainResolversPending } = + useOffchainResolvers(); const currentResolver = useMemo(() => { if (!chainId || !offchainResolvers || isOffchainResolversPending) return; - return offchainResolvers?.offchainResolvers.find((resolver) => resolver.chainId === chainId) - ?.resolverAddress; + return offchainResolvers?.offchainResolvers.find( + (resolver) => resolver.chainId === chainId + )?.resolverAddress; }, [offchainResolvers, chainId, isOffchainResolversPending]); const { @@ -136,11 +138,7 @@ export const useSetNameHashJustaNameResolver = < address: REGISTRY_ADDRESS, abi: recordExistsABI, functionName: 'recordExists', - args: [ - ethers.namehash( - ethers.getAddress(address ?? '').substring(2) + '.addr.reverse' - ), - ], + args: [namehash(getAddress(address ?? '').substring(2) + '.addr.reverse')], chainId: chainId, }); @@ -149,7 +147,7 @@ export const useSetNameHashJustaNameResolver = < chainId === 1 ? MAINNET_REGISTRAR_ADDRESS : SEPOLIA_REGISTRAR_ADDRESS, abi: setClaimWithResolverABI, functionName: 'claimWithResolver', - args: [ethers.getAddress(address ?? ''), currentResolver], + args: [getAddress(address ?? ''), currentResolver], chainId: chainId, query: { enabled: recordExistsStatus === 'success' && recordExistsConfig === false, @@ -164,11 +162,7 @@ export const useSetNameHashJustaNameResolver = < address: REGISTRY_ADDRESS, abi: getResolverABI, functionName: 'resolver', - args: [ - ethers.namehash( - ethers.getAddress(address ?? '').substring(2) + '.addr.reverse' - ), - ], + args: [namehash(getAddress(address ?? '').substring(2) + '.addr.reverse')], chainId: chainId, query: { enabled: recordExistsStatus === 'success' && recordExistsConfig === true, @@ -180,9 +174,7 @@ export const useSetNameHashJustaNameResolver = < abi: setResolverABI, functionName: 'setResolver', args: [ - ethers.namehash( - ethers.getAddress(address ?? '').substring(2) + '.addr.reverse' - ), + namehash(getAddress(address ?? '').substring(2) + '.addr.reverse'), currentResolver, ], chainId: chainId, diff --git a/packages/@justaname.id/sdk/package.json b/packages/@justaname.id/sdk/package.json index f8ea24bd..f44814b1 100644 --- a/packages/@justaname.id/sdk/package.json +++ b/packages/@justaname.id/sdk/package.json @@ -10,7 +10,7 @@ "jest": "^29.4.1" }, "peerDependencies": { - "ethers": ">=6.0.0", + "ethers": "^5.6.8 || ^6.0.8", "siwe": ">=2.0.0", "viem": ">=2.0.0" }, diff --git a/packages/@justaname.id/sdk/src/lib/justaname/index.ts b/packages/@justaname.id/sdk/src/lib/justaname/index.ts index be7d760c..84da9a6e 100644 --- a/packages/@justaname.id/sdk/src/lib/justaname/index.ts +++ b/packages/@justaname.id/sdk/src/lib/justaname/index.ts @@ -14,8 +14,8 @@ import { Subnames, } from '../features'; import { InvalidConfigurationException } from '../errors/InvalidConfiguration.exception'; -import { ethers } from 'ethers'; import { providerUrlChainIdLoadingMap, providerUrlChainIdMap } from '../memory'; +import { getJsonRpcProvider } from '../utils/ethersCompat'; /** * The main class for the JustaName SDK. @@ -162,11 +162,11 @@ export class JustaName { const defaultMainnetProviderUrl = 'https://cloudflare-eth.com'; const defaultTestnetProviderUrl = 'https://rpc.sepolia.org'; - const defaultMainnetProvider = new ethers.JsonRpcProvider( + const defaultMainnetProvider = getJsonRpcProvider( defaultMainnetProviderUrl, 1 ); - const defaultTestnetProvider = new ethers.JsonRpcProvider( + const defaultTestnetProvider = getJsonRpcProvider( defaultTestnetProviderUrl, 11155111 ); @@ -184,7 +184,7 @@ export class JustaName { }, // { // chainId: 31337 as ChainId, - // provider: new ethers.JsonRpcProvider('http://localhost:8545'), + // provider: getJsonRpcProvider('http://localhost:8545'), // providerUrl: 'http://localhost:8545', // }, ] as NetworksWithProvider; @@ -194,7 +194,7 @@ export class JustaName { if (network && network?.providerUrl) { return { chainId: network.chainId, - provider: new ethers.JsonRpcProvider(network.providerUrl), + provider: getJsonRpcProvider(network.providerUrl), providerUrl: network.providerUrl, }; } else { @@ -256,7 +256,7 @@ export class JustaName { } } - const provider = new ethers.JsonRpcProvider(network.providerUrl); + const provider = getJsonRpcProvider(network.providerUrl); provider.getNetwork().then((_network) => { if (network.chainId.toString() !== _network.chainId.toString()) { throw new InvalidConfigurationException( diff --git a/packages/@justaname.id/sdk/src/lib/types/justaname/configuration.ts b/packages/@justaname.id/sdk/src/lib/types/justaname/configuration.ts index 227c8129..344bc654 100644 --- a/packages/@justaname.id/sdk/src/lib/types/justaname/configuration.ts +++ b/packages/@justaname.id/sdk/src/lib/types/justaname/configuration.ts @@ -1,5 +1,5 @@ +import { JsonRpcProvider } from '../../utils/ethersCompat'; import { ChainId } from '../common'; -import { JsonRpcProvider } from 'ethers'; export interface NetworkWithProvider extends Network { diff --git a/packages/@justaname.id/sdk/src/lib/utils/ethersCompat.ts b/packages/@justaname.id/sdk/src/lib/utils/ethersCompat.ts new file mode 100644 index 00000000..dcc041b5 --- /dev/null +++ b/packages/@justaname.id/sdk/src/lib/utils/ethersCompat.ts @@ -0,0 +1,42 @@ +// inspired by spruceid siwe: https://github.com/spruceid/siwe/blob/main/packages/siwe/lib/ethersCompat.ts + +import { ethers } from 'ethers'; +// @ts-expect-error -- compatibility hack +type ProviderV5 = ethers.providers.Provider; +type ProviderV6 = ethers.Provider; +// @ts-expect-error -- compatibility hack +type JsonRpcProviderV5 = ethers.providers.JsonRpcProvider; +type JsonRpcProviderV6 = ethers.JsonRpcProvider; + +export type Provider = ProviderV6 extends undefined ? ProviderV5 : ProviderV6; +export type JsonRpcProvider = JsonRpcProviderV6 extends undefined + ? JsonRpcProviderV5 + : JsonRpcProviderV6; + +export const getJsonRpcProvider = ( + providerUrl?: string | undefined, + chainId?: number +): JsonRpcProvider => { + try { + return new ethers.JsonRpcProvider(providerUrl, chainId); + } catch { + // @ts-expect-error -- compatibility hack + return new ethers.providers.JsonRpcProvider(providerUrl, chainId); + } +}; + +let ethersNamehash = null; +let ethersGetAddress = null; + +try { + // @ts-expect-error -- compatibility hack + ethersNamehash = ethers.utils.namehash; + // @ts-expect-error -- compatibility hack + ethersGetAddress = ethers.utils.getAddress; +} catch { + ethersNamehash = ethers.namehash as (message: Uint8Array | string) => string; + + ethersGetAddress = ethers.getAddress as (address: string) => string; +} +export const namehash = ethersNamehash as (name: string) => string; +export const getAddress = ethersGetAddress as (address: string) => string; diff --git a/packages/@justaname.id/siwens/README.md b/packages/@justaname.id/siwens/README.md index 067c7dee..727d6e1b 100644 --- a/packages/@justaname.id/siwens/README.md +++ b/packages/@justaname.id/siwens/README.md @@ -43,54 +43,60 @@ yarn add @justaname.id/siwens ### Example Usage ```typescript -import { SIWENS, InvalidDomainException, InvalidENSException, InvalidStatementException, InvalidTimeException } f, InvalidDomainException, InvalidENSException, InvalidStatementException, InvalidTimeException } from '@justaname.id/siwens';rom '@justaname.id/siwens'; -import { ethers } from 'ethers'; +import { SIWENS, InvalidENSException } from '@justaname.id/siwens'; +import { Wallet } from 'ethers'; // Define your provider URL (e.g., Infura) -const providerUrl = 'https://mainnet.infura.io/v3/YOUR_INFURA_KEY'; +const infuraProjectId = 'YOUR_INFURA_PROJECT_ID'; +const providerUrl = 'https://mainnet.infura.io/v3/' + infuraProjectId; -const signer = new ethers.Wallet('YOUR_PRIVATE_KEY_ENS_HOLDER') +// const signer = Wallet.createRandom(); +const signer = new Wallet('YOUR_PRIVATE_KEY'); async function signInUser() { const siwens = new SIWENS({ params: { - domain: 'example.eth', // The domain you're authenticating for + domain: 'example.com', // The domain you're authenticating for + uri: 'https://example.com', // The URI of the dApp + chainId: 1, // The chain ID of the network ttl: 3600000, // Time-to-Live (TTL) in milliseconds (1 hour) ens: 'user.example.eth', // The ENS name being used statement: 'Signing into dApp', // Optional custom sign-in statement + address: signer.address }, providerUrl - }); + }); const message = await siwens.prepareMessage(); const signature = await signer.signMessage(message); - return signature; + return {signature, message}; } // Verifying a user's sign-in request -async function verifyUserSignature(signature: string, message: string) { - try { - const siwe = new SIWENS({ - params: message, - providerUrl - }) - - const verification = await siwe.verifySignature({ - signature: signature, - }); - - console.log('ENS Sign-in successful!', verification.ens); - } catch (error) { - if (error instanceof InvalidENSException) { - console.error('ENS Verification Failed:', error.message); - } else { - console.error('Error during verification:', error.message); - } - } +async function verifyUserSignature(signature, message) { + try { + const siwe = new SIWENS({ + params: message, + providerUrl + }) + + const verification = await siwe.verify({ + signature: signature, + }); + + console.log('ENS Sign-in successful!', verification.ens); + } catch (error) { + console.error('Error during verification:', error); + if (error instanceof InvalidENSException) { + console.error('ENS Verification Failed:', error.message); + } else { + console.error('Error during verification:', error); + } + } } // Example usage -signInUser().then(async (signature) => { - await verifyUserSignature(signature, 'Signing into dApp'); +signInUser().then(async ({message, signature}) => { + await verifyUserSignature(signature, message); }); ``` diff --git a/packages/@justaname.id/siwens/package.json b/packages/@justaname.id/siwens/package.json index e01effc2..1bfd739c 100644 --- a/packages/@justaname.id/siwens/package.json +++ b/packages/@justaname.id/siwens/package.json @@ -2,7 +2,7 @@ "name": "@justaname.id/siwens", "version": "0.0.85", "peerDependencies": { - "ethers": ">=6.0.0", + "ethers": "^5.6.8 || ^6.0.8", "siwe": ">=2.0.0" }, "exports": { diff --git a/packages/@justaname.id/siwens/src/lib/siwens/siwens.ts b/packages/@justaname.id/siwens/src/lib/siwens/siwens.ts index d12c68ca..c85ddcb7 100644 --- a/packages/@justaname.id/siwens/src/lib/siwens/siwens.ts +++ b/packages/@justaname.id/siwens/src/lib/siwens/siwens.ts @@ -1,4 +1,3 @@ -import { JsonRpcProvider } from 'ethers'; import { generateNonce, SiweMessage, @@ -19,6 +18,7 @@ import { extractDataFromStatement, } from '../utils'; import { toASCII, toUnicode } from 'punycode'; +import { getJsonRpcProvider, JsonRpcProvider } from '../utils/ethersCompat'; export interface SiwensResponse extends SiweResponse { ens: string; @@ -50,7 +50,7 @@ export class SIWENS extends SiweMessage { if (!providerUrl) { throw InvalidConfigurationException.providerUrlRequired(); } - this.provider = new JsonRpcProvider(providerUrl); + this.provider = getJsonRpcProvider(providerUrl); this.providerUrl = providerUrl; return; } @@ -91,12 +91,12 @@ export class SIWENS extends SiweMessage { expirationTime, }); this.providerUrl = providerUrl; - this.provider = new JsonRpcProvider(providerUrl); + this.provider = getJsonRpcProvider(providerUrl); } override async verify( params: VerifyParams, - opts: VerifyOpts + opts?: VerifyOpts ): Promise { let verification: SiweResponse; diff --git a/packages/@justaname.id/siwens/src/lib/utils/ethersCompat.ts b/packages/@justaname.id/siwens/src/lib/utils/ethersCompat.ts new file mode 100644 index 00000000..dcc041b5 --- /dev/null +++ b/packages/@justaname.id/siwens/src/lib/utils/ethersCompat.ts @@ -0,0 +1,42 @@ +// inspired by spruceid siwe: https://github.com/spruceid/siwe/blob/main/packages/siwe/lib/ethersCompat.ts + +import { ethers } from 'ethers'; +// @ts-expect-error -- compatibility hack +type ProviderV5 = ethers.providers.Provider; +type ProviderV6 = ethers.Provider; +// @ts-expect-error -- compatibility hack +type JsonRpcProviderV5 = ethers.providers.JsonRpcProvider; +type JsonRpcProviderV6 = ethers.JsonRpcProvider; + +export type Provider = ProviderV6 extends undefined ? ProviderV5 : ProviderV6; +export type JsonRpcProvider = JsonRpcProviderV6 extends undefined + ? JsonRpcProviderV5 + : JsonRpcProviderV6; + +export const getJsonRpcProvider = ( + providerUrl?: string | undefined, + chainId?: number +): JsonRpcProvider => { + try { + return new ethers.JsonRpcProvider(providerUrl, chainId); + } catch { + // @ts-expect-error -- compatibility hack + return new ethers.providers.JsonRpcProvider(providerUrl, chainId); + } +}; + +let ethersNamehash = null; +let ethersGetAddress = null; + +try { + // @ts-expect-error -- compatibility hack + ethersNamehash = ethers.utils.namehash; + // @ts-expect-error -- compatibility hack + ethersGetAddress = ethers.utils.getAddress; +} catch { + ethersNamehash = ethers.namehash as (message: Uint8Array | string) => string; + + ethersGetAddress = ethers.getAddress as (address: string) => string; +} +export const namehash = ethersNamehash as (name: string) => string; +export const getAddress = ethersGetAddress as (address: string) => string; diff --git a/packages/@justweb3/ui/src/lib/components/ClickableItem/index.tsx b/packages/@justweb3/ui/src/lib/components/ClickableItem/index.tsx index 9be1c6ce..827ba83e 100644 --- a/packages/@justweb3/ui/src/lib/components/ClickableItem/index.tsx +++ b/packages/@justweb3/ui/src/lib/components/ClickableItem/index.tsx @@ -52,10 +52,11 @@ export const ClickableItem = React.forwardRef<
{ + onClick={(e) => { if (!loading && !disabled && clickable) { onClick && onClick(); } + e.stopPropagation(); }} onPointerEnter={() => { if (!loading && !disabled && clickable) { diff --git a/packages/@justweb3/widget/src/lib/components/JustEnsCard/JustEnsCard.module.css b/packages/@justweb3/widget/src/lib/components/JustEnsCard/JustEnsCard.module.css index f4468019..11751fc2 100644 --- a/packages/@justweb3/widget/src/lib/components/JustEnsCard/JustEnsCard.module.css +++ b/packages/@justweb3/widget/src/lib/components/JustEnsCard/JustEnsCard.module.css @@ -1,6 +1,7 @@ .expandableCard { - height: 200px; - width: 400px; + height: 193px; + box-sizing: content-box; + width: 398px; display: flex; flex-direction: column; position: relative; diff --git a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx index fba60a52..1cfba830 100644 --- a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx +++ b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx @@ -1,22 +1,16 @@ import { JustEnsCard, - JustWeb3Button, JustWeb3Provider, JustWeb3ProviderConfig, } from '@justweb3/widget'; import '@justweb3/widget/styles.css'; -import { - ConnectButton, - getDefaultConfig, - RainbowKitProvider, -} from '@rainbow-me/rainbowkit'; +import { getDefaultConfig, RainbowKitProvider } from '@rainbow-me/rainbowkit'; import '@rainbow-me/rainbowkit/styles.css'; import { Meta, StoryObj } from '@storybook/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { WagmiProvider } from 'wagmi'; import { mainnet, sepolia } from 'wagmi/chains'; import { XMTPPlugin } from '../lib'; -import { ChainId } from '@justaname.id/sdk'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import { EFPPlugin } from '@justweb3/efp-plugin'; import { POAPPlugin } from '@justweb3/poap-plugin'; @@ -26,12 +20,12 @@ import { JustVerifiedPlugin } from '@justverified/plugin'; const queryClient = new QueryClient(); const JustWeb3Config: JustWeb3ProviderConfig = { - config: { - origin: import.meta.env.STORYBOOK_APP_ORIGIN, - domain: import.meta.env.STORYBOOK_APP_DOMAIN, - signInTtl: 1000 * 60 * 60 * 24, - }, - backendUrl: import.meta.env.STORYBOOK_APP_BACKEND_URL, + // config: { + // origin: import.meta.env.STORYBOOK_APP_ORIGIN, + // domain: import.meta.env.STORYBOOK_APP_DOMAIN, + // signInTtl: 1000 * 60 * 60 * 24, + // }, + // backendUrl: import.meta.env.STORYBOOK_APP_BACKEND_URL, networks: [ { chainId: 1, @@ -42,15 +36,15 @@ const JustWeb3Config: JustWeb3ProviderConfig = { providerUrl: import.meta.env.STORYBOOK_APP_SEPOLIA_PROVIDER_URL, }, ], - ensDomains: [ - { - ensDomain: import.meta.env.STORYBOOK_APP_ENS_DOMAIN, - chainId: parseInt(import.meta.env.STORYBOOK_APP_CHAIN_ID) as ChainId, - }, - ], + // ensDomains: [ + // { + // ensDomain: import.meta.env.STORYBOOK_APP_ENS_DOMAIN, + // chainId: parseInt(import.meta.env.STORYBOOK_APP_CHAIN_ID) as ChainId, + // }, + // ], openOnWalletConnect: false, - allowedEns: 'all', - dev: import.meta.env.STORYBOOK_APP_DEV === 'true', + // allowedEns: 'all', + // dev: import.meta.env.STORYBOOK_APP_DEV === 'true', plugins: [ XMTPPlugin, EFPPlugin, @@ -89,11 +83,11 @@ export const Example = () => { flexDirection: 'column', }} > -
- - - -
+ {/*
*/} + {/* */} + {/* */} + {/* */} + {/*
*/}
@@ -104,6 +98,13 @@ export const Example = () => { + + + + + + + { />
- - - - - - + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/}
From dd7436831c39052cd85beb7c44c93710f52eda5e Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Sun, 1 Dec 2024 02:48:53 +0200 Subject: [PATCH 15/29] chore(release): publish [skip ci] - project: @justaname.id/sdk 0.2.153 - project: @justaname.id/react 0.3.156 - project: @justaname.id/siwens 0.0.86 - project: @justweb3/ui 0.0.92 - project: @justweb3/widget 0.0.92 - project: @justverified/plugin 0.0.91 - project: @justweb3/efp-plugin 0.1.52 - project: @justweb3/poap-plugin 0.0.10 - project: @justweb3/talent-protocol-plugin 0.0.10 --- packages/@justaname.id/react/CHANGELOG.md | 17 +++++++++++++ packages/@justaname.id/react/package.json | 4 ++-- packages/@justaname.id/sdk/CHANGELOG.md | 17 +++++++++++++ packages/@justaname.id/sdk/package.json | 4 ++-- packages/@justaname.id/siwens/CHANGELOG.md | 12 ++++++++++ packages/@justaname.id/siwens/package.json | 2 +- packages/@justverified/plugin/CHANGELOG.md | 4 ++++ packages/@justverified/plugin/package.json | 2 +- packages/@justweb3/efp-plugin/CHANGELOG.md | 4 ++++ packages/@justweb3/efp-plugin/package.json | 2 +- packages/@justweb3/poap-plugin/package.json | 2 +- .../talent-protocol-plugin/package.json | 2 +- packages/@justweb3/ui/CHANGELOG.md | 12 ++++++++++ packages/@justweb3/ui/package.json | 2 +- packages/@justweb3/widget/CHANGELOG.md | 19 +++++++++++++++ packages/@justweb3/widget/package.json | 8 +++---- yarn.lock | 24 +++++++++---------- 17 files changed, 111 insertions(+), 26 deletions(-) diff --git a/packages/@justaname.id/react/CHANGELOG.md b/packages/@justaname.id/react/CHANGELOG.md index 26ad1bfe..2827e840 100644 --- a/packages/@justaname.id/react/CHANGELOG.md +++ b/packages/@justaname.id/react/CHANGELOG.md @@ -1,3 +1,20 @@ +## 0.3.156 (2024-12-01) + + +### 🚀 Features + +- support ethers 5 and ethers 6 ([f82ab13](https://github.com/JustaName-id/JustaName-sdk/commit/f82ab13)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.153 + + +### ❤️ Thank You + +- HadiKhai + ## 0.3.155 (2024-11-29) diff --git a/packages/@justaname.id/react/package.json b/packages/@justaname.id/react/package.json index 1d4ee357..b06ccdce 100644 --- a/packages/@justaname.id/react/package.json +++ b/packages/@justaname.id/react/package.json @@ -1,9 +1,9 @@ { "name": "@justaname.id/react", - "version": "0.3.155", + "version": "0.3.156", "dependencies": { "@ensdomains/ensjs": "4.0.2", - "@justaname.id/sdk": "0.2.152", + "@justaname.id/sdk": "0.2.153", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/sdk/CHANGELOG.md b/packages/@justaname.id/sdk/CHANGELOG.md index 2b4a989e..43ff92cf 100644 --- a/packages/@justaname.id/sdk/CHANGELOG.md +++ b/packages/@justaname.id/sdk/CHANGELOG.md @@ -1,3 +1,20 @@ +## 0.2.153 (2024-12-01) + + +### 🚀 Features + +- support ethers 5 and ethers 6 ([f82ab13](https://github.com/JustaName-id/JustaName-sdk/commit/f82ab13)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/siwens to 0.0.86 + + +### ❤️ Thank You + +- HadiKhai + ## 0.2.152 (2024-11-29) diff --git a/packages/@justaname.id/sdk/package.json b/packages/@justaname.id/sdk/package.json index f44814b1..9e6861fd 100644 --- a/packages/@justaname.id/sdk/package.json +++ b/packages/@justaname.id/sdk/package.json @@ -1,8 +1,8 @@ { "name": "@justaname.id/sdk", - "version": "0.2.152", + "version": "0.2.153", "dependencies": { - "@justaname.id/siwens": "0.0.85", + "@justaname.id/siwens": "0.0.86", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/siwens/CHANGELOG.md b/packages/@justaname.id/siwens/CHANGELOG.md index 4180e99b..c00dbee5 100644 --- a/packages/@justaname.id/siwens/CHANGELOG.md +++ b/packages/@justaname.id/siwens/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.0.86 (2024-12-01) + + +### 🚀 Features + +- support ethers 5 and ethers 6 ([f82ab13](https://github.com/JustaName-id/JustaName-sdk/commit/f82ab13)) + + +### ❤️ Thank You + +- HadiKhai + ## 0.0.85 (2024-11-29) This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. diff --git a/packages/@justaname.id/siwens/package.json b/packages/@justaname.id/siwens/package.json index 1bfd739c..2aeb7654 100644 --- a/packages/@justaname.id/siwens/package.json +++ b/packages/@justaname.id/siwens/package.json @@ -1,6 +1,6 @@ { "name": "@justaname.id/siwens", - "version": "0.0.85", + "version": "0.0.86", "peerDependencies": { "ethers": "^5.6.8 || ^6.0.8", "siwe": ">=2.0.0" diff --git a/packages/@justverified/plugin/CHANGELOG.md b/packages/@justverified/plugin/CHANGELOG.md index e0177be2..e64185f1 100644 --- a/packages/@justverified/plugin/CHANGELOG.md +++ b/packages/@justverified/plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.91 (2024-12-01) + +This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. + ## 0.0.90 (2024-11-29) This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. diff --git a/packages/@justverified/plugin/package.json b/packages/@justverified/plugin/package.json index 7b454ba7..2dfdb9ae 100644 --- a/packages/@justverified/plugin/package.json +++ b/packages/@justverified/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justverified/plugin", - "version": "0.0.90", + "version": "0.0.91", "dependencies": { "axios": "^1.6.0", "lodash": "4.17.21", diff --git a/packages/@justweb3/efp-plugin/CHANGELOG.md b/packages/@justweb3/efp-plugin/CHANGELOG.md index 722cb01e..1845fac7 100644 --- a/packages/@justweb3/efp-plugin/CHANGELOG.md +++ b/packages/@justweb3/efp-plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.52 (2024-12-01) + +This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. + ## 0.1.51 (2024-11-29) This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/efp-plugin/package.json b/packages/@justweb3/efp-plugin/package.json index ae26a786..fa7b2d05 100644 --- a/packages/@justweb3/efp-plugin/package.json +++ b/packages/@justweb3/efp-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/efp-plugin", - "version": "0.1.51", + "version": "0.1.52", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/poap-plugin/package.json b/packages/@justweb3/poap-plugin/package.json index a5276346..d3281111 100644 --- a/packages/@justweb3/poap-plugin/package.json +++ b/packages/@justweb3/poap-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/poap-plugin", - "version": "0.0.9", + "version": "0.0.10", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/talent-protocol-plugin/package.json b/packages/@justweb3/talent-protocol-plugin/package.json index 9303f74a..67f8f2fc 100644 --- a/packages/@justweb3/talent-protocol-plugin/package.json +++ b/packages/@justweb3/talent-protocol-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/talent-protocol-plugin", - "version": "0.0.9", + "version": "0.0.10", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/ui/CHANGELOG.md b/packages/@justweb3/ui/CHANGELOG.md index 24c4c2d6..6b814ee0 100644 --- a/packages/@justweb3/ui/CHANGELOG.md +++ b/packages/@justweb3/ui/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.0.92 (2024-12-01) + + +### 🚀 Features + +- support ethers 5 and ethers 6 ([f82ab13](https://github.com/JustaName-id/JustaName-sdk/commit/f82ab13)) + + +### ❤️ Thank You + +- HadiKhai + ## 0.0.91 (2024-11-29) This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/ui/package.json b/packages/@justweb3/ui/package.json index 8d530420..4b7bd8c4 100644 --- a/packages/@justweb3/ui/package.json +++ b/packages/@justweb3/ui/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/ui", - "version": "0.0.91", + "version": "0.0.92", "dependencies": { "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dialog": "^1.1.1", diff --git a/packages/@justweb3/widget/CHANGELOG.md b/packages/@justweb3/widget/CHANGELOG.md index 2632c8d4..164ce523 100644 --- a/packages/@justweb3/widget/CHANGELOG.md +++ b/packages/@justweb3/widget/CHANGELOG.md @@ -1,3 +1,22 @@ +## 0.0.92 (2024-12-01) + + +### 🚀 Features + +- support ethers 5 and ethers 6 ([f82ab13](https://github.com/JustaName-id/JustaName-sdk/commit/f82ab13)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.153 +- Updated @justaname.id/react to 0.3.156 +- Updated @justweb3/ui to 0.0.92 + + +### ❤️ Thank You + +- HadiKhai + ## 0.0.91 (2024-11-29) diff --git a/packages/@justweb3/widget/package.json b/packages/@justweb3/widget/package.json index 6f84d53f..9110d10f 100644 --- a/packages/@justweb3/widget/package.json +++ b/packages/@justweb3/widget/package.json @@ -1,12 +1,12 @@ { "name": "@justweb3/widget", - "version": "0.0.91", + "version": "0.0.92", "dependencies": { "@ensdomains/address-encoder": "^1.1.2", "@hookform/resolvers": "^3.9.0", - "@justaname.id/react": "0.3.155", - "@justaname.id/sdk": "0.2.152", - "@justweb3/ui": "^0.0.91", + "@justaname.id/react": "0.3.156", + "@justaname.id/sdk": "0.2.153", + "@justweb3/ui": "^0.0.92", "clsx": "1.2.1", "cropperjs": "^1.6.2", "lodash": "4.17.21", diff --git a/yarn.lock b/yarn.lock index 90201bcc..e2c96eb3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4514,44 +4514,44 @@ __metadata: languageName: node linkType: hard -"@justaname.id/react@npm:0.3.155, @justaname.id/react@workspace:packages/@justaname.id/react": +"@justaname.id/react@npm:0.3.156, @justaname.id/react@workspace:packages/@justaname.id/react": version: 0.0.0-use.local resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" dependencies: "@ensdomains/ensjs": "npm:4.0.2" - "@justaname.id/sdk": "npm:0.2.152" + "@justaname.id/sdk": "npm:0.2.153" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" peerDependencies: "@tanstack/react-query": ^5.x - ethers: ^6.x + ethers: ^5.6.8 || ^6.0.8 react: ">=17" viem: 2.x wagmi: 2.x languageName: unknown linkType: soft -"@justaname.id/sdk@npm:0.2.152, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": +"@justaname.id/sdk@npm:0.2.153, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": version: 0.0.0-use.local resolution: "@justaname.id/sdk@workspace:packages/@justaname.id/sdk" dependencies: - "@justaname.id/siwens": "npm:0.0.85" + "@justaname.id/siwens": "npm:0.0.86" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" peerDependencies: - ethers: ">=6.0.0" + ethers: ^5.6.8 || ^6.0.8 siwe: ">=2.0.0" viem: ">=2.0.0" languageName: unknown linkType: soft -"@justaname.id/siwens@npm:0.0.85, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": +"@justaname.id/siwens@npm:0.0.86, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": version: 0.0.0-use.local resolution: "@justaname.id/siwens@workspace:packages/@justaname.id/siwens" peerDependencies: - ethers: ">=6.0.0" + ethers: ^5.6.8 || ^6.0.8 siwe: ">=2.0.0" languageName: unknown linkType: soft @@ -4607,7 +4607,7 @@ __metadata: languageName: unknown linkType: soft -"@justweb3/ui@npm:^0.0.91, @justweb3/ui@workspace:packages/@justweb3/ui": +"@justweb3/ui@npm:^0.0.92, @justweb3/ui@workspace:packages/@justweb3/ui": version: 0.0.0-use.local resolution: "@justweb3/ui@workspace:packages/@justweb3/ui" dependencies: @@ -4635,9 +4635,9 @@ __metadata: dependencies: "@ensdomains/address-encoder": "npm:^1.1.2" "@hookform/resolvers": "npm:^3.9.0" - "@justaname.id/react": "npm:0.3.155" - "@justaname.id/sdk": "npm:0.2.152" - "@justweb3/ui": "npm:^0.0.91" + "@justaname.id/react": "npm:0.3.156" + "@justaname.id/sdk": "npm:0.2.153" + "@justweb3/ui": "npm:^0.0.92" clsx: "npm:1.2.1" cropperjs: "npm:^1.6.2" lodash: "npm:4.17.21" From 144583f57587c2713a02fccf0c01c54f69e0f603 Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Mon, 2 Dec 2024 07:30:31 +0200 Subject: [PATCH 16/29] chore(release): publish [skip ci] - project: @justaname.id/sdk 0.2.154 - project: @justaname.id/react 0.3.157 - project: @justaname.id/siwens 0.0.87 - project: @justweb3/ui 0.0.93 - project: @justweb3/widget 0.0.93 - project: @justverified/plugin 0.0.92 - project: @justweb3/efp-plugin 0.1.53 - project: @justweb3/poap-plugin 0.0.11 - project: @justweb3/talent-protocol-plugin 0.0.11 --- packages/@justaname.id/react/CHANGELOG.md | 7 +++++++ packages/@justaname.id/react/package.json | 4 ++-- packages/@justaname.id/sdk/CHANGELOG.md | 7 +++++++ packages/@justaname.id/sdk/package.json | 4 ++-- packages/@justaname.id/siwens/CHANGELOG.md | 4 ++++ packages/@justaname.id/siwens/package.json | 2 +- packages/@justverified/plugin/CHANGELOG.md | 4 ++++ packages/@justverified/plugin/package.json | 2 +- packages/@justweb3/efp-plugin/CHANGELOG.md | 4 ++++ packages/@justweb3/efp-plugin/package.json | 2 +- packages/@justweb3/poap-plugin/package.json | 2 +- .../talent-protocol-plugin/package.json | 2 +- packages/@justweb3/ui/CHANGELOG.md | 4 ++++ packages/@justweb3/ui/package.json | 2 +- packages/@justweb3/widget/CHANGELOG.md | 9 +++++++++ packages/@justweb3/widget/package.json | 8 ++++---- yarn.lock | 18 +++++++++--------- 17 files changed, 62 insertions(+), 23 deletions(-) diff --git a/packages/@justaname.id/react/CHANGELOG.md b/packages/@justaname.id/react/CHANGELOG.md index 2827e840..11102e1b 100644 --- a/packages/@justaname.id/react/CHANGELOG.md +++ b/packages/@justaname.id/react/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.3.157 (2024-12-02) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.154 + ## 0.3.156 (2024-12-01) diff --git a/packages/@justaname.id/react/package.json b/packages/@justaname.id/react/package.json index b06ccdce..679807f8 100644 --- a/packages/@justaname.id/react/package.json +++ b/packages/@justaname.id/react/package.json @@ -1,9 +1,9 @@ { "name": "@justaname.id/react", - "version": "0.3.156", + "version": "0.3.157", "dependencies": { "@ensdomains/ensjs": "4.0.2", - "@justaname.id/sdk": "0.2.153", + "@justaname.id/sdk": "0.2.154", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/sdk/CHANGELOG.md b/packages/@justaname.id/sdk/CHANGELOG.md index 43ff92cf..4c46437e 100644 --- a/packages/@justaname.id/sdk/CHANGELOG.md +++ b/packages/@justaname.id/sdk/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.2.154 (2024-12-02) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/siwens to 0.0.87 + ## 0.2.153 (2024-12-01) diff --git a/packages/@justaname.id/sdk/package.json b/packages/@justaname.id/sdk/package.json index 9e6861fd..5c60efb9 100644 --- a/packages/@justaname.id/sdk/package.json +++ b/packages/@justaname.id/sdk/package.json @@ -1,8 +1,8 @@ { "name": "@justaname.id/sdk", - "version": "0.2.153", + "version": "0.2.154", "dependencies": { - "@justaname.id/siwens": "0.0.86", + "@justaname.id/siwens": "0.0.87", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/siwens/CHANGELOG.md b/packages/@justaname.id/siwens/CHANGELOG.md index c00dbee5..6adfffb0 100644 --- a/packages/@justaname.id/siwens/CHANGELOG.md +++ b/packages/@justaname.id/siwens/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.87 (2024-12-02) + +This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. + ## 0.0.86 (2024-12-01) diff --git a/packages/@justaname.id/siwens/package.json b/packages/@justaname.id/siwens/package.json index 2aeb7654..580e7629 100644 --- a/packages/@justaname.id/siwens/package.json +++ b/packages/@justaname.id/siwens/package.json @@ -1,6 +1,6 @@ { "name": "@justaname.id/siwens", - "version": "0.0.86", + "version": "0.0.87", "peerDependencies": { "ethers": "^5.6.8 || ^6.0.8", "siwe": ">=2.0.0" diff --git a/packages/@justverified/plugin/CHANGELOG.md b/packages/@justverified/plugin/CHANGELOG.md index e64185f1..727d1eae 100644 --- a/packages/@justverified/plugin/CHANGELOG.md +++ b/packages/@justverified/plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.92 (2024-12-02) + +This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. + ## 0.0.91 (2024-12-01) This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. diff --git a/packages/@justverified/plugin/package.json b/packages/@justverified/plugin/package.json index 2dfdb9ae..ace7f9ee 100644 --- a/packages/@justverified/plugin/package.json +++ b/packages/@justverified/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justverified/plugin", - "version": "0.0.91", + "version": "0.0.92", "dependencies": { "axios": "^1.6.0", "lodash": "4.17.21", diff --git a/packages/@justweb3/efp-plugin/CHANGELOG.md b/packages/@justweb3/efp-plugin/CHANGELOG.md index 1845fac7..5aa394cc 100644 --- a/packages/@justweb3/efp-plugin/CHANGELOG.md +++ b/packages/@justweb3/efp-plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.53 (2024-12-02) + +This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. + ## 0.1.52 (2024-12-01) This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/efp-plugin/package.json b/packages/@justweb3/efp-plugin/package.json index fa7b2d05..3bf60963 100644 --- a/packages/@justweb3/efp-plugin/package.json +++ b/packages/@justweb3/efp-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/efp-plugin", - "version": "0.1.52", + "version": "0.1.53", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/poap-plugin/package.json b/packages/@justweb3/poap-plugin/package.json index d3281111..892b2cda 100644 --- a/packages/@justweb3/poap-plugin/package.json +++ b/packages/@justweb3/poap-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/poap-plugin", - "version": "0.0.10", + "version": "0.0.11", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/talent-protocol-plugin/package.json b/packages/@justweb3/talent-protocol-plugin/package.json index 67f8f2fc..28749f91 100644 --- a/packages/@justweb3/talent-protocol-plugin/package.json +++ b/packages/@justweb3/talent-protocol-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/talent-protocol-plugin", - "version": "0.0.10", + "version": "0.0.11", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/ui/CHANGELOG.md b/packages/@justweb3/ui/CHANGELOG.md index 6b814ee0..64fdc447 100644 --- a/packages/@justweb3/ui/CHANGELOG.md +++ b/packages/@justweb3/ui/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.93 (2024-12-02) + +This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. + ## 0.0.92 (2024-12-01) diff --git a/packages/@justweb3/ui/package.json b/packages/@justweb3/ui/package.json index 4b7bd8c4..3f2bc8c8 100644 --- a/packages/@justweb3/ui/package.json +++ b/packages/@justweb3/ui/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/ui", - "version": "0.0.92", + "version": "0.0.93", "dependencies": { "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dialog": "^1.1.1", diff --git a/packages/@justweb3/widget/CHANGELOG.md b/packages/@justweb3/widget/CHANGELOG.md index 164ce523..4dcb74e0 100644 --- a/packages/@justweb3/widget/CHANGELOG.md +++ b/packages/@justweb3/widget/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.0.93 (2024-12-02) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.154 +- Updated @justaname.id/react to 0.3.157 +- Updated @justweb3/ui to 0.0.93 + ## 0.0.92 (2024-12-01) diff --git a/packages/@justweb3/widget/package.json b/packages/@justweb3/widget/package.json index 9110d10f..2c21ce92 100644 --- a/packages/@justweb3/widget/package.json +++ b/packages/@justweb3/widget/package.json @@ -1,12 +1,12 @@ { "name": "@justweb3/widget", - "version": "0.0.92", + "version": "0.0.93", "dependencies": { "@ensdomains/address-encoder": "^1.1.2", "@hookform/resolvers": "^3.9.0", - "@justaname.id/react": "0.3.156", - "@justaname.id/sdk": "0.2.153", - "@justweb3/ui": "^0.0.92", + "@justaname.id/react": "0.3.157", + "@justaname.id/sdk": "0.2.154", + "@justweb3/ui": "^0.0.93", "clsx": "1.2.1", "cropperjs": "^1.6.2", "lodash": "4.17.21", diff --git a/yarn.lock b/yarn.lock index e2c96eb3..0905d656 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4514,12 +4514,12 @@ __metadata: languageName: node linkType: hard -"@justaname.id/react@npm:0.3.156, @justaname.id/react@workspace:packages/@justaname.id/react": +"@justaname.id/react@npm:0.3.157, @justaname.id/react@workspace:packages/@justaname.id/react": version: 0.0.0-use.local resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" dependencies: "@ensdomains/ensjs": "npm:4.0.2" - "@justaname.id/sdk": "npm:0.2.153" + "@justaname.id/sdk": "npm:0.2.154" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4532,11 +4532,11 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/sdk@npm:0.2.153, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": +"@justaname.id/sdk@npm:0.2.154, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": version: 0.0.0-use.local resolution: "@justaname.id/sdk@workspace:packages/@justaname.id/sdk" dependencies: - "@justaname.id/siwens": "npm:0.0.86" + "@justaname.id/siwens": "npm:0.0.87" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4547,7 +4547,7 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/siwens@npm:0.0.86, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": +"@justaname.id/siwens@npm:0.0.87, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": version: 0.0.0-use.local resolution: "@justaname.id/siwens@workspace:packages/@justaname.id/siwens" peerDependencies: @@ -4607,7 +4607,7 @@ __metadata: languageName: unknown linkType: soft -"@justweb3/ui@npm:^0.0.92, @justweb3/ui@workspace:packages/@justweb3/ui": +"@justweb3/ui@npm:^0.0.93, @justweb3/ui@workspace:packages/@justweb3/ui": version: 0.0.0-use.local resolution: "@justweb3/ui@workspace:packages/@justweb3/ui" dependencies: @@ -4635,9 +4635,9 @@ __metadata: dependencies: "@ensdomains/address-encoder": "npm:^1.1.2" "@hookform/resolvers": "npm:^3.9.0" - "@justaname.id/react": "npm:0.3.156" - "@justaname.id/sdk": "npm:0.2.153" - "@justweb3/ui": "npm:^0.0.92" + "@justaname.id/react": "npm:0.3.157" + "@justaname.id/sdk": "npm:0.2.154" + "@justweb3/ui": "npm:^0.0.93" clsx: "npm:1.2.1" cropperjs: "npm:^1.6.2" lodash: "npm:4.17.21" From aec600f52603a346db3233906e2e2815e320e9e9 Mon Sep 17 00:00:00 2001 From: anthony2399 Date: Mon, 2 Dec 2024 17:19:28 +0200 Subject: [PATCH 17/29] fix: yarn --- yarn.lock | 300 ++++-------------------------------------------------- 1 file changed, 18 insertions(+), 282 deletions(-) diff --git a/yarn.lock b/yarn.lock index 996edcfd..25fd2303 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,6 +1,9 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + __metadata: version: 8 - cacheKey: merged + cacheKey: 10c0 "@0no-co/graphql.web@npm:^1.0.5": version: 1.0.9 @@ -2060,25 +2063,6 @@ __metadata: languageName: node linkType: hard -"@ensdomains/ensjs@npm:4.0.1-alpha.0": - version: 4.0.1-alpha.0 - resolution: "@ensdomains/ensjs@npm:4.0.1-alpha.0" - dependencies: - "@adraffy/ens-normalize": "npm:1.10.1" - "@ensdomains/address-encoder": "npm:1.1.1" - "@ensdomains/content-hash": "npm:3.1.0-rc.1" - "@ensdomains/dnsprovejs": "npm:^0.5.1" - abitype: "npm:^1.0.0" - dns-packet: "npm:^5.3.1" - graphql: "npm:^16.3.0" - graphql-request: "npm:6.1.0" - pako: "npm:^2.1.0" - peerDependencies: - viem: ^2.9.2 - checksum: 10c0/44acb914772d8ad85ab0b4ea30f10d20da39213aa317f26fbbf9329bfcda8876666ed50905fccb4b89d8b4cc7e272aa1d40c3f5fc15ab89a62b6c01d07a4c05e - languageName: node - linkType: hard - "@ensdomains/ensjs@npm:4.0.2": version: 4.0.2 resolution: "@ensdomains/ensjs@npm:4.0.2" @@ -2102,7 +2086,6 @@ __metadata: "@esbuild/aix-ppc64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/aix-ppc64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=aix & cpu=ppc64 languageName: node linkType: hard @@ -2110,7 +2093,6 @@ __metadata: "@esbuild/aix-ppc64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/aix-ppc64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=aix & cpu=ppc64 languageName: node linkType: hard @@ -2118,7 +2100,6 @@ __metadata: "@esbuild/android-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-arm64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -2126,7 +2107,6 @@ __metadata: "@esbuild/android-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/android-arm64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -2134,7 +2114,6 @@ __metadata: "@esbuild/android-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-arm64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -2142,7 +2121,6 @@ __metadata: "@esbuild/android-arm@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-arm@npm:0.18.20" - checksum: 10c0/undefined conditions: os=android & cpu=arm languageName: node linkType: hard @@ -2150,7 +2128,6 @@ __metadata: "@esbuild/android-arm@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/android-arm@npm:0.19.12" - checksum: 10c0/undefined conditions: os=android & cpu=arm languageName: node linkType: hard @@ -2158,7 +2135,6 @@ __metadata: "@esbuild/android-arm@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-arm@npm:0.21.5" - checksum: 10c0/undefined conditions: os=android & cpu=arm languageName: node linkType: hard @@ -2166,7 +2142,6 @@ __metadata: "@esbuild/android-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-x64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -2174,7 +2149,6 @@ __metadata: "@esbuild/android-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/android-x64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -2182,7 +2156,6 @@ __metadata: "@esbuild/android-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-x64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -2190,7 +2163,6 @@ __metadata: "@esbuild/darwin-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/darwin-arm64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -2198,7 +2170,6 @@ __metadata: "@esbuild/darwin-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/darwin-arm64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -2206,7 +2177,6 @@ __metadata: "@esbuild/darwin-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/darwin-arm64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -2214,7 +2184,6 @@ __metadata: "@esbuild/darwin-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/darwin-x64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -2222,7 +2191,6 @@ __metadata: "@esbuild/darwin-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/darwin-x64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -2230,7 +2198,6 @@ __metadata: "@esbuild/darwin-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/darwin-x64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -2238,7 +2205,6 @@ __metadata: "@esbuild/freebsd-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/freebsd-arm64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -2246,7 +2212,6 @@ __metadata: "@esbuild/freebsd-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/freebsd-arm64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -2254,7 +2219,6 @@ __metadata: "@esbuild/freebsd-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/freebsd-arm64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -2262,7 +2226,6 @@ __metadata: "@esbuild/freebsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/freebsd-x64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -2270,7 +2233,6 @@ __metadata: "@esbuild/freebsd-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/freebsd-x64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -2278,7 +2240,6 @@ __metadata: "@esbuild/freebsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/freebsd-x64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -2286,7 +2247,6 @@ __metadata: "@esbuild/linux-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-arm64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -2294,7 +2254,6 @@ __metadata: "@esbuild/linux-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-arm64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -2302,7 +2261,6 @@ __metadata: "@esbuild/linux-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-arm64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -2310,7 +2268,6 @@ __metadata: "@esbuild/linux-arm@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-arm@npm:0.18.20" - checksum: 10c0/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -2318,7 +2275,6 @@ __metadata: "@esbuild/linux-arm@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-arm@npm:0.19.12" - checksum: 10c0/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -2326,7 +2282,6 @@ __metadata: "@esbuild/linux-arm@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-arm@npm:0.21.5" - checksum: 10c0/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -2334,7 +2289,6 @@ __metadata: "@esbuild/linux-ia32@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-ia32@npm:0.18.20" - checksum: 10c0/undefined conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -2342,7 +2296,6 @@ __metadata: "@esbuild/linux-ia32@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-ia32@npm:0.19.12" - checksum: 10c0/undefined conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -2350,7 +2303,6 @@ __metadata: "@esbuild/linux-ia32@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-ia32@npm:0.21.5" - checksum: 10c0/undefined conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -2358,7 +2310,6 @@ __metadata: "@esbuild/linux-loong64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-loong64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -2366,7 +2317,6 @@ __metadata: "@esbuild/linux-loong64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-loong64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -2374,7 +2324,6 @@ __metadata: "@esbuild/linux-loong64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-loong64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -2382,7 +2331,6 @@ __metadata: "@esbuild/linux-mips64el@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-mips64el@npm:0.18.20" - checksum: 10c0/undefined conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -2390,7 +2338,6 @@ __metadata: "@esbuild/linux-mips64el@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-mips64el@npm:0.19.12" - checksum: 10c0/undefined conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -2398,7 +2345,6 @@ __metadata: "@esbuild/linux-mips64el@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-mips64el@npm:0.21.5" - checksum: 10c0/undefined conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -2406,7 +2352,6 @@ __metadata: "@esbuild/linux-ppc64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-ppc64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -2414,7 +2359,6 @@ __metadata: "@esbuild/linux-ppc64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-ppc64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -2422,7 +2366,6 @@ __metadata: "@esbuild/linux-ppc64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-ppc64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -2430,7 +2373,6 @@ __metadata: "@esbuild/linux-riscv64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-riscv64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -2438,7 +2380,6 @@ __metadata: "@esbuild/linux-riscv64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-riscv64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -2446,7 +2387,6 @@ __metadata: "@esbuild/linux-riscv64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-riscv64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -2454,7 +2394,6 @@ __metadata: "@esbuild/linux-s390x@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-s390x@npm:0.18.20" - checksum: 10c0/undefined conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -2462,7 +2401,6 @@ __metadata: "@esbuild/linux-s390x@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-s390x@npm:0.19.12" - checksum: 10c0/undefined conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -2470,7 +2408,6 @@ __metadata: "@esbuild/linux-s390x@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-s390x@npm:0.21.5" - checksum: 10c0/undefined conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -2478,7 +2415,6 @@ __metadata: "@esbuild/linux-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-x64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -2486,7 +2422,6 @@ __metadata: "@esbuild/linux-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-x64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -2494,7 +2429,6 @@ __metadata: "@esbuild/linux-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-x64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -2502,7 +2436,6 @@ __metadata: "@esbuild/netbsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/netbsd-x64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -2510,7 +2443,6 @@ __metadata: "@esbuild/netbsd-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/netbsd-x64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -2518,7 +2450,6 @@ __metadata: "@esbuild/netbsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/netbsd-x64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -2526,7 +2457,6 @@ __metadata: "@esbuild/openbsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/openbsd-x64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -2534,7 +2464,6 @@ __metadata: "@esbuild/openbsd-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/openbsd-x64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -2542,7 +2471,6 @@ __metadata: "@esbuild/openbsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/openbsd-x64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -2550,7 +2478,6 @@ __metadata: "@esbuild/sunos-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/sunos-x64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -2558,7 +2485,6 @@ __metadata: "@esbuild/sunos-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/sunos-x64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -2566,7 +2492,6 @@ __metadata: "@esbuild/sunos-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/sunos-x64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -2574,7 +2499,6 @@ __metadata: "@esbuild/win32-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-arm64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -2582,7 +2506,6 @@ __metadata: "@esbuild/win32-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/win32-arm64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -2590,7 +2513,6 @@ __metadata: "@esbuild/win32-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-arm64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -2598,7 +2520,6 @@ __metadata: "@esbuild/win32-ia32@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-ia32@npm:0.18.20" - checksum: 10c0/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -2606,7 +2527,6 @@ __metadata: "@esbuild/win32-ia32@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/win32-ia32@npm:0.19.12" - checksum: 10c0/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -2614,7 +2534,6 @@ __metadata: "@esbuild/win32-ia32@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-ia32@npm:0.21.5" - checksum: 10c0/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -2622,7 +2541,6 @@ __metadata: "@esbuild/win32-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-x64@npm:0.18.20" - checksum: 10c0/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -2630,7 +2548,6 @@ __metadata: "@esbuild/win32-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/win32-x64@npm:0.19.12" - checksum: 10c0/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -2638,7 +2555,6 @@ __metadata: "@esbuild/win32-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-x64@npm:0.21.5" - checksum: 10c0/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4598,25 +4514,6 @@ __metadata: languageName: node linkType: hard -"@justaname.id/react@npm:0.3.147, @justaname.id/react@workspace:packages/@justaname.id/react": - version: 0.0.0-use.local - resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" - dependencies: - "@ensdomains/ensjs": "npm:4.0.1-alpha.0" - "@justaname.id/sdk": "npm:0.2.144" - axios: "npm:^1.6.0" - jest: "npm:^29.4.1" - qs: "npm:^6.12.0" - peerDependencies: - "@tanstack/react-query": ^5.x - ethers: ^6.x - react: ">=17" - viem: 2.x - wagmi: 2.x - checksum: 10c0/undefined - languageName: unknown - linkType: soft - "@justaname.id/react@npm:0.3.149, @justaname.id/react@workspace:packages/@justaname.id/react": version: 0.0.0-use.local resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" @@ -4632,23 +4529,6 @@ __metadata: react: ">=17" viem: 2.x wagmi: 2.x - checksum: 10c0/undefined - languageName: unknown - linkType: soft - -"@justaname.id/sdk@npm:0.2.144, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": - version: 0.0.0-use.local - resolution: "@justaname.id/sdk@workspace:packages/@justaname.id/sdk" - dependencies: - "@justaname.id/siwens": "npm:0.0.77" - axios: "npm:^1.6.0" - jest: "npm:^29.4.1" - qs: "npm:^6.12.0" - peerDependencies: - ethers: ">=6.0.0" - siwe: ">=2.0.0" - viem: ">=2.0.0" - checksum: 10c0/undefined languageName: unknown linkType: soft @@ -4664,17 +4544,6 @@ __metadata: ethers: ">=6.0.0" siwe: ">=2.0.0" viem: ">=2.0.0" - checksum: 10c0/undefined - languageName: unknown - linkType: soft - -"@justaname.id/siwens@npm:0.0.77, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": - version: 0.0.0-use.local - resolution: "@justaname.id/siwens@workspace:packages/@justaname.id/siwens" - peerDependencies: - ethers: ">=6.0.0" - siwe: ">=2.0.0" - checksum: 10c0/undefined languageName: unknown linkType: soft @@ -4684,7 +4553,6 @@ __metadata: peerDependencies: ethers: ">=6.0.0" siwe: ">=2.0.0" - checksum: 10c0/undefined languageName: unknown linkType: soft @@ -4700,7 +4568,6 @@ __metadata: "@justweb3/widget": ">=0.0.0" "@tanstack/react-query": ^5.x react: ">=17" - checksum: 10c0/undefined languageName: unknown linkType: soft @@ -4713,7 +4580,6 @@ __metadata: "@justweb3/widget": ">=0.0.0" "@tanstack/react-query": ^5.x react: ">=17" - checksum: 10c0/undefined languageName: unknown linkType: soft @@ -4726,7 +4592,6 @@ __metadata: "@justweb3/widget": ">=0.0.0" "@tanstack/react-query": ^5.x react: ">=17" - checksum: 10c0/undefined languageName: unknown linkType: soft @@ -4739,27 +4604,6 @@ __metadata: "@justweb3/widget": ">=0.0.0" "@tanstack/react-query": ^5.x react: ">=17" - checksum: 10c0/undefined - languageName: unknown - linkType: soft - -"@justweb3/ui@npm:^0.0.83, @justweb3/ui@workspace:packages/@justweb3/ui": - version: 0.0.0-use.local - resolution: "@justweb3/ui@workspace:packages/@justweb3/ui" - dependencies: - "@radix-ui/react-dialog": "npm:^1.1.1" - "@radix-ui/react-dropdown-menu": "npm:^2.1.2" - "@radix-ui/react-label": "npm:^2.1.0" - "@radix-ui/react-popover": "npm:^1.1.1" - "@radix-ui/react-slot": "npm:1.1.0" - "@radix-ui/react-tabs": "npm:^1.1.1" - clsx: "npm:1.2.1" - embla-carousel-react: "npm:^8.3.0" - input-otp: "npm:^1.2.4" - react-hook-form: "npm:^7.53.0" - peerDependencies: - react: ">=17" - checksum: 10c0/undefined languageName: unknown linkType: soft @@ -4782,7 +4626,6 @@ __metadata: react-hook-form: "npm:^7.53.0" peerDependencies: react: ">=17" - checksum: 10c0/undefined languageName: unknown linkType: soft @@ -4791,11 +4634,10 @@ __metadata: resolution: "@justweb3/widget@workspace:packages/@justweb3/widget" dependencies: "@ensdomains/address-encoder": "npm:^1.1.2" - "@ensdomains/ensjs": "npm:4.0.1-alpha.0" "@hookform/resolvers": "npm:^3.9.0" - "@justaname.id/react": "npm:0.3.147" - "@justaname.id/sdk": "npm:0.2.144" - "@justweb3/ui": "npm:^0.0.83" + "@justaname.id/react": "npm:0.3.149" + "@justaname.id/sdk": "npm:0.2.146" + "@justweb3/ui": "npm:^0.0.85" clsx: "npm:1.2.1" cropperjs: "npm:^1.6.2" lodash: "npm:4.17.21" @@ -4804,7 +4646,6 @@ __metadata: react: ">=17" viem: 2.x wagmi: 2.x - checksum: 10c0/undefined languageName: unknown linkType: soft @@ -4812,12 +4653,21 @@ __metadata: version: 0.0.0-use.local resolution: "@justweb3/xmtp-plugin@workspace:packages/@justweb3/xmtp-plugin" dependencies: + "@radix-ui/react-slider": "npm:^1.2.1" + "@xmtp/content-type-primitives": "npm:1.0.3" + "@xmtp/content-type-reaction": "npm:^1.1.11" + "@xmtp/content-type-remote-attachment": "npm:^1.1.12" + "@xmtp/content-type-reply": "npm:^1.1.12" + "@xmtp/content-type-text": "npm:1.0.1" "@xmtp/react-sdk": "npm:^9.0.0" + "@xmtp/xmtp-js": "npm:^13.0.4" + react-media-recorder-2: "npm:^1.6.23" + react-timer-hook: "npm:^3.0.8" peerDependencies: "@justweb3/widget": ">=0.0.0" + "@tanstack/react-query": ^5.x react: ">=17" wagmi: 2.x - checksum: 10c0/undefined languageName: unknown linkType: soft @@ -5485,7 +5335,6 @@ __metadata: "@napi-rs/nice-android-arm-eabi@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-android-arm-eabi@npm:1.0.1" - checksum: 10c0/undefined conditions: os=android & cpu=arm languageName: node linkType: hard @@ -5493,7 +5342,6 @@ __metadata: "@napi-rs/nice-android-arm64@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-android-arm64@npm:1.0.1" - checksum: 10c0/undefined conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -5501,7 +5349,6 @@ __metadata: "@napi-rs/nice-darwin-arm64@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-darwin-arm64@npm:1.0.1" - checksum: 10c0/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -5509,7 +5356,6 @@ __metadata: "@napi-rs/nice-darwin-x64@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-darwin-x64@npm:1.0.1" - checksum: 10c0/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -5517,7 +5363,6 @@ __metadata: "@napi-rs/nice-freebsd-x64@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-freebsd-x64@npm:1.0.1" - checksum: 10c0/undefined conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -5525,7 +5370,6 @@ __metadata: "@napi-rs/nice-linux-arm-gnueabihf@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-linux-arm-gnueabihf@npm:1.0.1" - checksum: 10c0/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -5533,7 +5377,6 @@ __metadata: "@napi-rs/nice-linux-arm64-gnu@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-linux-arm64-gnu@npm:1.0.1" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -5541,7 +5384,6 @@ __metadata: "@napi-rs/nice-linux-arm64-musl@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-linux-arm64-musl@npm:1.0.1" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -5549,7 +5391,6 @@ __metadata: "@napi-rs/nice-linux-ppc64-gnu@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-linux-ppc64-gnu@npm:1.0.1" - checksum: 10c0/undefined conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard @@ -5557,7 +5398,6 @@ __metadata: "@napi-rs/nice-linux-riscv64-gnu@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-linux-riscv64-gnu@npm:1.0.1" - checksum: 10c0/undefined conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard @@ -5565,7 +5405,6 @@ __metadata: "@napi-rs/nice-linux-s390x-gnu@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-linux-s390x-gnu@npm:1.0.1" - checksum: 10c0/undefined conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard @@ -5573,7 +5412,6 @@ __metadata: "@napi-rs/nice-linux-x64-gnu@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-linux-x64-gnu@npm:1.0.1" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -5581,7 +5419,6 @@ __metadata: "@napi-rs/nice-linux-x64-musl@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-linux-x64-musl@npm:1.0.1" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -5589,7 +5426,6 @@ __metadata: "@napi-rs/nice-win32-arm64-msvc@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-win32-arm64-msvc@npm:1.0.1" - checksum: 10c0/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -5597,7 +5433,6 @@ __metadata: "@napi-rs/nice-win32-ia32-msvc@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-win32-ia32-msvc@npm:1.0.1" - checksum: 10c0/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -5605,7 +5440,6 @@ __metadata: "@napi-rs/nice-win32-x64-msvc@npm:1.0.1": version: 1.0.1 resolution: "@napi-rs/nice-win32-x64-msvc@npm:1.0.1" - checksum: 10c0/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -5697,7 +5531,6 @@ __metadata: "@next/swc-darwin-arm64@npm:14.2.3": version: 14.2.3 resolution: "@next/swc-darwin-arm64@npm:14.2.3" - checksum: 10c0/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -5705,7 +5538,6 @@ __metadata: "@next/swc-darwin-x64@npm:14.2.3": version: 14.2.3 resolution: "@next/swc-darwin-x64@npm:14.2.3" - checksum: 10c0/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -5713,7 +5545,6 @@ __metadata: "@next/swc-linux-arm64-gnu@npm:14.2.3": version: 14.2.3 resolution: "@next/swc-linux-arm64-gnu@npm:14.2.3" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -5721,7 +5552,6 @@ __metadata: "@next/swc-linux-arm64-musl@npm:14.2.3": version: 14.2.3 resolution: "@next/swc-linux-arm64-musl@npm:14.2.3" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -5729,7 +5559,6 @@ __metadata: "@next/swc-linux-x64-gnu@npm:14.2.3": version: 14.2.3 resolution: "@next/swc-linux-x64-gnu@npm:14.2.3" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -5737,7 +5566,6 @@ __metadata: "@next/swc-linux-x64-musl@npm:14.2.3": version: 14.2.3 resolution: "@next/swc-linux-x64-musl@npm:14.2.3" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -5745,7 +5573,6 @@ __metadata: "@next/swc-win32-arm64-msvc@npm:14.2.3": version: 14.2.3 resolution: "@next/swc-win32-arm64-msvc@npm:14.2.3" - checksum: 10c0/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -5753,7 +5580,6 @@ __metadata: "@next/swc-win32-ia32-msvc@npm:14.2.3": version: 14.2.3 resolution: "@next/swc-win32-ia32-msvc@npm:14.2.3" - checksum: 10c0/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -5761,7 +5587,6 @@ __metadata: "@next/swc-win32-x64-msvc@npm:14.2.3": version: 14.2.3 resolution: "@next/swc-win32-x64-msvc@npm:14.2.3" - checksum: 10c0/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -6574,7 +6399,6 @@ __metadata: "@nx/nx-darwin-arm64@npm:19.7.3": version: 19.7.3 resolution: "@nx/nx-darwin-arm64@npm:19.7.3" - checksum: 10c0/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -6582,7 +6406,6 @@ __metadata: "@nx/nx-darwin-x64@npm:19.7.3": version: 19.7.3 resolution: "@nx/nx-darwin-x64@npm:19.7.3" - checksum: 10c0/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -6590,7 +6413,6 @@ __metadata: "@nx/nx-freebsd-x64@npm:19.7.3": version: 19.7.3 resolution: "@nx/nx-freebsd-x64@npm:19.7.3" - checksum: 10c0/undefined conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -6598,7 +6420,6 @@ __metadata: "@nx/nx-linux-arm-gnueabihf@npm:19.7.3": version: 19.7.3 resolution: "@nx/nx-linux-arm-gnueabihf@npm:19.7.3" - checksum: 10c0/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -6606,7 +6427,6 @@ __metadata: "@nx/nx-linux-arm64-gnu@npm:19.7.3": version: 19.7.3 resolution: "@nx/nx-linux-arm64-gnu@npm:19.7.3" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -6614,7 +6434,6 @@ __metadata: "@nx/nx-linux-arm64-musl@npm:19.7.3": version: 19.7.3 resolution: "@nx/nx-linux-arm64-musl@npm:19.7.3" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -6622,7 +6441,6 @@ __metadata: "@nx/nx-linux-x64-gnu@npm:19.7.3": version: 19.7.3 resolution: "@nx/nx-linux-x64-gnu@npm:19.7.3" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -6630,7 +6448,6 @@ __metadata: "@nx/nx-linux-x64-musl@npm:19.7.3": version: 19.7.3 resolution: "@nx/nx-linux-x64-musl@npm:19.7.3" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -6638,7 +6455,6 @@ __metadata: "@nx/nx-win32-arm64-msvc@npm:19.7.3": version: 19.7.3 resolution: "@nx/nx-win32-arm64-msvc@npm:19.7.3" - checksum: 10c0/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -6646,7 +6462,6 @@ __metadata: "@nx/nx-win32-x64-msvc@npm:19.7.3": version: 19.7.3 resolution: "@nx/nx-win32-x64-msvc@npm:19.7.3" - checksum: 10c0/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -6832,7 +6647,6 @@ __metadata: "@parcel/watcher-android-arm64@npm:2.4.1": version: 2.4.1 resolution: "@parcel/watcher-android-arm64@npm:2.4.1" - checksum: 10c0/undefined conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -6840,7 +6654,6 @@ __metadata: "@parcel/watcher-darwin-arm64@npm:2.4.1": version: 2.4.1 resolution: "@parcel/watcher-darwin-arm64@npm:2.4.1" - checksum: 10c0/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -6848,7 +6661,6 @@ __metadata: "@parcel/watcher-darwin-x64@npm:2.4.1": version: 2.4.1 resolution: "@parcel/watcher-darwin-x64@npm:2.4.1" - checksum: 10c0/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -6856,7 +6668,6 @@ __metadata: "@parcel/watcher-freebsd-x64@npm:2.4.1": version: 2.4.1 resolution: "@parcel/watcher-freebsd-x64@npm:2.4.1" - checksum: 10c0/undefined conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -6864,7 +6675,6 @@ __metadata: "@parcel/watcher-linux-arm-glibc@npm:2.4.1": version: 2.4.1 resolution: "@parcel/watcher-linux-arm-glibc@npm:2.4.1" - checksum: 10c0/undefined conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard @@ -6872,7 +6682,6 @@ __metadata: "@parcel/watcher-linux-arm64-glibc@npm:2.4.1": version: 2.4.1 resolution: "@parcel/watcher-linux-arm64-glibc@npm:2.4.1" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -6880,7 +6689,6 @@ __metadata: "@parcel/watcher-linux-arm64-musl@npm:2.4.1": version: 2.4.1 resolution: "@parcel/watcher-linux-arm64-musl@npm:2.4.1" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -6888,7 +6696,6 @@ __metadata: "@parcel/watcher-linux-x64-glibc@npm:2.4.1": version: 2.4.1 resolution: "@parcel/watcher-linux-x64-glibc@npm:2.4.1" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -6896,7 +6703,6 @@ __metadata: "@parcel/watcher-linux-x64-musl@npm:2.4.1": version: 2.4.1 resolution: "@parcel/watcher-linux-x64-musl@npm:2.4.1" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -6915,7 +6721,6 @@ __metadata: "@parcel/watcher-win32-arm64@npm:2.4.1": version: 2.4.1 resolution: "@parcel/watcher-win32-arm64@npm:2.4.1" - checksum: 10c0/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -6923,7 +6728,6 @@ __metadata: "@parcel/watcher-win32-ia32@npm:2.4.1": version: 2.4.1 resolution: "@parcel/watcher-win32-ia32@npm:2.4.1" - checksum: 10c0/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -6931,7 +6735,6 @@ __metadata: "@parcel/watcher-win32-x64@npm:2.4.1": version: 2.4.1 resolution: "@parcel/watcher-win32-x64@npm:2.4.1" - checksum: 10c0/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -8769,7 +8572,6 @@ __metadata: "@rollup/rollup-android-arm-eabi@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-android-arm-eabi@npm:4.24.3" - checksum: 10c0/undefined conditions: os=android & cpu=arm languageName: node linkType: hard @@ -8777,7 +8579,6 @@ __metadata: "@rollup/rollup-android-arm64@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-android-arm64@npm:4.24.3" - checksum: 10c0/undefined conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -8785,7 +8586,6 @@ __metadata: "@rollup/rollup-darwin-arm64@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-darwin-arm64@npm:4.24.3" - checksum: 10c0/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -8793,7 +8593,6 @@ __metadata: "@rollup/rollup-darwin-x64@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-darwin-x64@npm:4.24.3" - checksum: 10c0/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -8801,7 +8600,6 @@ __metadata: "@rollup/rollup-freebsd-arm64@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-freebsd-arm64@npm:4.24.3" - checksum: 10c0/undefined conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -8809,7 +8607,6 @@ __metadata: "@rollup/rollup-freebsd-x64@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-freebsd-x64@npm:4.24.3" - checksum: 10c0/undefined conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -8817,7 +8614,6 @@ __metadata: "@rollup/rollup-linux-arm-gnueabihf@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.24.3" - checksum: 10c0/undefined conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard @@ -8825,7 +8621,6 @@ __metadata: "@rollup/rollup-linux-arm-musleabihf@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.24.3" - checksum: 10c0/undefined conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard @@ -8833,7 +8628,6 @@ __metadata: "@rollup/rollup-linux-arm64-gnu@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.24.3" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -8841,7 +8635,6 @@ __metadata: "@rollup/rollup-linux-arm64-musl@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-linux-arm64-musl@npm:4.24.3" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -8849,7 +8642,6 @@ __metadata: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.24.3" - checksum: 10c0/undefined conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard @@ -8857,7 +8649,6 @@ __metadata: "@rollup/rollup-linux-riscv64-gnu@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.24.3" - checksum: 10c0/undefined conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard @@ -8865,7 +8656,6 @@ __metadata: "@rollup/rollup-linux-s390x-gnu@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.24.3" - checksum: 10c0/undefined conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard @@ -8873,7 +8663,6 @@ __metadata: "@rollup/rollup-linux-x64-gnu@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-linux-x64-gnu@npm:4.24.3" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -8881,7 +8670,6 @@ __metadata: "@rollup/rollup-linux-x64-musl@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-linux-x64-musl@npm:4.24.3" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -8889,7 +8677,6 @@ __metadata: "@rollup/rollup-win32-arm64-msvc@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.24.3" - checksum: 10c0/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -8897,7 +8684,6 @@ __metadata: "@rollup/rollup-win32-ia32-msvc@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.24.3" - checksum: 10c0/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -8905,7 +8691,6 @@ __metadata: "@rollup/rollup-win32-x64-msvc@npm:4.24.3": version: 4.24.3 resolution: "@rollup/rollup-win32-x64-msvc@npm:4.24.3" - checksum: 10c0/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -10911,7 +10696,6 @@ __metadata: "@swc/core-darwin-arm64@npm:1.5.29": version: 1.5.29 resolution: "@swc/core-darwin-arm64@npm:1.5.29" - checksum: 10c0/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -10919,7 +10703,6 @@ __metadata: "@swc/core-darwin-arm64@npm:1.7.42": version: 1.7.42 resolution: "@swc/core-darwin-arm64@npm:1.7.42" - checksum: 10c0/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -10927,7 +10710,6 @@ __metadata: "@swc/core-darwin-x64@npm:1.5.29": version: 1.5.29 resolution: "@swc/core-darwin-x64@npm:1.5.29" - checksum: 10c0/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -10935,7 +10717,6 @@ __metadata: "@swc/core-darwin-x64@npm:1.7.42": version: 1.7.42 resolution: "@swc/core-darwin-x64@npm:1.7.42" - checksum: 10c0/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -10943,7 +10724,6 @@ __metadata: "@swc/core-linux-arm-gnueabihf@npm:1.5.29": version: 1.5.29 resolution: "@swc/core-linux-arm-gnueabihf@npm:1.5.29" - checksum: 10c0/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -10951,7 +10731,6 @@ __metadata: "@swc/core-linux-arm-gnueabihf@npm:1.7.42": version: 1.7.42 resolution: "@swc/core-linux-arm-gnueabihf@npm:1.7.42" - checksum: 10c0/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -10959,7 +10738,6 @@ __metadata: "@swc/core-linux-arm64-gnu@npm:1.5.29": version: 1.5.29 resolution: "@swc/core-linux-arm64-gnu@npm:1.5.29" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -10967,7 +10745,6 @@ __metadata: "@swc/core-linux-arm64-gnu@npm:1.7.42": version: 1.7.42 resolution: "@swc/core-linux-arm64-gnu@npm:1.7.42" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -10975,7 +10752,6 @@ __metadata: "@swc/core-linux-arm64-musl@npm:1.5.29": version: 1.5.29 resolution: "@swc/core-linux-arm64-musl@npm:1.5.29" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -10983,7 +10759,6 @@ __metadata: "@swc/core-linux-arm64-musl@npm:1.7.42": version: 1.7.42 resolution: "@swc/core-linux-arm64-musl@npm:1.7.42" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -10991,7 +10766,6 @@ __metadata: "@swc/core-linux-x64-gnu@npm:1.5.29": version: 1.5.29 resolution: "@swc/core-linux-x64-gnu@npm:1.5.29" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -10999,7 +10773,6 @@ __metadata: "@swc/core-linux-x64-gnu@npm:1.7.42": version: 1.7.42 resolution: "@swc/core-linux-x64-gnu@npm:1.7.42" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -11007,7 +10780,6 @@ __metadata: "@swc/core-linux-x64-musl@npm:1.5.29": version: 1.5.29 resolution: "@swc/core-linux-x64-musl@npm:1.5.29" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -11015,7 +10787,6 @@ __metadata: "@swc/core-linux-x64-musl@npm:1.7.42": version: 1.7.42 resolution: "@swc/core-linux-x64-musl@npm:1.7.42" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -11023,7 +10794,6 @@ __metadata: "@swc/core-win32-arm64-msvc@npm:1.5.29": version: 1.5.29 resolution: "@swc/core-win32-arm64-msvc@npm:1.5.29" - checksum: 10c0/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -11031,7 +10801,6 @@ __metadata: "@swc/core-win32-arm64-msvc@npm:1.7.42": version: 1.7.42 resolution: "@swc/core-win32-arm64-msvc@npm:1.7.42" - checksum: 10c0/undefined conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -11039,7 +10808,6 @@ __metadata: "@swc/core-win32-ia32-msvc@npm:1.5.29": version: 1.5.29 resolution: "@swc/core-win32-ia32-msvc@npm:1.5.29" - checksum: 10c0/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -11047,7 +10815,6 @@ __metadata: "@swc/core-win32-ia32-msvc@npm:1.7.42": version: 1.7.42 resolution: "@swc/core-win32-ia32-msvc@npm:1.7.42" - checksum: 10c0/undefined conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -11055,7 +10822,6 @@ __metadata: "@swc/core-win32-x64-msvc@npm:1.5.29": version: 1.5.29 resolution: "@swc/core-win32-x64-msvc@npm:1.5.29" - checksum: 10c0/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -11063,7 +10829,6 @@ __metadata: "@swc/core-win32-x64-msvc@npm:1.7.42": version: 1.7.42 resolution: "@swc/core-win32-x64-msvc@npm:1.7.42" - checksum: 10c0/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -14494,15 +14259,6 @@ __metadata: languageName: node linkType: hard -"@xmtp/content-type-primitives@npm:^1.0.1, @xmtp/content-type-primitives@npm:^1.0.3": - version: 1.0.3 - resolution: "@xmtp/content-type-primitives@npm:1.0.3" - dependencies: - "@xmtp/proto": "npm:^3.72.0" - checksum: 10c0/a644dd24d0edad2c67b4b7a42f5af32914fb2df935debaabde61dba9d0c061692b198757777323c266a1ce84a1a3050d98bde21f795035a18ae076fee9528a0e - languageName: node - linkType: hard - "@xmtp/content-type-reaction@npm:^1.1.11": version: 1.1.11 resolution: "@xmtp/content-type-reaction@npm:1.1.11" @@ -14551,15 +14307,6 @@ __metadata: languageName: node linkType: hard -"@xmtp/content-type-text@npm:^1.0.0, @xmtp/content-type-text@npm:^1.0.1": - version: 1.0.1 - resolution: "@xmtp/content-type-text@npm:1.0.1" - dependencies: - "@xmtp/content-type-primitives": "npm:^1.0.3" - checksum: 10c0/d981039d21ce437b3ae7eaa2e2c2779788c823354b59f261d9bf0582862d9b44872c20ae4964587a502adcc2fca99162e60adf55460992dacdc795513e035465 - languageName: node - linkType: hard - "@xmtp/proto@npm:^3.72.0": version: 3.72.3 resolution: "@xmtp/proto@npm:3.72.3" @@ -22608,7 +22355,6 @@ __metadata: resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" dependencies: node-gyp: "npm:latest" - checksum: 10c0/undefined conditions: os=darwin languageName: node linkType: hard @@ -22618,7 +22364,6 @@ __metadata: resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" dependencies: node-gyp: "npm:latest" - checksum: 10c0/undefined conditions: os=darwin languageName: node linkType: hard @@ -26932,7 +26677,7 @@ __metadata: "@chromatic-com/storybook": "npm:^1" "@docusaurus/eslint-plugin": "npm:^3.5.2" "@ensdomains/address-encoder": "npm:^1.1.2" - "@ensdomains/ensjs": "npm:4.0.1-alpha.0" + "@ensdomains/ensjs": "npm:4.0.2" "@hookform/error-message": "npm:^2.0.1" "@hookform/resolvers": "npm:^3.9.0" "@inquirer/prompts": "npm:^4.3.0" @@ -27132,7 +26877,6 @@ __metadata: vitest: "npm:1.3.1" wagmi: "npm:^2.5.7" webpack-cli: "npm:^5.1.4" - checksum: 10c0/undefined languageName: unknown linkType: soft @@ -27568,7 +27312,6 @@ __metadata: "lightningcss-darwin-arm64@npm:1.19.0": version: 1.19.0 resolution: "lightningcss-darwin-arm64@npm:1.19.0" - checksum: 10c0/undefined conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -27576,7 +27319,6 @@ __metadata: "lightningcss-darwin-x64@npm:1.19.0": version: 1.19.0 resolution: "lightningcss-darwin-x64@npm:1.19.0" - checksum: 10c0/undefined conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -27584,7 +27326,6 @@ __metadata: "lightningcss-linux-arm-gnueabihf@npm:1.19.0": version: 1.19.0 resolution: "lightningcss-linux-arm-gnueabihf@npm:1.19.0" - checksum: 10c0/undefined conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -27592,7 +27333,6 @@ __metadata: "lightningcss-linux-arm64-gnu@npm:1.19.0": version: 1.19.0 resolution: "lightningcss-linux-arm64-gnu@npm:1.19.0" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -27600,7 +27340,6 @@ __metadata: "lightningcss-linux-arm64-musl@npm:1.19.0": version: 1.19.0 resolution: "lightningcss-linux-arm64-musl@npm:1.19.0" - checksum: 10c0/undefined conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -27608,7 +27347,6 @@ __metadata: "lightningcss-linux-x64-gnu@npm:1.19.0": version: 1.19.0 resolution: "lightningcss-linux-x64-gnu@npm:1.19.0" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -27616,7 +27354,6 @@ __metadata: "lightningcss-linux-x64-musl@npm:1.19.0": version: 1.19.0 resolution: "lightningcss-linux-x64-musl@npm:1.19.0" - checksum: 10c0/undefined conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -27624,7 +27361,6 @@ __metadata: "lightningcss-win32-x64-msvc@npm:1.19.0": version: 1.19.0 resolution: "lightningcss-win32-x64-msvc@npm:1.19.0" - checksum: 10c0/undefined conditions: os=win32 & cpu=x64 languageName: node linkType: hard From 3df90a76b6c03dd819c5e51405cda3133a7fe112 Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Tue, 3 Dec 2024 17:45:35 +0200 Subject: [PATCH 18/29] feat: sign in optional --- package.json | 1 + .../react/src/lib/helpers/ethersCompat.ts | 49 +++++++----- .../src/lib/helpers/isParseable/index.ts | 8 ++ .../lib/hooks/primaryName/usePrimaryName.ts | 1 - .../react/src/lib/hooks/signIn/useEnsAuth.ts | 14 +++- .../src/lib/hooks/signIn/useEnsSignIn.ts | 18 +++++ .../src/lib/hooks/signIn/useEnsSignOut.ts | 9 +++ .../sdk/src/lib/utils/ethersCompat.ts | 49 +++++++----- .../siwens/src/lib/utils/ethersCompat.ts | 49 +++++++----- .../lib/components/ClickableItem/index.tsx | 7 +- .../@justweb3/widget/.storybook/preview.ts | 0 .../src/lib/components/JustEnsCard/index.tsx | 15 +++- .../Profile/ContentSection/index.tsx | 10 ++- .../src/lib/dialogs/SignInDialog/index.tsx | 6 +- .../lib/providers/JustWeb3Provider/index.tsx | 44 +++++++++-- .../src/lib/providers/MAppProvider/index.tsx | 13 ++- .../lib/providers/PluginProvider/index.tsx | 4 +- .../widget/src/lib/types/config/index.ts | 1 + .../xmtp-plugin/.storybook/preview.tsx | 9 +++ .../xmtp-plugin/src/stories/xmtp.stories.tsx | 79 ++++++++++--------- yarn.lock | 63 ++++++++++++++- 21 files changed, 330 insertions(+), 119 deletions(-) create mode 100644 packages/@justaname.id/react/src/lib/helpers/isParseable/index.ts delete mode 100644 packages/@justweb3/widget/.storybook/preview.ts diff --git a/package.json b/package.json index d3e05ddc..c04d4d28 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,7 @@ "react-native-url-polyfill": "^2.0.0", "react-native-web": "~0.19.9", "react-router-dom": "6.11.2", + "react-scan": "^0.0.35", "react-split": "^2.0.14", "react-timer-hook": "^3.0.8", "react-tiny-popover": "^8.0.4", diff --git a/packages/@justaname.id/react/src/lib/helpers/ethersCompat.ts b/packages/@justaname.id/react/src/lib/helpers/ethersCompat.ts index dcc041b5..682e9f25 100644 --- a/packages/@justaname.id/react/src/lib/helpers/ethersCompat.ts +++ b/packages/@justaname.id/react/src/lib/helpers/ethersCompat.ts @@ -1,6 +1,7 @@ // inspired by spruceid siwe: https://github.com/spruceid/siwe/blob/main/packages/siwe/lib/ethersCompat.ts import { ethers } from 'ethers'; + // @ts-expect-error -- compatibility hack type ProviderV5 = ethers.providers.Provider; type ProviderV6 = ethers.Provider; @@ -13,30 +14,38 @@ export type JsonRpcProvider = JsonRpcProviderV6 extends undefined ? JsonRpcProviderV5 : JsonRpcProviderV6; +interface EthersCompat { + namehash?: (name: string) => string; + getAddress?: (address: string) => string; + JsonRpcProvider?: new (...args: any[]) => JsonRpcProvider; + utils: { + namehash: (name: string) => string; + getAddress: (address: string) => string; + }; + providers: { + JsonRpcProvider: new (...args: any[]) => JsonRpcProvider; + }; +} + +const ethersCompat = ethers as unknown as EthersCompat; + export const getJsonRpcProvider = ( - providerUrl?: string | undefined, + providerUrl?: string, chainId?: number ): JsonRpcProvider => { - try { - return new ethers.JsonRpcProvider(providerUrl, chainId); - } catch { - // @ts-expect-error -- compatibility hack - return new ethers.providers.JsonRpcProvider(providerUrl, chainId); + if ('JsonRpcProvider' in ethersCompat) { + return new ethersCompat.JsonRpcProvider!(providerUrl, chainId); + } else { + return new ethersCompat.providers.JsonRpcProvider(providerUrl, chainId); } }; -let ethersNamehash = null; -let ethersGetAddress = null; - -try { - // @ts-expect-error -- compatibility hack - ethersNamehash = ethers.utils.namehash; - // @ts-expect-error -- compatibility hack - ethersGetAddress = ethers.utils.getAddress; -} catch { - ethersNamehash = ethers.namehash as (message: Uint8Array | string) => string; +export const namehash: (name: string) => string = + 'namehash' in ethersCompat + ? ethersCompat.namehash! + : ethersCompat.utils.namehash; - ethersGetAddress = ethers.getAddress as (address: string) => string; -} -export const namehash = ethersNamehash as (name: string) => string; -export const getAddress = ethersGetAddress as (address: string) => string; +export const getAddress: (address: string) => string = + 'getAddress' in ethersCompat + ? ethersCompat.getAddress! + : ethersCompat.utils.getAddress; diff --git a/packages/@justaname.id/react/src/lib/helpers/isParseable/index.ts b/packages/@justaname.id/react/src/lib/helpers/isParseable/index.ts new file mode 100644 index 00000000..a6d87b9a --- /dev/null +++ b/packages/@justaname.id/react/src/lib/helpers/isParseable/index.ts @@ -0,0 +1,8 @@ +export const isParseable = (value: any): boolean => { + try { + JSON.parse(value); + return true; + } catch (e) { + return false; + } +}; diff --git a/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts b/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts index aff748e2..c901ae1d 100644 --- a/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts +++ b/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts @@ -107,7 +107,6 @@ export const usePrimaryName = ( const query = useQuery({ ...defaultOptions, retry: (_count, error) => { - console.log('Error fetching primary name', error, _count); if (error?.message.includes('PrimaryNameNotFound')) { return false; } diff --git a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsAuth.ts b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsAuth.ts index 989783ad..9a052b3a 100644 --- a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsAuth.ts +++ b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsAuth.ts @@ -4,6 +4,7 @@ import { useJustaName } from '../../providers'; import { ChainId } from '@justaname.id/sdk'; import { defaultOptions } from '../../query'; import axios from 'axios'; +import { isParseable } from '../../helpers/isParseable'; export const buildEnsAuthKey = (backendUrl: string) => ['ENS_AUTH', backendUrl]; @@ -17,6 +18,7 @@ export interface UseEnsAuthParams { backendUrl?: string; currentEnsRoute?: string; enabled?: boolean; + local?: boolean; } export interface UseEnsAuthReturn { @@ -51,11 +53,21 @@ export const useEnsAuth = ( queryKey: buildEnsAuthKey(_backendUrl), queryFn: async () => { try { + if (params?.local) { + const response = localStorage.getItem('ENS_AUTH') || ''; + if (isParseable(response)) { + return JSON.parse(response); + } else { + localStorage.removeItem('ENS_AUTH'); + } + return null; + } + const response = await axios.get(currentEnsEndpoint, { headers: { 'Content-Type': 'application/json', }, - withCredentials: true, // Similar to 'credentials: include' in fetch + withCredentials: true, }); return response.data; diff --git a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignIn.ts b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignIn.ts index 9184d4df..906b7f51 100644 --- a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignIn.ts +++ b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignIn.ts @@ -20,6 +20,7 @@ export interface UseEnsSignInParams signinNonceRoute?: string; signinRoute?: string; currentEnsRoute?: string; + local?: boolean; } export interface UseEnsSignInResult { @@ -59,12 +60,14 @@ export const useEnsSignIn = ( const { refreshEnsAuth } = useEnsAuth({ backendUrl: _backendUrl, currentEnsRoute: _currentEnsRoute, + local: params?.local, }); const { nonce, refetchNonce } = useEnsNonce({ backendUrl: params?.backendUrl, signinNonceRoute: params?.signinNonceRoute, address, + enabled: !params?.local, }); const mutation = useMutation({ @@ -73,6 +76,21 @@ export const useEnsSignIn = ( throw new Error('No address found'); } + if (params?.local) { + localStorage.setItem( + 'ENS_AUTH', + JSON.stringify({ + ens: _params.ens, + chainId, + address, + }) + ); + + refreshEnsAuth(); + + return 'success'; + } + if (!nonce) { throw new Error('No nonce found'); } diff --git a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignOut.ts b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignOut.ts index 085fbf29..29a43c19 100644 --- a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignOut.ts +++ b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignOut.ts @@ -16,6 +16,7 @@ export interface UseEnsSignOutParams { signoutRoute?: string; currentEnsRoute?: string; signinNonceRoute?: string; + local?: boolean; } export const useEnsSignOut = ( @@ -46,16 +47,24 @@ export const useEnsSignOut = ( const { refreshEnsAuth, connectedEns } = useEnsAuth({ backendUrl: _backendUrl, currentEnsRoute: _currentEnsRoute, + local: params?.local, }); const { refetchNonce } = useEnsNonce({ backendUrl: _backendUrl, signinNonceRoute: _signinNonceRoute, address: connectedEns?.address, + enabled: !params?.local, }); const mutation = useMutation({ mutationFn: async () => { + if (params?.local) { + localStorage.removeItem('ENS_AUTH'); + refreshEnsAuth(); + return; + } + await fetch(signoutEndpoint, { method: 'POST', credentials: 'include', diff --git a/packages/@justaname.id/sdk/src/lib/utils/ethersCompat.ts b/packages/@justaname.id/sdk/src/lib/utils/ethersCompat.ts index dcc041b5..682e9f25 100644 --- a/packages/@justaname.id/sdk/src/lib/utils/ethersCompat.ts +++ b/packages/@justaname.id/sdk/src/lib/utils/ethersCompat.ts @@ -1,6 +1,7 @@ // inspired by spruceid siwe: https://github.com/spruceid/siwe/blob/main/packages/siwe/lib/ethersCompat.ts import { ethers } from 'ethers'; + // @ts-expect-error -- compatibility hack type ProviderV5 = ethers.providers.Provider; type ProviderV6 = ethers.Provider; @@ -13,30 +14,38 @@ export type JsonRpcProvider = JsonRpcProviderV6 extends undefined ? JsonRpcProviderV5 : JsonRpcProviderV6; +interface EthersCompat { + namehash?: (name: string) => string; + getAddress?: (address: string) => string; + JsonRpcProvider?: new (...args: any[]) => JsonRpcProvider; + utils: { + namehash: (name: string) => string; + getAddress: (address: string) => string; + }; + providers: { + JsonRpcProvider: new (...args: any[]) => JsonRpcProvider; + }; +} + +const ethersCompat = ethers as unknown as EthersCompat; + export const getJsonRpcProvider = ( - providerUrl?: string | undefined, + providerUrl?: string, chainId?: number ): JsonRpcProvider => { - try { - return new ethers.JsonRpcProvider(providerUrl, chainId); - } catch { - // @ts-expect-error -- compatibility hack - return new ethers.providers.JsonRpcProvider(providerUrl, chainId); + if ('JsonRpcProvider' in ethersCompat) { + return new ethersCompat.JsonRpcProvider!(providerUrl, chainId); + } else { + return new ethersCompat.providers.JsonRpcProvider(providerUrl, chainId); } }; -let ethersNamehash = null; -let ethersGetAddress = null; - -try { - // @ts-expect-error -- compatibility hack - ethersNamehash = ethers.utils.namehash; - // @ts-expect-error -- compatibility hack - ethersGetAddress = ethers.utils.getAddress; -} catch { - ethersNamehash = ethers.namehash as (message: Uint8Array | string) => string; +export const namehash: (name: string) => string = + 'namehash' in ethersCompat + ? ethersCompat.namehash! + : ethersCompat.utils.namehash; - ethersGetAddress = ethers.getAddress as (address: string) => string; -} -export const namehash = ethersNamehash as (name: string) => string; -export const getAddress = ethersGetAddress as (address: string) => string; +export const getAddress: (address: string) => string = + 'getAddress' in ethersCompat + ? ethersCompat.getAddress! + : ethersCompat.utils.getAddress; diff --git a/packages/@justaname.id/siwens/src/lib/utils/ethersCompat.ts b/packages/@justaname.id/siwens/src/lib/utils/ethersCompat.ts index dcc041b5..682e9f25 100644 --- a/packages/@justaname.id/siwens/src/lib/utils/ethersCompat.ts +++ b/packages/@justaname.id/siwens/src/lib/utils/ethersCompat.ts @@ -1,6 +1,7 @@ // inspired by spruceid siwe: https://github.com/spruceid/siwe/blob/main/packages/siwe/lib/ethersCompat.ts import { ethers } from 'ethers'; + // @ts-expect-error -- compatibility hack type ProviderV5 = ethers.providers.Provider; type ProviderV6 = ethers.Provider; @@ -13,30 +14,38 @@ export type JsonRpcProvider = JsonRpcProviderV6 extends undefined ? JsonRpcProviderV5 : JsonRpcProviderV6; +interface EthersCompat { + namehash?: (name: string) => string; + getAddress?: (address: string) => string; + JsonRpcProvider?: new (...args: any[]) => JsonRpcProvider; + utils: { + namehash: (name: string) => string; + getAddress: (address: string) => string; + }; + providers: { + JsonRpcProvider: new (...args: any[]) => JsonRpcProvider; + }; +} + +const ethersCompat = ethers as unknown as EthersCompat; + export const getJsonRpcProvider = ( - providerUrl?: string | undefined, + providerUrl?: string, chainId?: number ): JsonRpcProvider => { - try { - return new ethers.JsonRpcProvider(providerUrl, chainId); - } catch { - // @ts-expect-error -- compatibility hack - return new ethers.providers.JsonRpcProvider(providerUrl, chainId); + if ('JsonRpcProvider' in ethersCompat) { + return new ethersCompat.JsonRpcProvider!(providerUrl, chainId); + } else { + return new ethersCompat.providers.JsonRpcProvider(providerUrl, chainId); } }; -let ethersNamehash = null; -let ethersGetAddress = null; - -try { - // @ts-expect-error -- compatibility hack - ethersNamehash = ethers.utils.namehash; - // @ts-expect-error -- compatibility hack - ethersGetAddress = ethers.utils.getAddress; -} catch { - ethersNamehash = ethers.namehash as (message: Uint8Array | string) => string; +export const namehash: (name: string) => string = + 'namehash' in ethersCompat + ? ethersCompat.namehash! + : ethersCompat.utils.namehash; - ethersGetAddress = ethers.getAddress as (address: string) => string; -} -export const namehash = ethersNamehash as (name: string) => string; -export const getAddress = ethersGetAddress as (address: string) => string; +export const getAddress: (address: string) => string = + 'getAddress' in ethersCompat + ? ethersCompat.getAddress! + : ethersCompat.utils.getAddress; diff --git a/packages/@justweb3/ui/src/lib/components/ClickableItem/index.tsx b/packages/@justweb3/ui/src/lib/components/ClickableItem/index.tsx index 827ba83e..15ace89b 100644 --- a/packages/@justweb3/ui/src/lib/components/ClickableItem/index.tsx +++ b/packages/@justweb3/ui/src/lib/components/ClickableItem/index.tsx @@ -8,7 +8,7 @@ interface ClickableListItemProps { subtitle?: string | React.ReactNode; left?: React.ReactNode; loading?: boolean; - onClick?: () => void; + onClick?: (e: React.MouseEvent) => void; disabled?: boolean; right?: React.ReactNode; onHover?: (hover: boolean) => void; @@ -54,9 +54,10 @@ export const ClickableItem = React.forwardRef< className={clsx(wrapperClassNames, className)} onClick={(e) => { if (!loading && !disabled && clickable) { - onClick && onClick(); + onClick && onClick(e); } - e.stopPropagation(); + // e.stopPropagation(); + // e.preventDefault(); }} onPointerEnter={() => { if (!loading && !disabled && clickable) { diff --git a/packages/@justweb3/widget/.storybook/preview.ts b/packages/@justweb3/widget/.storybook/preview.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/@justweb3/widget/src/lib/components/JustEnsCard/index.tsx b/packages/@justweb3/widget/src/lib/components/JustEnsCard/index.tsx index 64e94c4e..515471f2 100644 --- a/packages/@justweb3/widget/src/lib/components/JustEnsCard/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/JustEnsCard/index.tsx @@ -111,8 +111,13 @@ export const JustEnsCard: FC = ({ return (
handleEnsClick()} + ref={ref} + className={styles.expandableCard} + onClick={(e) => { + e.stopPropagation(); + e.preventDefault(); + handleEnsClick(); + }} > = ({ ) } disabled={!isEns && !primaryName} - onClick={() => handleEnsClick()} + onClick={(event) => { + handleEnsClick(); + event.stopPropagation(); + event.preventDefault(); + }} /> ); }; diff --git a/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx b/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx index 02dcc277..30394ddc 100644 --- a/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx @@ -63,10 +63,14 @@ const ContentSection: React.FC = ({ const { openEnsProfile } = useJustWeb3(); const isProfileSelf = useMemo(() => { - const isEns = accountEnsNames?.map((ens) => ens.ens).includes(fullSubname); + const tempEns = accountEnsNames + ?.map((ens) => ens.ens) + .find((e) => e === fullSubname); - if (isEns) { - return chainId === connectedWalletChainId; + if (tempEns) { + if (!accountSubnames?.find((subname) => subname.ens === tempEns)) { + return chainId === connectedWalletChainId; + } } return ( diff --git a/packages/@justweb3/widget/src/lib/dialogs/SignInDialog/index.tsx b/packages/@justweb3/widget/src/lib/dialogs/SignInDialog/index.tsx index 484abef9..eeb51db4 100644 --- a/packages/@justweb3/widget/src/lib/dialogs/SignInDialog/index.tsx +++ b/packages/@justweb3/widget/src/lib/dialogs/SignInDialog/index.tsx @@ -64,6 +64,7 @@ export interface SignInDialogProps { logo?: string; disableOverlay?: boolean; dev?: boolean; + local?: boolean; } export const SignInDialog: FC = ({ @@ -73,6 +74,7 @@ export const SignInDialog: FC = ({ logo, disableOverlay, dev = false, + local, }) => { const { chainId, ensDomains } = useJustaName(); const { isConnected, address } = useMountedAccount(); @@ -152,7 +154,9 @@ export const SignInDialog: FC = ({ : isAddSubnamePendingTestnet; }, [chainId, isAddSubnamePendingMainnet, isAddSubnamePendingTestnet]); - const { signIn } = useEnsSignIn(); + const { signIn } = useEnsSignIn({ + local: local, + }); const { offchainResolvers, isOffchainResolversPending } = useOffchainResolvers(); diff --git a/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx b/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx index f91ca993..f670f2f8 100644 --- a/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx +++ b/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx @@ -18,6 +18,7 @@ import { UseEnsSignInResult, useEnsSignOut, UseEnsSignOutResult, + useMounted, useMountedAccount, useRecords, UseSubnameUpdateFunctionParams, @@ -182,6 +183,22 @@ export const JustWeb3Provider: FC = ({ } }; + const mounted = useMounted(); + useEffect(() => { + if (mounted) { + if (window !== undefined) { + handleJustWeb3Config({ + ...initialConfig, + config: { + domain: window?.location?.hostname, + origin: window?.location?.origin, + ...initialConfig.config, + }, + }); + } + } + }, [initialConfig, mounted]); + return ( @@ -211,6 +228,7 @@ export const JustWeb3Provider: FC = ({ : true } handleOpenDialog={handleOpenSignInDialog} + enableAuth={config.enableAuth} /> = ({ logo={config.logo} disableOverlay={config.disableOverlay} dev={config.dev} + local={!config.enableAuth} /> { const context = useContext(JustWeb3Context); const justanameContext = useContext(JustaNameContext); - const { signIn, isSignInPending } = useEnsSignIn(); - const { signOut, isSignOutPending } = useEnsSignOut(); + + const { signIn, isSignInPending } = useEnsSignIn({ + local: !context.config.enableAuth, + }); + const { signOut, isSignOutPending } = useEnsSignOut({ + local: !context.config.enableAuth, + }); const { connectedEns, isLoggedIn, @@ -278,7 +302,9 @@ export const useJustWeb3 = (): useJustWeb3 => { isEnsAuthLoading, isEnsAuthFetching, refreshEnsAuth, - } = useEnsAuth(); + } = useEnsAuth({ + local: !context.config.enableAuth, + }); const { handleUpdateRecords, handleOpenEnsProfile } = context; const handleUpdateRecordsInternal = async ( records: Omit & { @@ -343,10 +369,16 @@ export const useJustWeb3 = (): useJustWeb3 => { const CheckSession: FC<{ openOnWalletConnect: boolean; handleOpenDialog: (open: boolean) => void; -}> = ({ openOnWalletConnect, handleOpenDialog }) => { - const { connectedEns, isEnsAuthPending } = useEnsAuth(); + enableAuth?: boolean; +}> = ({ openOnWalletConnect, handleOpenDialog, enableAuth }) => { + const { connectedEns, isEnsAuthPending } = useEnsAuth({ + local: !enableAuth, + }); const { getRecords } = useRecords(); - const { signOut } = useEnsSignOut(); + const { signOut } = useEnsSignOut({ + local: !enableAuth, + }); + const { address, isConnected: isConnectedAccount, diff --git a/packages/@justweb3/widget/src/lib/providers/MAppProvider/index.tsx b/packages/@justweb3/widget/src/lib/providers/MAppProvider/index.tsx index 383b3512..56cac1bb 100644 --- a/packages/@justweb3/widget/src/lib/providers/MAppProvider/index.tsx +++ b/packages/@justweb3/widget/src/lib/providers/MAppProvider/index.tsx @@ -33,6 +33,7 @@ export interface MAppContextProps { handleOpenAuthorizeMAppDialog: (mAppName: string, open?: boolean) => void; handleOpenRevokeMAppDialog: (mAppName: string, open?: boolean) => void; handleOpenSignInDialog: (open: boolean) => void; + config: JustWeb3ProviderConfig; } export const MAppContext = createContext({ @@ -42,6 +43,7 @@ export const MAppContext = createContext({ handleOpenAuthorizeMAppDialog: () => {}, handleOpenRevokeMAppDialog: () => {}, handleOpenSignInDialog: () => {}, + config: {}, }); interface MAppsProviderProps { @@ -66,7 +68,9 @@ export const MAppsProvider: FC = ({ plugins, config, }) => { - const { isEnsAuthPending, isLoggedIn, connectedEns } = useEnsAuth(); + const { isEnsAuthPending, isLoggedIn, connectedEns } = useEnsAuth({ + local: !config.enableAuth, + }); const [mAppsToEnableOpen, setMAppsToEnableOpen] = useState< { name: string; isOpen: boolean }[] | undefined >(undefined); @@ -159,6 +163,7 @@ export const MAppsProvider: FC = ({ handleOpenRevokeMAppDialog, canEnableMApps, handleOpenSignInDialog, + config, }} > { handleOpenAuthorizeMAppDialog: contextOpenAuthorizeMAppDialog, handleOpenRevokeMAppDialog: contextOpenRevokeMAppDialog, handleOpenSignInDialog, + config, } = useContext(MAppContext); - - const { connectedEns } = useEnsAuth(); + const { connectedEns } = useEnsAuth({ + local: !config.enableAuth, + }); const { isMAppEnabled, isMAppEnabledPending } = useIsMAppEnabled({ ens: connectedEns?.ens || '', mApp, diff --git a/packages/@justweb3/widget/src/lib/providers/PluginProvider/index.tsx b/packages/@justweb3/widget/src/lib/providers/PluginProvider/index.tsx index b6a4e822..5e4d8743 100644 --- a/packages/@justweb3/widget/src/lib/providers/PluginProvider/index.tsx +++ b/packages/@justweb3/widget/src/lib/providers/PluginProvider/index.tsx @@ -49,7 +49,9 @@ export const PluginProvider: FC = ({ mApps, config, }) => { - const { connectedEns, isEnsAuthPending, isLoggedIn } = useEnsAuth(); + const { connectedEns, isEnsAuthPending, isLoggedIn } = useEnsAuth({ + local: !config.enableAuth, + }); const { records } = useRecords({ ens: connectedEns?.ens || '', }); diff --git a/packages/@justweb3/widget/src/lib/types/config/index.ts b/packages/@justweb3/widget/src/lib/types/config/index.ts index 89ce259c..b62a6b59 100644 --- a/packages/@justweb3/widget/src/lib/types/config/index.ts +++ b/packages/@justweb3/widget/src/lib/types/config/index.ts @@ -9,6 +9,7 @@ export interface JustWeb3ProviderConfig allowedEns?: 'all' | 'claimable' | string[]; logo?: string; disableOverlay?: boolean; + enableAuth?: boolean; mApps?: (string | { name: string; openOnConnect: boolean })[]; plugins?: JustaPlugin[]; } diff --git a/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx b/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx index 940554e4..ef63dacb 100644 --- a/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx +++ b/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx @@ -1,3 +1,12 @@ import './polyfills'; +import { scan } from 'react-scan'; // import this BEFORE react + +if (typeof window !== 'undefined') { + scan({ + enabled: true, + log: true, // logs render info to console (default: false) + }); +} + export const decorators = [(Story) => ]; diff --git a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx index 1cfba830..40a4e83e 100644 --- a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx +++ b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx @@ -1,21 +1,21 @@ import { JustEnsCard, + JustWeb3Button, JustWeb3Provider, JustWeb3ProviderConfig, } from '@justweb3/widget'; import '@justweb3/widget/styles.css'; -import { getDefaultConfig, RainbowKitProvider } from '@rainbow-me/rainbowkit'; +import { + ConnectButton, + getDefaultConfig, + RainbowKitProvider, +} from '@rainbow-me/rainbowkit'; import '@rainbow-me/rainbowkit/styles.css'; import { Meta, StoryObj } from '@storybook/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { WagmiProvider } from 'wagmi'; import { mainnet, sepolia } from 'wagmi/chains'; -import { XMTPPlugin } from '../lib'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; -import { EFPPlugin } from '@justweb3/efp-plugin'; -import { POAPPlugin } from '@justweb3/poap-plugin'; -import { TalentProtocolPlugin } from '@justweb3/talent-protocol-plugin'; -import { JustVerifiedPlugin } from '@justverified/plugin'; const queryClient = new QueryClient(); @@ -42,20 +42,20 @@ const JustWeb3Config: JustWeb3ProviderConfig = { // chainId: parseInt(import.meta.env.STORYBOOK_APP_CHAIN_ID) as ChainId, // }, // ], - openOnWalletConnect: false, - // allowedEns: 'all', - // dev: import.meta.env.STORYBOOK_APP_DEV === 'true', - plugins: [ - XMTPPlugin, - EFPPlugin, - POAPPlugin({ - apiKey: import.meta.env.STORYBOOK_APP_POAP_KEY, - }), - TalentProtocolPlugin({ - apiKey: import.meta.env.STORYBOOK_APP_TALENT_PROTOCOL_API_KEY, - }), - JustVerifiedPlugin(['email', 'telegram', 'twitter', 'discord']), - ], + // openOnWalletConnect: false, + // // allowedEns: 'all', + // // dev: import.meta.env.STORYBOOK_APP_DEV === 'true', + // plugins: [ + // XMTPPlugin, + // EFPPlugin, + // POAPPlugin({ + // apiKey: import.meta.env.STORYBOOK_APP_POAP_KEY, + // }), + // TalentProtocolPlugin({ + // apiKey: import.meta.env.STORYBOOK_APP_TALENT_PROTOCOL_API_KEY, + // }), + // JustVerifiedPlugin(['email', 'telegram', 'twitter', 'discord']), + // ], // color: { // primary: '#FF00FF', // background: '#000000', @@ -83,11 +83,11 @@ export const Example = () => { flexDirection: 'column', }} > - {/*
*/} - {/* */} - {/* */} - {/* */} - {/*
*/} +
+ + + +
@@ -115,17 +115,24 @@ export const Example = () => { chainId={11155111} />
-
- {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} +
+ + + + + +
diff --git a/yarn.lock b/yarn.lock index 0905d656..19a59273 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1798,6 +1798,27 @@ __metadata: languageName: node linkType: hard +"@clack/core@npm:0.3.5, @clack/core@npm:^0.3.5": + version: 0.3.5 + resolution: "@clack/core@npm:0.3.5" + dependencies: + picocolors: "npm:^1.0.0" + sisteransi: "npm:^1.0.5" + checksum: 10c0/b1037226b38696bd95e09beef789ff4e23abb282505ac233c0316c2410c8afb68cf91b67812c883f05ffa6943d6f0593f1ebc17beb94f4a42c13e4657f598c0b + languageName: node + linkType: hard + +"@clack/prompts@npm:^0.8.2": + version: 0.8.2 + resolution: "@clack/prompts@npm:0.8.2" + dependencies: + "@clack/core": "npm:0.3.5" + picocolors: "npm:^1.0.0" + sisteransi: "npm:^1.0.5" + checksum: 10c0/7ac6e7e0fba1c958847e6e3ef9415d9c2184fb424b31691aaef64fd06042d243e859c157b941ca1c9f73e9cb649413fab487a602b981e300acfbec4a111d7562 + languageName: node + linkType: hard + "@coinbase/wallet-sdk@npm:4.0.3": version: 4.0.3 resolution: "@coinbase/wallet-sdk@npm:4.0.3" @@ -26842,6 +26863,7 @@ __metadata: react-native-web: "npm:~0.19.9" react-refresh: "npm:^0.10.0" react-router-dom: "npm:6.11.2" + react-scan: "npm:^0.0.35" react-split: "npm:^2.0.14" react-test-renderer: "npm:18.2.0" react-timer-hook: "npm:^3.0.8" @@ -26945,7 +26967,7 @@ __metadata: languageName: node linkType: hard -"kleur@npm:4.1.5": +"kleur@npm:4.1.5, kleur@npm:^4.1.5": version: 4.1.5 resolution: "kleur@npm:4.1.5" checksum: 10c0/e9de6cb49657b6fa70ba2d1448fd3d691a5c4370d8f7bbf1c2f64c24d461270f2117e1b0afe8cb3114f13bbd8e51de158c2a224953960331904e636a5e4c0f2a @@ -31436,6 +31458,15 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.49.0": + version: 1.49.0 + resolution: "playwright-core@npm:1.49.0" + bin: + playwright-core: cli.js + checksum: 10c0/22c1a72fabdcc87bd1cd4d40a032d2c5b94cf94ba7484dc182048c3fa1c8ec26180b559d8cac4ca9870e8fd6bdf5ef9d9f54e7a31fd60d67d098fcffc5e4253b + languageName: node + linkType: hard + "playwright@npm:^1.14.0": version: 1.48.2 resolution: "playwright@npm:1.48.2" @@ -31451,6 +31482,21 @@ __metadata: languageName: node linkType: hard +"playwright@npm:^1.49.0": + version: 1.49.0 + resolution: "playwright@npm:1.49.0" + dependencies: + fsevents: "npm:2.3.2" + playwright-core: "npm:1.49.0" + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 10c0/e94d662747cd147d0573570fec90dadc013c1097595714036fc8934a075c5a82ab04a49111b03b1f762ea86429bdb7c94460901896901e20970b30ce817cc93f + languageName: node + linkType: hard + "plist@npm:^3.0.5": version: 3.1.0 resolution: "plist@npm:3.1.0" @@ -33451,6 +33497,21 @@ __metadata: languageName: node linkType: hard +"react-scan@npm:^0.0.35": + version: 0.0.35 + resolution: "react-scan@npm:0.0.35" + dependencies: + "@clack/core": "npm:^0.3.5" + "@clack/prompts": "npm:^0.8.2" + kleur: "npm:^4.1.5" + mri: "npm:^1.2.0" + playwright: "npm:^1.49.0" + bin: + react-scan: bin/cli.js + checksum: 10c0/f0f8d4f489bd07fa659b1f10111befd92e5c12d1fd2d39abeaa22a358069700914c570085ff6c73c9bd541d0c24e8725b65a2454699d1c45a7c8b646339530ec + languageName: node + linkType: hard + "react-shallow-renderer@npm:^16.15.0": version: 16.15.0 resolution: "react-shallow-renderer@npm:16.15.0" From 11c7dad266b8b41302a3593b2eabf8b8e9b0b703 Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Tue, 3 Dec 2024 17:54:21 +0200 Subject: [PATCH 19/29] chore(release): publish [skip ci] - project: @justaname.id/sdk 0.2.155 - project: @justaname.id/react 0.3.158 - project: @justaname.id/siwens 0.0.88 - project: @justweb3/ui 0.0.94 - project: @justweb3/widget 0.0.94 - project: @justverified/plugin 0.0.93 - project: @justweb3/efp-plugin 0.1.54 - project: @justweb3/poap-plugin 0.0.12 - project: @justweb3/talent-protocol-plugin 0.0.12 --- packages/@justaname.id/react/CHANGELOG.md | 17 +++++++++++++++++ packages/@justaname.id/react/package.json | 4 ++-- packages/@justaname.id/sdk/CHANGELOG.md | 17 +++++++++++++++++ packages/@justaname.id/sdk/package.json | 4 ++-- packages/@justaname.id/siwens/CHANGELOG.md | 12 ++++++++++++ packages/@justaname.id/siwens/package.json | 2 +- packages/@justverified/plugin/CHANGELOG.md | 4 ++++ packages/@justverified/plugin/package.json | 2 +- packages/@justweb3/efp-plugin/CHANGELOG.md | 4 ++++ packages/@justweb3/efp-plugin/package.json | 2 +- packages/@justweb3/poap-plugin/package.json | 2 +- .../talent-protocol-plugin/package.json | 2 +- packages/@justweb3/ui/CHANGELOG.md | 12 ++++++++++++ packages/@justweb3/ui/package.json | 2 +- packages/@justweb3/widget/CHANGELOG.md | 19 +++++++++++++++++++ packages/@justweb3/widget/package.json | 8 ++++---- yarn.lock | 18 +++++++++--------- 17 files changed, 108 insertions(+), 23 deletions(-) diff --git a/packages/@justaname.id/react/CHANGELOG.md b/packages/@justaname.id/react/CHANGELOG.md index 11102e1b..18b3f63d 100644 --- a/packages/@justaname.id/react/CHANGELOG.md +++ b/packages/@justaname.id/react/CHANGELOG.md @@ -1,3 +1,20 @@ +## 0.3.158 (2024-12-03) + + +### 🚀 Features + +- sign in optional ([3df90a7](https://github.com/JustaName-id/JustaName-sdk/commit/3df90a7)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.155 + + +### ❤️ Thank You + +- HadiKhai + ## 0.3.157 (2024-12-02) diff --git a/packages/@justaname.id/react/package.json b/packages/@justaname.id/react/package.json index 679807f8..e3f639be 100644 --- a/packages/@justaname.id/react/package.json +++ b/packages/@justaname.id/react/package.json @@ -1,9 +1,9 @@ { "name": "@justaname.id/react", - "version": "0.3.157", + "version": "0.3.158", "dependencies": { "@ensdomains/ensjs": "4.0.2", - "@justaname.id/sdk": "0.2.154", + "@justaname.id/sdk": "0.2.155", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/sdk/CHANGELOG.md b/packages/@justaname.id/sdk/CHANGELOG.md index 4c46437e..0be6bf0c 100644 --- a/packages/@justaname.id/sdk/CHANGELOG.md +++ b/packages/@justaname.id/sdk/CHANGELOG.md @@ -1,3 +1,20 @@ +## 0.2.155 (2024-12-03) + + +### 🚀 Features + +- sign in optional ([3df90a7](https://github.com/JustaName-id/JustaName-sdk/commit/3df90a7)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/siwens to 0.0.88 + + +### ❤️ Thank You + +- HadiKhai + ## 0.2.154 (2024-12-02) diff --git a/packages/@justaname.id/sdk/package.json b/packages/@justaname.id/sdk/package.json index 5c60efb9..33222e62 100644 --- a/packages/@justaname.id/sdk/package.json +++ b/packages/@justaname.id/sdk/package.json @@ -1,8 +1,8 @@ { "name": "@justaname.id/sdk", - "version": "0.2.154", + "version": "0.2.155", "dependencies": { - "@justaname.id/siwens": "0.0.87", + "@justaname.id/siwens": "0.0.88", "axios": "^1.6.0", "qs": "^6.12.0" }, diff --git a/packages/@justaname.id/siwens/CHANGELOG.md b/packages/@justaname.id/siwens/CHANGELOG.md index 6adfffb0..36acbe66 100644 --- a/packages/@justaname.id/siwens/CHANGELOG.md +++ b/packages/@justaname.id/siwens/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.0.88 (2024-12-03) + + +### 🚀 Features + +- sign in optional ([3df90a7](https://github.com/JustaName-id/JustaName-sdk/commit/3df90a7)) + + +### ❤️ Thank You + +- HadiKhai + ## 0.0.87 (2024-12-02) This was a version bump only for @justaname.id/siwens to align it with other projects, there were no code changes. diff --git a/packages/@justaname.id/siwens/package.json b/packages/@justaname.id/siwens/package.json index 580e7629..e7616056 100644 --- a/packages/@justaname.id/siwens/package.json +++ b/packages/@justaname.id/siwens/package.json @@ -1,6 +1,6 @@ { "name": "@justaname.id/siwens", - "version": "0.0.87", + "version": "0.0.88", "peerDependencies": { "ethers": "^5.6.8 || ^6.0.8", "siwe": ">=2.0.0" diff --git a/packages/@justverified/plugin/CHANGELOG.md b/packages/@justverified/plugin/CHANGELOG.md index 727d1eae..67dfe942 100644 --- a/packages/@justverified/plugin/CHANGELOG.md +++ b/packages/@justverified/plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.93 (2024-12-03) + +This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. + ## 0.0.92 (2024-12-02) This was a version bump only for @justverified/plugin to align it with other projects, there were no code changes. diff --git a/packages/@justverified/plugin/package.json b/packages/@justverified/plugin/package.json index ace7f9ee..27dd8160 100644 --- a/packages/@justverified/plugin/package.json +++ b/packages/@justverified/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justverified/plugin", - "version": "0.0.92", + "version": "0.0.93", "dependencies": { "axios": "^1.6.0", "lodash": "4.17.21", diff --git a/packages/@justweb3/efp-plugin/CHANGELOG.md b/packages/@justweb3/efp-plugin/CHANGELOG.md index 5aa394cc..8c6a03c5 100644 --- a/packages/@justweb3/efp-plugin/CHANGELOG.md +++ b/packages/@justweb3/efp-plugin/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.54 (2024-12-03) + +This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. + ## 0.1.53 (2024-12-02) This was a version bump only for @justweb3/efp-plugin to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/efp-plugin/package.json b/packages/@justweb3/efp-plugin/package.json index 3bf60963..49fb3781 100644 --- a/packages/@justweb3/efp-plugin/package.json +++ b/packages/@justweb3/efp-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/efp-plugin", - "version": "0.1.53", + "version": "0.1.54", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/poap-plugin/package.json b/packages/@justweb3/poap-plugin/package.json index 892b2cda..58373ca4 100644 --- a/packages/@justweb3/poap-plugin/package.json +++ b/packages/@justweb3/poap-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/poap-plugin", - "version": "0.0.11", + "version": "0.0.12", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/talent-protocol-plugin/package.json b/packages/@justweb3/talent-protocol-plugin/package.json index 28749f91..c538a7e0 100644 --- a/packages/@justweb3/talent-protocol-plugin/package.json +++ b/packages/@justweb3/talent-protocol-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/talent-protocol-plugin", - "version": "0.0.11", + "version": "0.0.12", "dependencies": { "axios": "^1.6.0" }, diff --git a/packages/@justweb3/ui/CHANGELOG.md b/packages/@justweb3/ui/CHANGELOG.md index 64fdc447..ed39886b 100644 --- a/packages/@justweb3/ui/CHANGELOG.md +++ b/packages/@justweb3/ui/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.0.94 (2024-12-03) + + +### 🚀 Features + +- sign in optional ([3df90a7](https://github.com/JustaName-id/JustaName-sdk/commit/3df90a7)) + + +### ❤️ Thank You + +- HadiKhai + ## 0.0.93 (2024-12-02) This was a version bump only for @justweb3/ui to align it with other projects, there were no code changes. diff --git a/packages/@justweb3/ui/package.json b/packages/@justweb3/ui/package.json index 3f2bc8c8..09562f42 100644 --- a/packages/@justweb3/ui/package.json +++ b/packages/@justweb3/ui/package.json @@ -1,6 +1,6 @@ { "name": "@justweb3/ui", - "version": "0.0.93", + "version": "0.0.94", "dependencies": { "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dialog": "^1.1.1", diff --git a/packages/@justweb3/widget/CHANGELOG.md b/packages/@justweb3/widget/CHANGELOG.md index 4dcb74e0..91e4af78 100644 --- a/packages/@justweb3/widget/CHANGELOG.md +++ b/packages/@justweb3/widget/CHANGELOG.md @@ -1,3 +1,22 @@ +## 0.0.94 (2024-12-03) + + +### 🚀 Features + +- sign in optional ([3df90a7](https://github.com/JustaName-id/JustaName-sdk/commit/3df90a7)) + + +### 🧱 Updated Dependencies + +- Updated @justaname.id/sdk to 0.2.155 +- Updated @justaname.id/react to 0.3.158 +- Updated @justweb3/ui to 0.0.94 + + +### ❤️ Thank You + +- HadiKhai + ## 0.0.93 (2024-12-02) diff --git a/packages/@justweb3/widget/package.json b/packages/@justweb3/widget/package.json index 2c21ce92..303946bf 100644 --- a/packages/@justweb3/widget/package.json +++ b/packages/@justweb3/widget/package.json @@ -1,12 +1,12 @@ { "name": "@justweb3/widget", - "version": "0.0.93", + "version": "0.0.94", "dependencies": { "@ensdomains/address-encoder": "^1.1.2", "@hookform/resolvers": "^3.9.0", - "@justaname.id/react": "0.3.157", - "@justaname.id/sdk": "0.2.154", - "@justweb3/ui": "^0.0.93", + "@justaname.id/react": "0.3.158", + "@justaname.id/sdk": "0.2.155", + "@justweb3/ui": "^0.0.94", "clsx": "1.2.1", "cropperjs": "^1.6.2", "lodash": "4.17.21", diff --git a/yarn.lock b/yarn.lock index 19a59273..50444bfa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4535,12 +4535,12 @@ __metadata: languageName: node linkType: hard -"@justaname.id/react@npm:0.3.157, @justaname.id/react@workspace:packages/@justaname.id/react": +"@justaname.id/react@npm:0.3.158, @justaname.id/react@workspace:packages/@justaname.id/react": version: 0.0.0-use.local resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" dependencies: "@ensdomains/ensjs": "npm:4.0.2" - "@justaname.id/sdk": "npm:0.2.154" + "@justaname.id/sdk": "npm:0.2.155" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4553,11 +4553,11 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/sdk@npm:0.2.154, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": +"@justaname.id/sdk@npm:0.2.155, @justaname.id/sdk@workspace:packages/@justaname.id/sdk": version: 0.0.0-use.local resolution: "@justaname.id/sdk@workspace:packages/@justaname.id/sdk" dependencies: - "@justaname.id/siwens": "npm:0.0.87" + "@justaname.id/siwens": "npm:0.0.88" axios: "npm:^1.6.0" jest: "npm:^29.4.1" qs: "npm:^6.12.0" @@ -4568,7 +4568,7 @@ __metadata: languageName: unknown linkType: soft -"@justaname.id/siwens@npm:0.0.87, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": +"@justaname.id/siwens@npm:0.0.88, @justaname.id/siwens@workspace:packages/@justaname.id/siwens": version: 0.0.0-use.local resolution: "@justaname.id/siwens@workspace:packages/@justaname.id/siwens" peerDependencies: @@ -4628,7 +4628,7 @@ __metadata: languageName: unknown linkType: soft -"@justweb3/ui@npm:^0.0.93, @justweb3/ui@workspace:packages/@justweb3/ui": +"@justweb3/ui@npm:^0.0.94, @justweb3/ui@workspace:packages/@justweb3/ui": version: 0.0.0-use.local resolution: "@justweb3/ui@workspace:packages/@justweb3/ui" dependencies: @@ -4656,9 +4656,9 @@ __metadata: dependencies: "@ensdomains/address-encoder": "npm:^1.1.2" "@hookform/resolvers": "npm:^3.9.0" - "@justaname.id/react": "npm:0.3.157" - "@justaname.id/sdk": "npm:0.2.154" - "@justweb3/ui": "npm:^0.0.93" + "@justaname.id/react": "npm:0.3.158" + "@justaname.id/sdk": "npm:0.2.155" + "@justweb3/ui": "npm:^0.0.94" clsx: "npm:1.2.1" cropperjs: "npm:^1.6.2" lodash: "npm:4.17.21" From 6e497746e645637c8218747146102d7aba117752 Mon Sep 17 00:00:00 2001 From: anthony2399 Date: Tue, 3 Dec 2024 19:30:11 +0200 Subject: [PATCH 20/29] feat: finalizing new convo --- package.json | 1 + .../src/lib/components/Chat/index.tsx | 126 +++++++----- .../src/lib/components/ChatList/index.tsx | 9 +- .../src/lib/components/ChatSheet/index.tsx | 2 + .../src/lib/components/CustomPlayer/index.tsx | 19 +- .../components/CustomVoicePreview/index.tsx | 16 +- .../lib/components/EmojiSelector/index.tsx | 30 +-- .../src/lib/components/MessageCard/index.tsx | 97 +++++---- .../src/lib/components/MessageItem/index.tsx | 40 ++-- .../components/MessageSkeletonCard/index.tsx | 10 +- .../lib/components/MessageTextField/index.tsx | 70 ++++--- .../lib/components/NewConversation/index.tsx | 184 ++++++++++++++++++ .../lib/components/NewMessageSheet/index.tsx | 29 +++ .../lib/components/VoiceMessageCard/index.tsx | 50 +++-- .../xmtp-plugin/src/lib/hooks/index.ts | 2 + .../lib/hooks/useAddressResolution/index.ts | 72 +++++++ .../lib/hooks/useIdentityResolution/index.ts | 35 ++++ yarn.lock | 10 + 18 files changed, 615 insertions(+), 187 deletions(-) create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/NewMessageSheet/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/useAddressResolution/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/useIdentityResolution/index.ts diff --git a/package.json b/package.json index d3e05ddc..029e8c75 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@hookform/error-message": "^2.0.1", "@hookform/resolvers": "^3.9.0", "@inquirer/prompts": "^4.3.0", + "@justaname.id/address-resolution": "^1.1.0", "@privy-io/react-auth": "^1.82.0", "@privy-io/wagmi": "^0.2.12", "@radix-ui/react-accordion": "^1.2.1", diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx index dffcbedf..84855c4d 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx @@ -21,23 +21,23 @@ import { CachedConversation, ContentTypeMetadata, useCanMessage, - useClient, useConsent, useMessages, - useStreamMessages, + useStreamMessages } from '@xmtp/react-sdk'; import React, { useEffect, useMemo } from 'react'; import { useSendReactionMessage } from '../../hooks'; +import { typeLookup } from '../../utils/attachments'; import { filterReactionsMessages, MessageWithReaction, } from '../../utils/filterReactionsMessages'; import { formatAddress } from '../../utils/formatAddress'; import { groupMessagesByDate } from '../../utils/groupMessageByDate'; -import MessageCard from '../MessageCard'; import EmojiSelector from '../EmojiSelector'; -import MessageTextField from '../MessageTextField'; +import MessageCard from '../MessageCard'; import { MessageSkeletonCard } from '../MessageSkeletonCard'; +import MessageTextField from '../MessageTextField'; export interface ChatProps { conversation: CachedConversation; @@ -49,7 +49,6 @@ export const Chat: React.FC = ({ conversation, onBack }) => { React.useState(null); const [reactionMessage, setReactionMessage] = React.useState(null); - const [emojiSelectorTop, setEmojiSelectorTop] = React.useState(0); const [isRequest, setIsRequest] = React.useState(false); const [isRequestChangeLoading, setIsRequestChangeLoading] = React.useState(false); @@ -65,7 +64,6 @@ export const Chat: React.FC = ({ conversation, onBack }) => { const { sanitizeEnsImage } = useEnsAvatar(); const { address } = useMountedAccount(); - const { client } = useClient(); const [canMessage, setCanMessage] = React.useState(true); @@ -224,10 +222,10 @@ export const Chat: React.FC = ({ conversation, onBack }) => { src={ primaryName ? sanitizeEnsImage({ - name: primaryName, - chainId: 1, - image: records?.sanitizedRecords?.avatar, - }) + name: primaryName, + chainId: 1, + image: records?.sanitizedRecords?.avatar, + }) : undefined } style={{ @@ -337,14 +335,15 @@ export const Chat: React.FC = ({ conversation, onBack }) => { {isCanMessageLoading || isLoading ? ( - {[...Array(5)].map((_, index) => ( + {[...Array(8)].map((_, index) => ( = ({ conversation, onBack }) => { {canMessage ? ( @@ -379,19 +395,34 @@ export const Chat: React.FC = ({ conversation, onBack }) => { {groupedMessages && Object.keys(groupedMessages).map((date, index) => ( -

+

- {date} -

+ }} /> +

+ {date} +

+
+ {groupedMessages[date].map((message) => ( = ({ conversation, onBack }) => { ) as HTMLElement; replica.id = `${message.id}-replica`; replica.style.position = 'absolute'; - replica.style.top = element?.offsetTop + 'px'; - replica.style.top = '100px'; + replica.style.bottom = '310px'; + replica.style.minHeight = '20px'; + replica.style.left = '4.2vw'; replica.style.zIndex = '90'; element?.parentElement?.appendChild(replica); replica.classList.add('replica-animate'); - setEmojiSelectorTop( - 100 + element.getBoundingClientRect().height - ); }} /> ))} @@ -429,15 +458,9 @@ export const Chat: React.FC = ({ conversation, onBack }) => { style={{ zIndex: 99, position: 'absolute', - right: - reactionMessage?.senderAddress === client?.address - ? '20px' - : 'auto', - left: - reactionMessage?.senderAddress === client?.address - ? 'auto' - : '20px', - top: `${emojiSelectorTop + 20}px`, + left: '50%', + transform: 'translateX(-50%)', + bottom: `30px`, }} > = ({ conversation, onBack }) => { {isMessagesSenderOnly && (

Message in user’s Requests

-

This user has not accepted your message request yet

+

This user has not accepted your message request yet

)} setReplyMessage(null)} conversation={conversation} replyMessage={replyMessage} + peerAddress={conversation.peerAddress} /> )} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx index 676a6753..25222391 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx @@ -1,5 +1,5 @@ -import { CachedConversation, ContentTypeMetadata } from '@xmtp/react-sdk'; import { Flex } from '@justweb3/ui'; +import { CachedConversation, ContentTypeMetadata } from '@xmtp/react-sdk'; import React from 'react'; import { MessageItem } from '../MessageItem'; @@ -8,19 +8,24 @@ export interface ChatListProps { handleOpenChat: ( conversation: CachedConversation | null ) => void; + blockedList?: boolean } export const ChatList: React.FC = ({ conversations, handleOpenChat, + blockedList }) => { return ( - + {conversations.map((conversation) => ( handleOpenChat(conversation)} key={conversation.topic} + blocked={blockedList} /> ))} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx index 5a794bda..a9063ce3 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx @@ -83,6 +83,7 @@ export const ChatSheet: React.FC = ({ flexDirection: 'column', marginBottom: '0px', overflow: 'hidden', + marginTop: '10px', flex: '1', }} > @@ -126,6 +127,7 @@ export const ChatSheet: React.FC = ({ diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/CustomPlayer/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/CustomPlayer/index.tsx index 32af76c1..1ab77a3c 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/CustomPlayer/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/CustomPlayer/index.tsx @@ -1,4 +1,4 @@ -import { Flex, PauseIcon, PlayIcon } from '@justweb3/ui'; +import { DownloadIcon, Flex, PauseIcon, PlayIcon } from '@justweb3/ui'; import React, { useEffect, useRef, useState } from 'react'; @@ -6,12 +6,14 @@ export interface CustomPlayerProps { style?: React.CSSProperties; url?: string; disabled?: boolean; + fileName?: string; } export const CustomPlayer: React.FC = ({ style, url = '', - disabled + disabled, + fileName }) => { const [playing, setPlaying] = React.useState(false); const videoRef = useRef(null); @@ -84,12 +86,21 @@ export const CustomPlayer: React.FC = ({ } { !playing && -
-
+ {!!fileName && ( + { + e.stopPropagation() + }} style={{ + transform: 'translateY(2px)' + }} href={url} download={fileName}> + + )} +
} + ); } diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/CustomVoicePreview/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/CustomVoicePreview/index.tsx index 49e12de3..5a1ed580 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/CustomVoicePreview/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/CustomVoicePreview/index.tsx @@ -56,29 +56,27 @@ const CustomVoicePreview: React.FC = ({ return ( {playing ? - : - }

{playing || currentTime > 0 ? formatTime(currentTime) : formatTime(audioDuration ?? 0)}

- diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/EmojiSelector/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/EmojiSelector/index.tsx index f39022f8..c57959d1 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/EmojiSelector/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/EmojiSelector/index.tsx @@ -32,29 +32,30 @@ const EmojiSelector: React.FC = ({ return ( - setSearchValue(e.target.value)} /> -
{filteredEmojis.map((emoji, index) => ( @@ -62,10 +63,11 @@ const EmojiSelector: React.FC = ({ key={index} onClick={() => onEmojiClickHandler(emoji)} style={{ - padding: '2px', - fontSize: '20px', + aspectRatio: '1', + fontSize: '16px', borderRadius: '10px', border: 'none', + cursor: 'pointer' }} > {emoji.emoji} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx index f63cce4d..ee30c266 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx @@ -2,7 +2,7 @@ import { useEffect, useMemo, useRef } from "react"; import { CachedConversation, DecodedMessage } from "@xmtp/react-sdk"; import { MessageWithReaction } from "../../utils/filterReactionsMessages"; import { useState } from "react"; -import { useMountedAccount } from "@justaname.id/react"; +import { useMountedAccount, usePrimaryName } from "@justaname.id/react"; import React from "react"; import { useSendReactionMessage } from "../../hooks"; import { typeLookup } from "../../utils/attachments"; @@ -87,6 +87,8 @@ const MeasureAndHyphenateText: React.FC<{ text: string; maxWidth: number, isRece whiteSpace: 'pre-wrap', wordBreak: 'break-word', margin: 0, + paddingLeft: "2px", + fontFamily: 'var(--justweb3-font-family)', color: isReceiver ? 'var(--justweb3-foreground-color-2)' : 'var(--justweb3-foreground-color-4)' }}> {processedText} @@ -107,6 +109,10 @@ const MessageCard: React.FC = ({ const divRef = useRef(null); const { mutateAsync: sendReaction } = useSendReactionMessage(conversation); + const { primaryName } = usePrimaryName({ + address: peerAddress as `0x${string}`, + }); + const isText = useMemo(() => { return typeof message.content === "string" }, [message.content]) @@ -226,10 +232,10 @@ const MessageCard: React.FC = ({ fontSize: '14px', lineHeight: '14px', padding: isReply ? '4px' : '5px', - borderRadius: '5px', + borderRadius: '14px', backgroundColor: isReceiver ? 'var(--justweb3-foreground-color-4)' : 'var(--justweb3-primary-color)', - borderBottomLeftRadius: isReceiver ? '0px' : '5px', - borderBottomRightRadius: !isReceiver ? '0px' : '5px', + borderBottomLeftRadius: isReceiver ? '0px' : '14px', + borderBottomRightRadius: !isReceiver ? '0px' : '14px', }} gap="5px" @@ -262,22 +268,21 @@ const MessageCard: React.FC = ({ maxWidth: !isImage ? '220px' : 'none', fontSize: '14px', lineHeight: '14px', - padding: '10px', + padding: '5px', backgroundColor: isReceiver ? 'var(--justweb3-primary-color)' : 'var(--justweb3-foreground-color-4)', - borderRadius: '5px', - borderBottomLeftRadius: isReceiver ? '0px' : '5px', - borderBottomRightRadius: isReceiver ? '5px' : '0px', + borderRadius: '10px', + borderBottomLeftRadius: isReceiver ? '0px' : '10px', + borderBottomRightRadius: isReceiver ? '10px' : '0px', }} onClick={navigateToRepliedMessage} > - +

{repliedMessage?.senderAddress === address ? "YOU" : formatAddress(repliedMessage?.senderAddress ?? "")}

+ }} >{repliedMessage?.senderAddress === address ? "YOU" : primaryName ?? formatAddress(repliedMessage?.senderAddress ?? "")}

{(isReplyText || isReplyReply) ? (

= ({ }} >{isReplyReply ? repliedMessage.content.content : repliedMessage.content}

) : ( isReplyVoice ? - = ({ : typeLookup[replyAttachmentExtention] === "video" ? : @@ -357,35 +362,49 @@ const MessageCard: React.FC = ({ : {typeLookup[attachmentExtention] === "image" ? - {message.content.filename} +
+ {message.content.filename} + + +
: typeLookup[attachmentExtention] === "video" ? - : - - + +

{message.content.filename}

{calculateFileSize(message.content.data?.byteLength ?? 0)}

} - -
}
} @@ -407,14 +426,7 @@ const MessageCard: React.FC = ({ >{findEmojiByName(message.reactionMessage.content.content)}

)} - {!isVoice && ( -

{formatMessageSentTime(message.sentAt)}

)} +
= ({
- +

{formatMessageSentTime(message.sentAt)}

); }; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx index 80ee2e9b..0fc4ec87 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx @@ -4,22 +4,25 @@ import { ContentTypeMetadata, reactionContentTypeConfig, replyContentTypeConfig, + useConsent, useLastMessage, useStreamMessages, } from '@xmtp/react-sdk'; import { useEnsAvatar, usePrimaryName, useRecords } from '@justaname.id/react'; -import { Avatar, Flex, formatText, P, SPAN } from '@justweb3/ui'; +import { Avatar, Button, Flex, formatText, P, SPAN } from '@justweb3/ui'; import React, { useMemo } from 'react'; import { formatChatDate } from '../../utils/formatChatDate'; export interface MessageItemProps { conversation: CachedConversation; onClick?: () => void; + blocked?: boolean; } export const MessageItem: React.FC = ({ conversation, onClick, + blocked }) => { const lastMessage = useLastMessage(conversation.topic); useStreamMessages(conversation); @@ -31,6 +34,14 @@ export const MessageItem: React.FC = ({ }); const { sanitizeEnsImage } = useEnsAvatar(); + const { allow, refreshConsentList } = useConsent() + + const allowUser = async () => { + await refreshConsentList() + await allow([conversation.peerAddress]) + await refreshConsentList() + } + const lastContent = useMemo(() => { if (!lastMessage) return ''; @@ -67,18 +78,21 @@ export const MessageItem: React.FC = ({ padding: '10px', border: '1px solid #E8E8E8', borderRadius: '5px', - cursor: 'pointer', + cursor: blocked ? 'auto' : 'pointer', + }} + onClick={() => { + if (blocked) return + onClick && onClick() }} - onClick={onClick} > @@ -123,12 +137,16 @@ export const MessageItem: React.FC = ({ marginLeft: 'auto', alignContent: 'space-between', textAlign: 'end', - width: '50px', }} > - - {lastMessage?.sentAt ? formatChatDate(lastMessage.sentAt) : ''} - + {blocked ? + + : + + {lastMessage?.sentAt ? formatChatDate(lastMessage.sentAt) : ''} + + } ); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSkeletonCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSkeletonCard/index.tsx index 0b18023f..f7855876 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSkeletonCard/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSkeletonCard/index.tsx @@ -18,10 +18,10 @@ export const MessageSkeletonCard: React.FC = ({ isRece maxWidth: '170px', width: '170px', minHeight: '40px', + maxHeight: '40px', fontSize: '14px', display: 'flex', flexDirection: 'column', - padding: '10px', overflowWrap: 'break-word', borderRadius: '10px', border: '1px solid var(--justweb3-primary-color)', @@ -32,6 +32,14 @@ export const MessageSkeletonCard: React.FC = ({ isRece boxShadow: isReceiver ? 'shadow-[-1px_2px_0_0_#3]' : 'shadow-[1px_2px_0_0_#88C6F5]', }}> + + + ) } \ No newline at end of file diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx index 4026a6af..09c03549 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx @@ -3,7 +3,7 @@ import type { Attachment } from '@xmtp/content-type-remote-attachment'; import { CachedConversation, useClient } from '@xmtp/react-sdk'; import React, { Dispatch, SetStateAction, useEffect, useMemo, useRef, useState } from 'react'; import { MessageWithReaction } from '../../utils/filterReactionsMessages'; -import { useMountedAccount } from '@justaname.id/react'; +import { useMountedAccount, usePrimaryName } from '@justaname.id/react'; import { useAttachmentChange, useRecordingTimer, useRecordVoice, useSendAttachment, useSendMessages, useSendReplyMessage } from '../../hooks'; import { AttachmentType, typeLookup } from '../../utils/attachments'; import { Button, CloseIcon, Flex, Input, LoadingSpinner, P, AddImageIcon, AddVideoIcon, AddFolderIcon, DocumentIcon, SendIcon, StopIcon, MicIcon } from '@justweb3/ui'; @@ -20,6 +20,7 @@ interface MessageTextFieldProps { replyMessage?: MessageWithReaction | null; onCancelReply?: () => void; onNewConvo?: (message: string) => void; + peerAddress?: string; } const MessageTextField: React.FC = ({ @@ -28,7 +29,8 @@ const MessageTextField: React.FC = ({ replyMessage, onCancelReply, conversation, - onNewConvo + onNewConvo, + peerAddress }) => { const [messageValue, setMessageValue] = React.useState(""); const [attachment, setAttachment] = React.useState(); @@ -45,6 +47,9 @@ const MessageTextField: React.FC = ({ return attachment?.mimeType.split("/")?.[1] || ""; }, [attachment]); + const { primaryName } = usePrimaryName({ + address: peerAddress as `0x${string}`, + }); // Attachments const [acceptedTypes, setAcceptedTypes]: [ @@ -202,9 +207,8 @@ const MessageTextField: React.FC = ({ {replyMessage && ( = ({ borderBottomRightRadius: 0, borderBottomLeftRadius: 0, }} > - = ({ onClick={navigateToRepliedMessage} >

{isSender ? "YOU" : formatAddress(replyMessage.senderAddress)}

+ }} >{isSender ? "YOU" : primaryName ?? formatAddress(replyMessage.senderAddress)}

{(isReplyText || isReplyReply) ? (

= ({ : typeLookup[replyAttachmentExtention] === "image" ? {replyMessage.content.filename} = ({ : typeLookup[replyAttachmentExtention] === "video" ? : @@ -287,9 +290,18 @@ const MessageTextField: React.FC = ({ padding: '10px 15px', borderRadius: '6px', background: 'white', - // TODO: check border color border: '1px solid grey' }} > + {attachment?.mimeType !== "audio/wav" && ( +

+ )} {attachment?.mimeType === "audio/wav" ? : @@ -299,32 +311,29 @@ const MessageTextField: React.FC = ({ zIndex: 5, padding: '10px 0px', right: '12px', - bottom: '4px', + bottom: '20px', borderRadius: '10px', - background: 'white', - border: '1px solid var(--justweb3-primary-color)', }} > {typeLookup[attachmentExtention] === "image" ? {attachment?.filename} : typeLookup[attachmentExtention] === "video" ? : - - +

= ({ } @@ -378,7 +390,7 @@ const MessageTextField: React.FC = ({ background: 'white' }} >

= ({ {recordingValue}

RECORDING...

- { stopRecording(); @@ -415,7 +427,7 @@ const MessageTextField: React.FC = ({ borderRadius: "6px", borderTopLeftRadius: replyMessage ? 0 : "6px", borderTopRightRadius: replyMessage ? 0 : "6px", - // borderTop: replyMessage ? "0px" : "auto", + borderTop: replyMessage ? "0px" : "", }} placeholder={`Send message...`} value={messageValue} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx new file mode 100644 index 00000000..12cd9345 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx @@ -0,0 +1,184 @@ +import { CachedConversation, toCachedConversation, useCanMessage, useClient, useConsent, useConversation, useStartConversation } from '@xmtp/react-sdk'; +import React, { useEffect, useMemo } from 'react'; +import MessageTextField from '../MessageTextField'; +import { useAddressResolutionName, useDebounced, useIdentityResolution } from '../../hooks'; +import { useMountedAccount, } from '@justaname.id/react'; + +import { ArrowIcon, Flex, Input, LoadingSpinner } from '@justweb3/ui'; + +const CancelIcon: React.FC> = (props) => ( + +); + +interface NewConversationProps { + onChatStarted: (conversation: CachedConversation) => void; + onBack: () => void; + selectedAddress?: string +} + +const NewConversation: React.FC = ({ + onChatStarted, + onBack, + selectedAddress +}) => { + // States + const [newAddress, setNewAddress] = React.useState(selectedAddress ?? ""); + const [canMessage, setCanMessage] = React.useState(false); + //Queries + const { client } = useClient(); + const { startConversation } = useStartConversation() + const { getCachedByPeerAddress } = useConversation(); + const { refreshConsentList, allow } = useConsent(); + const { address } = useMountedAccount(); + const { canMessage: xmtpCanMessage, isLoading } = useCanMessage(); + const { + value: debouncedAddress, + } = useDebounced(newAddress, 500); + + const isAddressName = useMemo(() => { + return !debouncedAddress.startsWith("0x") && !debouncedAddress.startsWith("0X") && debouncedAddress.length > 0; + }, [debouncedAddress]) + + const { name, isAddressResolving } = useAddressResolutionName(debouncedAddress, !isAddressName); + + const { address: resolvedAddress, isIdentityResolving } = useIdentityResolution(debouncedAddress, isAddressName); + + + const handleCanMessage = async () => { + if (!client) return; + try { + if (isAddressName && !!resolvedAddress) { + const res = await xmtpCanMessage(resolvedAddress); + setCanMessage(res) + } else { + if (debouncedAddress.length == 42) { + const res = await xmtpCanMessage(debouncedAddress); + setCanMessage(res) + } + } + } catch (e) { + console.log("error", e) + setCanMessage(false) + } + } + + + + const handleNewConversation = async (message: string) => { + if (!client) return; + const peerAddress = (isAddressName && !!resolvedAddress) ? resolvedAddress : debouncedAddress; + try { + const conv = await startConversation(peerAddress, message ?? {}) + if (!conv.cachedConversation) { + if (!conv.conversation) { return } + else { + const cachedConvo = toCachedConversation(conv.conversation, address ?? ''); + await allow([conv.conversation.peerAddress]); + await refreshConsentList(); + onChatStarted(cachedConvo) + } + } else { + await allow([conv.cachedConversation.peerAddress]); + await refreshConsentList(); + onChatStarted(conv.cachedConversation) + } + } catch (error) { + const e = error as Error; + console.log('error creating chat', e) + } + } + + const checkIfConversationExists = async (peerAddress: string) => { + const convoExists = await getCachedByPeerAddress(peerAddress); + if (convoExists) { + onChatStarted(convoExists) + } + } + + useEffect(() => { + if (!isLoading && !isIdentityResolving && debouncedAddress.length > 0) { + handleCanMessage(); + } else if (canMessage && debouncedAddress.length === 0) { + setCanMessage(false); + } + }, [debouncedAddress, isLoading, isIdentityResolving]); + + + + useEffect(() => { + if (canMessage) { + checkIfConversationExists((isAddressName && !!resolvedAddress) ? resolvedAddress : debouncedAddress); + } + }, [canMessage, resolvedAddress, debouncedAddress]) + + const isSearchLoading = useMemo(() => { + return ((isAddressName && isIdentityResolving) && debouncedAddress.length > 4) || isLoading; + }, [isLoading, debouncedAddress, resolvedAddress, isAddressName]) + + useEffect(() => { + + if (!isAddressResolving && !isIdentityResolving) { + return + } + + if (name) { + setNewAddress(name) + return + } + }, [name, isAddressResolving, isIdentityResolving]) + + return ( + + + + + + To

+ } + right={ + isSearchLoading ? + : + { + setNewAddress("") + }} /> + } + placeholder={'Subname, Wallet...'} + onChange={(e) => setNewAddress(e.target.value)} + + /> +
+ + + +
+ ); +}; + +export default NewConversation; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/NewMessageSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/NewMessageSheet/index.tsx new file mode 100644 index 00000000..33213d9e --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/NewMessageSheet/index.tsx @@ -0,0 +1,29 @@ +import { Sheet, SheetContent, SheetTitle } from '@justweb3/ui'; +import { CachedConversation } from '@xmtp/react-sdk'; +import NewConversation from '../NewConversation'; + +export interface MessageSheetProps { + openNewChat: boolean; + handleOpenNewChat: ( + open: boolean + ) => void; + onChatStarted: (conversation: CachedConversation) => void; +} + +export const NewMessageSheet: React.FC = ({ + handleOpenNewChat, + openNewChat, + onChatStarted +}) => { + return ( + !open && handleOpenNewChat(false)} + > + + New Conversation + handleOpenNewChat(false)} /> + + + ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx index 7fe843ae..0664a88b 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx @@ -1,16 +1,16 @@ +import { Flex, P, PauseIcon, PlayIcon } from '@justweb3/ui'; import * as Slider from '@radix-ui/react-slider'; import { DecodedMessage } from '@xmtp/xmtp-js'; -import { Flex, PauseIcon, PlayIcon } from '@justweb3/ui'; import React, { useEffect, useMemo, useRef, useState } from 'react'; -import { MessageWithReaction } from '../../utils/filterReactionsMessages'; import useGetAudioDuration from '../../hooks/useGetAudioDuration'; +import { MessageWithReaction } from '../../utils/filterReactionsMessages'; +import { formatTime } from '../../utils/formatVoiceTime'; interface VoiceMessageCardProps { message: MessageWithReaction | DecodedMessage; style?: React.CSSProperties; disabled?: boolean; isReceiver: boolean; - isReply?: boolean; } const VoiceMessageCard: React.FC = ({ @@ -18,7 +18,6 @@ const VoiceMessageCard: React.FC = ({ style, disabled, isReceiver, - isReply, }) => { const [playing, setPlaying] = useState(false); const [currentTime, setCurrentTime] = useState(0); @@ -116,9 +115,12 @@ const VoiceMessageCard: React.FC = ({ width="22" height="22" fill={ - isReceiver - ? 'var(--justweb3-primary-color)' - : 'var(--justweb3-foreground-color-4)' + disabled ? + 'var(--justweb3-primary-color)' + : + isReceiver + ? 'var(--justweb3-primary-color)' + : 'var(--justweb3-foreground-color-4)' } style={{ cursor: 'pointer', @@ -156,7 +158,7 @@ const VoiceMessageCard: React.FC = ({ > = ({ > = ({ style={{ width: '6px', height: '5px', - backgroundColor: isReceiver + background: isReceiver ? 'var(--justweb3-primary-color)' : 'var(--justweb3-foreground-color-4)', borderRadius: '2.5px', @@ -191,24 +193,16 @@ const VoiceMessageCard: React.FC = ({ aria-label="Volume" /> - {/**/} - {/*

{playing || currentTime > 0 ? formatTime(currentTime) : formatTime(duration ?? 0)}

*/} - {/* {!isReply && (*/} - {/*

{formatMessageSentTime(message.sentAt)}

*/} - {/* )}*/} - {/*
*/} + +

{playing || currentTime > 0 ? formatTime(currentTime) : formatTime(duration ?? 0)}

+ +
); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts index f61e9449..0d8c18f6 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts @@ -2,7 +2,9 @@ export * from './sendAttachment'; export * from './sendMessage'; export * from './sendReactionMessage'; export * from './sendReplyMessage'; +export * from './useAddressResolution'; export * from './useAttachmentChange'; export * from './useDebounced'; +export * from './useIdentityResolution'; export * from './useRecordingTimer'; export * from './useVoiceRecording'; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useAddressResolution/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useAddressResolution/index.ts new file mode 100644 index 00000000..72344758 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useAddressResolution/index.ts @@ -0,0 +1,72 @@ +import { addressResolution } from '@justaname.id/address-resolution'; +import { + getPrimaryNameParams, + useMountedAccount, + usePrimaryName, +} from '@justaname.id/react'; +import { ChainId } from '@justaname.id/sdk'; +import { useQuery } from '@tanstack/react-query'; + +export interface AddressResolutionResponse { + id: string; + name: string; + address: string; + nameHash: string; + chainId: number; +} + +export const buildAddressResolutionByAddressKey = (address: string) => [ + 'ADDRESS_RESOLUTION_BY_ADDRESS', + address, +]; +export const getAddressResolutionNameByAddress = async ( + address: string, + chainId: ChainId | undefined, + getPrimaryName: ( + params: getPrimaryNameParams, + force?: boolean + ) => Promise +): Promise => { + try { + const name = await addressResolution( + address, + // TODO: fix + process.env.NEXT_PUBLIC_PROVIDER_URL ?? '' + ); + if (!name) { + const backName = await getPrimaryName({ + address: address as `0x${string}`, + chainId, + }); + if (!!backName) { + return backName as string; + } else { + return null; + } + } else { + return name as string; + } + } catch (error) { + return null; + } +}; + +export const useAddressResolutionName = (address: string, isValid = true) => { + const { chainId } = useMountedAccount(); + const { getPrimaryName } = usePrimaryName(); + const query = useQuery({ + queryKey: buildAddressResolutionByAddressKey(address || ''), + queryFn: () => + getAddressResolutionNameByAddress( + address || '', + chainId as ChainId, + getPrimaryName + ), + enabled: address.length == 42 && isValid, + }); + return { + isAddressResolving: query.isPending, + name: query.data, + refetchAddressResolution: query.refetch, + }; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useIdentityResolution/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useIdentityResolution/index.ts new file mode 100644 index 00000000..f871bd94 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useIdentityResolution/index.ts @@ -0,0 +1,35 @@ +import { useQuery } from '@tanstack/react-query'; +import { ethers } from 'ethers'; + +export const buildIdentityResolutionByNameKey = (name: string) => [ + 'IDENTITY_RESOLUTION_BY_NAME', + name, +]; +export const getIdentityResolutionByName = async ( + name: string +): Promise => { + try { + const provider = new ethers.JsonRpcProvider( + process.env.NEXT_PUBLIC_PROVIDER_URL + ); + const address = await provider.resolveName(name); + return address; + } catch (e) { + console.log('error', e); + return null; + } +}; + +export const useIdentityResolution = (name: string, enabled: boolean) => { + const query = useQuery({ + queryKey: buildIdentityResolutionByNameKey(name), + queryFn: () => getIdentityResolutionByName(name), + enabled: enabled && name.length > 4, + }); + + return { + isIdentityResolving: query.isLoading, + address: query.data, + refetchIdentityResolution: query.refetch, + }; +}; diff --git a/yarn.lock b/yarn.lock index 25fd2303..b0c859c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4514,6 +4514,15 @@ __metadata: languageName: node linkType: hard +"@justaname.id/address-resolution@npm:^1.1.0": + version: 1.1.0 + resolution: "@justaname.id/address-resolution@npm:1.1.0" + peerDependencies: + ethers: 6.9.0 + checksum: 10c0/f8ffb6eb96ca7497aee179a9714dc45c0dd31fe4a1564eea9faf1b26ff689c58539a20568f17ec107dbdf4d298cf1f1e6593aff0aee24023caf1d07c42d5e263 + languageName: node + linkType: hard + "@justaname.id/react@npm:0.3.149, @justaname.id/react@workspace:packages/@justaname.id/react": version: 0.0.0-use.local resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" @@ -26681,6 +26690,7 @@ __metadata: "@hookform/error-message": "npm:^2.0.1" "@hookform/resolvers": "npm:^3.9.0" "@inquirer/prompts": "npm:^4.3.0" + "@justaname.id/address-resolution": "npm:^1.1.0" "@nx/cypress": "npm:19.7.3" "@nx/eslint": "npm:19.7.3" "@nx/eslint-plugin": "npm:19.7.3" From 1fb2493ee33d5fe8095525705df5afc208830951 Mon Sep 17 00:00:00 2001 From: anthony2399 Date: Tue, 3 Dec 2024 19:42:42 +0200 Subject: [PATCH 21/29] feat: added comment --- .../xmtp-plugin/src/lib/components/NewConversation/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx index 12cd9345..b780fef0 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx @@ -36,6 +36,7 @@ const NewConversation: React.FC = ({ value: debouncedAddress, } = useDebounced(newAddress, 500); + // TODO: change to regex const isAddressName = useMemo(() => { return !debouncedAddress.startsWith("0x") && !debouncedAddress.startsWith("0X") && debouncedAddress.length > 0; }, [debouncedAddress]) From bafad7b9c872ab3eeecbf9b79aec3a8750c67092 Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Wed, 4 Dec 2024 05:00:42 +0200 Subject: [PATCH 22/29] feat: compute height for message, using justaname react hook for identity resolution and sign in fix --- demo/server/src/main.ts | 6 + .../lib/hooks/primaryName/usePrimaryName.ts | 6 +- .../react/src/lib/hooks/signIn/useEnsAuth.ts | 1 + .../react/src/lib/hooks/signIn/useEnsNonce.ts | 22 +- .../src/lib/hooks/signIn/useEnsSignIn.ts | 53 +- .../src/lib/hooks/signIn/useEnsSignOut.ts | 5 +- .../src/stories/justverified.stories.tsx | 60 +- .../Profile/ContentSection/index.tsx | 38 +- .../src/lib/components/Chat/index.tsx | 124 +- .../src/lib/components/MessageCard/index.tsx | 1025 +++++++++------- .../src/lib/components/MessageItem/index.tsx | 37 +- .../lib/components/MessageTextField/index.tsx | 1037 ++++++++++------- .../lib/components/NewConversation/index.tsx | 383 +++--- .../xmtp-plugin/src/lib/hooks/index.ts | 10 +- .../lib/hooks/useAddressResolution/index.ts | 72 -- .../lib/hooks/useIdentityResolution/index.ts | 35 - .../index.ts | 0 .../{sendMessage => useSendMessage}/index.ts | 0 .../index.ts | 0 .../index.ts | 0 .../xmtp-plugin/src/stories/xmtp.stories.tsx | 35 +- yarn.lock | 10 + 22 files changed, 1653 insertions(+), 1306 deletions(-) delete mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/useAddressResolution/index.ts delete mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/useIdentityResolution/index.ts rename packages/@justweb3/xmtp-plugin/src/lib/hooks/{sendAttachment => useSendAttachment}/index.ts (100%) rename packages/@justweb3/xmtp-plugin/src/lib/hooks/{sendMessage => useSendMessage}/index.ts (100%) rename packages/@justweb3/xmtp-plugin/src/lib/hooks/{sendReactionMessage => useSendReactionMessage}/index.ts (100%) rename packages/@justweb3/xmtp-plugin/src/lib/hooks/{sendReplyMessage => useSendReplyMessage}/index.ts (100%) diff --git a/demo/server/src/main.ts b/demo/server/src/main.ts index b3d71883..06f75887 100644 --- a/demo/server/src/main.ts +++ b/demo/server/src/main.ts @@ -68,9 +68,15 @@ app.post('/api/signin', async (req: Request, res) => { return; } + if (!req.session.nonce) { + res.status(401).json({ message: 'No nonce found.' }); + return; + } + const { data: message, ens } = await justaname.signIn.signIn({ message: req.body.message, signature: req.body.signature, + nonce: req.session.nonce, }); if (!message) { diff --git a/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts b/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts index c901ae1d..594082b5 100644 --- a/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts +++ b/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts @@ -13,7 +13,7 @@ export const buildPrimaryName = ( ) => ['PRIMARY_NAME', address, chainId]; export interface UsePrimaryNameParams { - address?: Address; + address?: string; chainId?: ChainId; enabled?: boolean; } @@ -72,7 +72,7 @@ export const usePrimaryName = ( throw new Error('Address is required'); } return getName(ensClient, { - address: params?.address, + address: params?.address as Address, }); }; @@ -115,7 +115,7 @@ export const usePrimaryName = ( queryKey: buildPrimaryName(params?.address || '', _chainId), queryFn: () => getPrimaryName({ - address: params?.address, + address: params?.address as Address, }), enabled: Boolean(params?.address) && Boolean(ensClient) && Boolean(_enabled), diff --git a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsAuth.ts b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsAuth.ts index 9a052b3a..24707001 100644 --- a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsAuth.ts +++ b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsAuth.ts @@ -47,6 +47,7 @@ export const useEnsAuth = ( () => _backendUrl + _currentEnsRoute, [_backendUrl, _currentEnsRoute] ); + const query = useQuery({ ...defaultOptions, retry: 0, diff --git a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsNonce.ts b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsNonce.ts index def93b8c..314d3a86 100644 --- a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsNonce.ts +++ b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsNonce.ts @@ -1,7 +1,12 @@ import { useMemo } from 'react'; import { useJustaName } from '../../providers'; -import { useQuery } from '@tanstack/react-query'; +import { + QueryObserverResult, + RefetchOptions, + useQuery, +} from '@tanstack/react-query'; import { defaultOptions } from '../../query'; +import { useMountedAccount } from '../account'; export const buildNonceKey = ( backendUrl: string, @@ -12,13 +17,15 @@ export const buildNonceKey = ( export interface UseEnsNonceParams { signinNonceRoute?: string; backendUrl?: string; - address?: string; + // address?: string; enabled?: boolean; } export interface UseEnsNonceResult { nonce: string | undefined; - refetchNonce: () => void; + refetchNonce: ( + options?: RefetchOptions | undefined + ) => Promise>; isNoncePending: boolean; isNonceLoading: boolean; isNonceFetching: boolean; @@ -26,6 +33,7 @@ export interface UseEnsNonceResult { export const useEnsNonce = (params?: UseEnsNonceParams): UseEnsNonceResult => { const { backendUrl, routes } = useJustaName(); + const { address } = useMountedAccount(); const _enabled = params?.enabled !== undefined ? params.enabled : true; const _backendUrl = useMemo( () => params?.backendUrl || backendUrl || '', @@ -44,11 +52,7 @@ export const useEnsNonce = (params?: UseEnsNonceParams): UseEnsNonceResult => { ...defaultOptions, retry: 0, staleTime: Infinity, - queryKey: buildNonceKey( - _backendUrl, - _signinNonceRoute, - params?.address || '' - ), + queryKey: buildNonceKey(_backendUrl, _signinNonceRoute, address || ''), queryFn: async () => { const nonceResponse = await fetch(nonceEndpoint, { credentials: 'include', @@ -60,7 +64,7 @@ export const useEnsNonce = (params?: UseEnsNonceParams): UseEnsNonceResult => { return nonceResponse.text(); }, - enabled: Boolean(params?.address) && Boolean(_enabled), + enabled: Boolean(address) && Boolean(_enabled), }); return { diff --git a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignIn.ts b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignIn.ts index 906b7f51..a076079d 100644 --- a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignIn.ts +++ b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignIn.ts @@ -57,6 +57,10 @@ export const useEnsSignIn = ( () => params?.currentEnsRoute || routes.currentEnsRoute, [routes.currentEnsRoute, params?.currentEnsRoute] ); + const _signinNonceRoute = useMemo( + () => params?.signinNonceRoute || routes.signinNonceRoute, + [routes.signinNonceRoute, params?.signinNonceRoute] + ); const { refreshEnsAuth } = useEnsAuth({ backendUrl: _backendUrl, currentEnsRoute: _currentEnsRoute, @@ -64,38 +68,37 @@ export const useEnsSignIn = ( }); const { nonce, refetchNonce } = useEnsNonce({ - backendUrl: params?.backendUrl, - signinNonceRoute: params?.signinNonceRoute, - address, + backendUrl: _backendUrl, + signinNonceRoute: _signinNonceRoute, enabled: !params?.local, }); const mutation = useMutation({ mutationFn: async (_params: UseEnsSignInFunctionParams) => { - if (!address) { - throw new Error('No address found'); - } + try { + if (!address) { + throw new Error('No address found'); + } - if (params?.local) { - localStorage.setItem( - 'ENS_AUTH', - JSON.stringify({ - ens: _params.ens, - chainId, - address, - }) - ); + if (params?.local) { + localStorage.setItem( + 'ENS_AUTH', + JSON.stringify({ + ens: _params.ens, + chainId, + address, + }) + ); - refreshEnsAuth(); + refreshEnsAuth(); - return 'success'; - } + return 'success'; + } - if (!nonce) { - throw new Error('No nonce found'); - } + if (!nonce) { + throw new Error('No nonce found'); + } - try { const message = justaname.signIn.requestSignIn({ ens: _params.ens, ttl: config?.signInTtl, @@ -123,11 +126,15 @@ export const useEnsSignIn = ( credentials: 'include', }); + if (response.status !== 200) { + throw new Error('Failed to sign in'); + } + refreshEnsAuth(); return response.text(); } catch (e) { - refetchNonce(); + await refetchNonce(); throw e; } }, diff --git a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignOut.ts b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignOut.ts index 29a43c19..34cd468b 100644 --- a/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignOut.ts +++ b/packages/@justaname.id/react/src/lib/hooks/signIn/useEnsSignOut.ts @@ -44,7 +44,7 @@ export const useEnsSignOut = ( [routes.signinNonceRoute, params?.signinNonceRoute] ); - const { refreshEnsAuth, connectedEns } = useEnsAuth({ + const { refreshEnsAuth } = useEnsAuth({ backendUrl: _backendUrl, currentEnsRoute: _currentEnsRoute, local: params?.local, @@ -53,7 +53,6 @@ export const useEnsSignOut = ( const { refetchNonce } = useEnsNonce({ backendUrl: _backendUrl, signinNonceRoute: _signinNonceRoute, - address: connectedEns?.address, enabled: !params?.local, }); @@ -70,8 +69,8 @@ export const useEnsSignOut = ( credentials: 'include', }); + await refetchNonce(); refreshEnsAuth(); - refetchNonce(); }, }); diff --git a/packages/@justverified/plugin/src/stories/justverified.stories.tsx b/packages/@justverified/plugin/src/stories/justverified.stories.tsx index e541a041..d3074875 100644 --- a/packages/@justverified/plugin/src/stories/justverified.stories.tsx +++ b/packages/@justverified/plugin/src/stories/justverified.stories.tsx @@ -11,7 +11,6 @@ import { ChainId } from '@justaname.id/sdk'; import { Meta, StoryObj } from '@storybook/react'; import { Button } from '@justweb3/ui'; import { - JustEnsCard, JustWeb3Button, JustWeb3Provider, JustWeb3ProviderConfig, @@ -19,6 +18,7 @@ import { } from '@justweb3/widget'; import '@justweb3/widget/styles.css'; import { JustVerifiedPlugin } from '../lib'; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; const queryClient = new QueryClient(); @@ -47,13 +47,14 @@ const JustWeb3Config: JustWeb3ProviderConfig = { ], openOnWalletConnect: true, allowedEns: 'all', - dev: import.meta.env.STORYBOOK_APP_DEV === 'true', + // dev: import.meta.env.STORYBOOK_APP_DEV === 'true', disableOverlay: true, + // enableAuth: true, plugins: [ JustVerifiedPlugin( - ['twitter', 'github', 'discord'], + ['twitter', 'github', 'discord'] // 'http://localhost:3009/verifications/v1' - 'https://api-staging.justaname.id/verifications/v1' + // 'https://api-staging.justaname.id/verifications/v1' ), ], }; @@ -110,35 +111,36 @@ export const Example = () => {
- + {/**/} -
- - - - - - - -
-
- - - - - - -
+ {/*
*/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/*
*/} + {/*
*/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/*
*/}
+ ); diff --git a/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx b/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx index 30394ddc..de020496 100644 --- a/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx @@ -24,6 +24,10 @@ import { TabsContent, TabsList, TabsTrigger, + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, } from '@justweb3/ui'; import React, { Fragment, useContext, useEffect, useMemo } from 'react'; import { getChainIcon } from '../../../icons/chain-icons'; @@ -191,13 +195,33 @@ const ContentSection: React.FC = ({ title={'Addresses'} items={sanitized?.allAddresses?.map((address) => { return ( - + + + +
+ +
+
+ +

+ {address.symbol.toUpperCase()}: {address.value} +

+
+
+
); })} /> diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx index 84855c4d..f497e3ed 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx @@ -23,7 +23,7 @@ import { useCanMessage, useConsent, useMessages, - useStreamMessages + useStreamMessages, } from '@xmtp/react-sdk'; import React, { useEffect, useMemo } from 'react'; import { useSendReactionMessage } from '../../hooks'; @@ -152,6 +152,35 @@ export const Chat: React.FC = ({ conversation, onBack }) => { // await checkMessageIfRead(); }, [messages, conversation]); + const isStringContent = + typeof replyMessage?.content === 'string' || + typeof replyMessage?.content?.content === 'string'; + + const mimeType = replyMessage?.content?.mimeType; + const type = mimeType ? typeLookup[mimeType.split('/')?.[1]] : null; + + const computeHeight = useMemo(() => { + const additionalHeight = []; + const height = '100vh - 50px - 3rem - 1.5rem - 73px - 15px'; + if (replyMessage) { + if (isStringContent) { + additionalHeight.push('46px'); + } else if (mimeType === 'audio/wav') { + additionalHeight.push('61px'); + } else if (type === 'video' || type === 'image') { + additionalHeight.push('116px'); + } + } + + if (isMessagesSenderOnly) { + additionalHeight.push('59px'); + } + + return `calc( ${height} ${ + additionalHeight.length > 0 ? ' - ' + additionalHeight.join(' - ') : '' + } )`; + }, [replyMessage, isMessagesSenderOnly, isStringContent, mimeType, type]); + return ( = ({ conversation, onBack }) => { src={ primaryName ? sanitizeEnsImage({ - name: primaryName, - chainId: 1, - image: records?.sanitizedRecords?.avatar, - }) + name: primaryName, + chainId: 1, + image: records?.sanitizedRecords?.avatar, + }) : undefined } style={{ @@ -338,9 +367,9 @@ export const Chat: React.FC = ({ conversation, onBack }) => { gap="5px" style={{ flex: 1, - padding: '10px 10px', - minHeight: 'calc(100vh - 200px)', - maxHeight: 'calc(100vh - 200px)', + // padding: '10px 10px', + minHeight: computeHeight, + maxHeight: computeHeight, }} > {[...Array(8)].map((_, index) => ( @@ -354,28 +383,8 @@ export const Chat: React.FC = ({ conversation, onBack }) => { {canMessage ? ( @@ -395,15 +404,23 @@ export const Chat: React.FC = ({ conversation, onBack }) => { {groupedMessages && Object.keys(groupedMessages).map((date, index) => ( - -
+ +

= ({ conversation, onBack }) => { > {date}

-
+
{groupedMessages[date].map((message) => ( = ({ conversation, onBack }) => { style={{ padding: '10px', borderRadius: '10px', - backgroundColor: 'var(--justweb3-foreground-color-4)' + backgroundColor: 'var(--justweb3-foreground-color-4)', }} >

= ({ conversation, onBack }) => { fontSize: '14px', fontWeight: 900, lineHeight: '100%', - color: 'black' + color: 'black', }} > Message in user’s Requests

-

This user has not accepted your message request yet

+

+ This user has not accepted your message request yet +

)} void; - // onReaction: (message: DecodedMessage) => void; - onReply: (message: MessageWithReaction) => void; - onReaction: (message: MessageWithReaction) => void; + message: MessageWithReaction; + conversation: CachedConversation; + peerAddress: string; + // onReply: (message: DecodedMessage) => void; + // onReaction: (message: DecodedMessage) => void; + onReply: (message: MessageWithReaction) => void; + onReaction: (message: MessageWithReaction) => void; } -const MeasureAndHyphenateText: React.FC<{ text: string; maxWidth: number, isReceiver: boolean }> = ({ text, maxWidth, isReceiver }) => { - const [processedText, setProcessedText] = useState(''); - - useEffect(() => { - // Function to measure text width - const measureText = (text = '', font = '10px Inter') => { - const canvas = document.createElement('canvas'); - const context = canvas.getContext('2d'); - if (!context) return 0; - context.font = font; - return context.measureText(text).width; - }; - - // Function to insert hyphens - const insertHyphens = (text: string) => { - const words = text.split(' '); - let currentLine = ''; - let finalText = ''; - - words.forEach((word) => { - const testLine = currentLine + word + ' '; - const testLineWidth = measureText(testLine); - - if (testLineWidth > maxWidth && currentLine !== '') { - // Check if it's necessary to hyphenate the current word - let hyphenated = false; - for (let i = word.length; i > 0; i--) { - const part = word.substring(0, i); - const testPartWidth = measureText(currentLine + part + '-'); - - if (testPartWidth <= maxWidth) { - finalText += currentLine + part + '-\n'; - currentLine = word.substring(i) + ' '; - hyphenated = true; - break; - } - } - - if (!hyphenated) { - finalText += currentLine + '\n'; - currentLine = word + ' '; - } - } else { - currentLine = testLine; - } - }); - - finalText += currentLine; - return finalText; - }; - - // Process the text - const processed = insertHyphens(text); - setProcessedText(processed); - }, [text, maxWidth]); - - return ( -
-            {processedText}
-        
- ); +const MeasureAndHyphenateText: React.FC<{ + text: string; + maxWidth: number; + isReceiver: boolean; +}> = ({ text, maxWidth, isReceiver }) => { + const [processedText, setProcessedText] = useState(''); + + useEffect(() => { + // Function to measure text width + const measureText = (text = '', font = '10px Inter') => { + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + if (!context) return 0; + context.font = font; + return context.measureText(text).width; + }; + + // Function to insert hyphens + const insertHyphens = (text: string) => { + const words = text.split(' '); + let currentLine = ''; + let finalText = ''; + + words.forEach((word) => { + const testLine = currentLine + word + ' '; + const testLineWidth = measureText(testLine); + + if (testLineWidth > maxWidth && currentLine !== '') { + // Check if it's necessary to hyphenate the current word + let hyphenated = false; + for (let i = word.length; i > 0; i--) { + const part = word.substring(0, i); + const testPartWidth = measureText(currentLine + part + '-'); + + if (testPartWidth <= maxWidth) { + finalText += currentLine + part + '-\n'; + currentLine = word.substring(i) + ' '; + hyphenated = true; + break; + } + } + + if (!hyphenated) { + finalText += currentLine + '\n'; + currentLine = word + ' '; + } + } else { + currentLine = testLine; + } + }); + + finalText += currentLine; + return finalText; + }; + + // Process the text + const processed = insertHyphens(text); + setProcessedText(processed); + }, [text, maxWidth]); + + return ( +
+      {processedText}
+    
+ ); }; const MessageCard: React.FC = ({ - message, - peerAddress, - onReply, - conversation, - onReaction + message, + peerAddress, + onReply, + conversation, + onReaction, }) => { - const { address } = useMountedAccount(); - const [hovered, setHovered] = useState(false) - const [repliedMessage, setRepliedMessage] = React.useState(null); - const divRef = useRef(null); - const { mutateAsync: sendReaction } = useSendReactionMessage(conversation); - - const { primaryName } = usePrimaryName({ - address: peerAddress as `0x${string}`, - }); - - const isText = useMemo(() => { - return typeof message.content === "string" - }, [message.content]) - - - useEffect(() => { - function handleMouseEnter() { - setHovered(true) - } - function handleMouseLeave() { - setHovered(false) - } - const divElement = divRef.current; - if (divElement) { - divElement.addEventListener('mouseenter', handleMouseEnter); - divElement.addEventListener('mouseleave', handleMouseLeave); - } - return () => { - if (divElement) { - divElement.removeEventListener('mouseenter', handleMouseEnter); - divElement.removeEventListener('mouseleave', handleMouseLeave); - } - }; - }, []); - - - const attachmentExtention = useMemo(() => { - if (!isText && message.content.mimeType) - return message.content.mimeType.split("/")?.[1] || ""; - }, [isText, message.content.mimeType]); - - - const isImage = message.content && message.content.data; - const isReply = message.content && message.contentType === "xmtp.org/reply:1.0" - const isReceiver = message.senderAddress === peerAddress; - const isVoice = message.content.mimeType === "audio/wav"; - - - const getMessageDataById = (messageId: string) => { - const messageElement = document.getElementById(messageId); - if (!messageElement) { - return null; - } - - const messageDataString = messageElement.getAttribute('data-message'); - if (!messageDataString) { - return null; - } - try { - const messageData = JSON.parse(messageDataString); - return messageData; - } catch (e) { - console.error('Failed to parse message data:', e); - return null; - } + const { address } = useMountedAccount(); + const [hovered, setHovered] = useState(false); + const [repliedMessage, setRepliedMessage] = + React.useState(null); + const divRef = useRef(null); + const { mutateAsync: sendReaction } = useSendReactionMessage(conversation); + + const { primaryName } = usePrimaryName({ + address: peerAddress as `0x${string}`, + }); + + const isText = useMemo(() => { + return typeof message.content === 'string'; + }, [message.content]); + + useEffect(() => { + function handleMouseEnter() { + setHovered(true); } - - const handleEmojiSelect = (emoji: string, action: "added" | "removed") => { - sendReaction({ - action: action, - content: emoji, - referenceId: message.id, - }); + function handleMouseLeave() { + setHovered(false); } - - const navigateToRepliedMessage = () => { - if (!repliedMessage) return; - const element = document.getElementById(repliedMessage.id); - if (element) { - element.scrollIntoView({ behavior: "smooth", block: "center" }); - } + const divElement = divRef.current; + if (divElement) { + divElement.addEventListener('mouseenter', handleMouseEnter); + divElement.addEventListener('mouseleave', handleMouseLeave); + } + return () => { + if (divElement) { + divElement.removeEventListener('mouseenter', handleMouseEnter); + divElement.removeEventListener('mouseleave', handleMouseLeave); + } + }; + }, []); + + const attachmentExtention = useMemo(() => { + if (!isText && message.content.mimeType) + return message.content.mimeType.split('/')?.[1] || ''; + }, [isText, message.content.mimeType]); + + const isImage = message.content && message.content.data; + const isReply = + message.content && message.contentType === 'xmtp.org/reply:1.0'; + const isReceiver = message.senderAddress === peerAddress; + const isVoice = message.content.mimeType === 'audio/wav'; + + const getMessageDataById = (messageId: string) => { + const messageElement = document.getElementById(messageId); + if (!messageElement) { + return null; } + const messageDataString = messageElement.getAttribute('data-message'); + if (!messageDataString) { + return null; + } + try { + const messageData = JSON.parse(messageDataString); + return messageData; + } catch (e) { + console.error('Failed to parse message data:', e); + return null; + } + }; - const isReplyVoice = useMemo(() => { - if (!repliedMessage) return false; - return repliedMessage.content.mimeType === "audio/wav"; - }, [repliedMessage]); - - const isReplyText = useMemo(() => { - if (!repliedMessage) return false; - return typeof repliedMessage.content === "string" - }, [repliedMessage]) - - const isReplyReply = useMemo(() => { - if (!repliedMessage) return false; - return !!repliedMessage.content.reference - }, [repliedMessage]) - - const replyAttachmentExtention = useMemo(() => { - if (!isReplyText && !!repliedMessage && !isReplyReply) - return repliedMessage.content.mimeType.split("/")?.[1] || ""; - }, [isReplyText, repliedMessage]); - - useEffect(() => { - if (!isReply || !!repliedMessage) return; - const repliedMsg = getMessageDataById(message.content.reference) - setRepliedMessage(repliedMsg); - }, [isReply, message.content.reference, repliedMessage]) + const handleEmojiSelect = (emoji: string, action: 'added' | 'removed') => { + sendReaction({ + action: action, + content: emoji, + referenceId: message.id, + }); + }; - return ( - - + const navigateToRepliedMessage = () => { + if (!repliedMessage) return; + const element = document.getElementById(repliedMessage.id); + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + }; + + const isReplyVoice = useMemo(() => { + if (!repliedMessage) return false; + return repliedMessage.content.mimeType === 'audio/wav'; + }, [repliedMessage]); + + const isReplyText = useMemo(() => { + if (!repliedMessage) return false; + return typeof repliedMessage.content === 'string'; + }, [repliedMessage]); + + const isReplyReply = useMemo(() => { + if (!repliedMessage) return false; + return !!repliedMessage.content.reference; + }, [repliedMessage]); + + const replyAttachmentExtention = useMemo(() => { + if (!isReplyText && !!repliedMessage && !isReplyReply) + return repliedMessage.content.mimeType.split('/')?.[1] || ''; + }, [isReplyReply, isReplyText, repliedMessage]); + + useEffect(() => { + if (!isReply || !!repliedMessage) return; + const repliedMsg = getMessageDataById(message.content.reference); + setRepliedMessage(repliedMsg); + }, [isReply, message.content.reference, repliedMessage]); + + return ( + + + + <> + {repliedMessage && isReply ? ( + + - <> - { - repliedMessage && isReply ? - - - - -

{repliedMessage?.senderAddress === address ? "YOU" : primaryName ?? formatAddress(repliedMessage?.senderAddress ?? "")}

- - {(isReplyText || isReplyReply) ? ( -

{isReplyReply ? repliedMessage.content.content : repliedMessage.content}

- ) : ( - isReplyVoice ? - - : - typeLookup[replyAttachmentExtention] === "image" ? - {repliedMessage.content.filename} - : - typeLookup[replyAttachmentExtention] === "video" ? - - : - - -

{repliedMessage.content.filename}

-
- )} -
-
-
-

{message.content.content}

-
-
-
- : - isText ? - - - - : - - {isVoice ? - - : - - {typeLookup[attachmentExtention] === "image" ? -
- {message.content.filename} - - -
- : - typeLookup[attachmentExtention] === "video" ? - - : - - - -

{message.content.filename}

-

{calculateFileSize(message.content.data?.byteLength ?? 0)}

-
-
} -
} -
- } - {message.reactionMessage && ( -

{ - if (!message.reactionMessage) return; - if (message.reactionMessage.senderAddress !== address) return; - handleEmojiSelect("", "removed") - }} - style={{ - position: 'absolute', - cursor: 'pointer', - bottom: '-0.5rem', - fontSize: '20px', - right: isReceiver ? '-12px' : 'auto', - left: isReceiver ? 'auto' : '-12px', - }} - >{findEmojiByName(message.reactionMessage.content.content)}

- )} - - -
- - - onReply(message)} /> - - {message.senderAddress !== address && - { - onReaction(message) - } - } /> - } - + onClick={navigateToRepliedMessage} + > + +

+ {repliedMessage?.senderAddress === address + ? 'YOU' + : primaryName ?? + formatAddress(repliedMessage?.senderAddress ?? '')} +

+ + {isReplyText || isReplyReply ? ( +

+ {isReplyReply + ? repliedMessage.content.content + : repliedMessage.content} +

+ ) : isReplyVoice ? ( + + ) : typeLookup[replyAttachmentExtention] === 'image' ? ( + {repliedMessage.content.filename} + ) : typeLookup[replyAttachmentExtention] === 'video' ? ( + + ) : ( + + +

+ {repliedMessage.content.filename} +

+
+ )} +
+
+
+

+ {message.content.content} +

+
-
-

{formatMessageSentTime(message.sentAt)}

-
- ); +
+ ) : isText ? ( + + + + ) : ( + + {isVoice ? ( + + ) : ( + + {typeLookup[attachmentExtention] === 'image' ? ( +
+ {message.content.filename} + + + +
+ ) : typeLookup[attachmentExtention] === 'video' ? ( + + ) : ( + + + +

+ {message.content.filename} +

+

+ {calculateFileSize( + message.content.data?.byteLength ?? 0 + )} +

+
+
+ )} +
+ )} +
+ )} + {message.reactionMessage && ( +

{ + if (!message.reactionMessage) return; + if (message.reactionMessage.senderAddress !== address) return; + handleEmojiSelect('', 'removed'); + }} + style={{ + position: 'absolute', + cursor: 'pointer', + bottom: '-0.5rem', + fontSize: '20px', + right: isReceiver ? '-12px' : 'auto', + left: isReceiver ? 'auto' : '-12px', + }} + > + {findEmojiByName(message.reactionMessage.content.content)} +

+ )} + +
+ + + onReply(message)} + /> + + {message.senderAddress !== address && ( + { + onReaction(message); + }} + /> + )} + +
+

+ {formatMessageSentTime(message.sentAt)} +

+
+ ); }; export default MessageCard; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx index 0fc4ec87..816ee169 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx @@ -22,7 +22,7 @@ export interface MessageItemProps { export const MessageItem: React.FC = ({ conversation, onClick, - blocked + blocked, }) => { const lastMessage = useLastMessage(conversation.topic); useStreamMessages(conversation); @@ -34,13 +34,13 @@ export const MessageItem: React.FC = ({ }); const { sanitizeEnsImage } = useEnsAvatar(); - const { allow, refreshConsentList } = useConsent() + const { allow, refreshConsentList } = useConsent(); const allowUser = async () => { - await refreshConsentList() - await allow([conversation.peerAddress]) - await refreshConsentList() - } + await refreshConsentList(); + await allow([conversation.peerAddress]); + await refreshConsentList(); + }; const lastContent = useMemo(() => { if (!lastMessage) return ''; @@ -76,23 +76,23 @@ export const MessageItem: React.FC = ({ { - if (blocked) return - onClick && onClick() + if (blocked) return; + onClick && onClick(); }} > @@ -139,14 +139,15 @@ export const MessageItem: React.FC = ({ textAlign: 'end', }} > - {blocked ? - - : + {blocked ? ( + + ) : ( {lastMessage?.sentAt ? formatChatDate(lastMessage.sentAt) : ''} - } + )} ); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx index 09c03549..4909da6b 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx @@ -1,473 +1,642 @@ - import type { Attachment } from '@xmtp/content-type-remote-attachment'; import { CachedConversation, useClient } from '@xmtp/react-sdk'; -import React, { Dispatch, SetStateAction, useEffect, useMemo, useRef, useState } from 'react'; +import React, { + Dispatch, + SetStateAction, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; import { MessageWithReaction } from '../../utils/filterReactionsMessages'; import { useMountedAccount, usePrimaryName } from '@justaname.id/react'; -import { useAttachmentChange, useRecordingTimer, useRecordVoice, useSendAttachment, useSendMessages, useSendReplyMessage } from '../../hooks'; +import { + useAttachmentChange, + useRecordingTimer, + useRecordVoice, + useSendAttachment, + useSendMessages, + useSendReplyMessage, +} from '../../hooks'; import { AttachmentType, typeLookup } from '../../utils/attachments'; -import { Button, CloseIcon, Flex, Input, LoadingSpinner, P, AddImageIcon, AddVideoIcon, AddFolderIcon, DocumentIcon, SendIcon, StopIcon, MicIcon } from '@justweb3/ui'; +import { + AddFolderIcon, + AddImageIcon, + AddVideoIcon, + Button, + CloseIcon, + DocumentIcon, + Flex, + Input, + LoadingSpinner, + MicIcon, + P, + SendIcon, + StopIcon, +} from '@justweb3/ui'; import { formatAddress } from '../../utils/formatAddress'; import VoiceMessageCard from '../VoiceMessageCard'; import { CustomPlayer } from '../CustomPlayer'; import CustomVoicePreview from '../CustomVoicePreview'; - interface MessageTextFieldProps { - newConvo?: boolean; - disabled?: boolean; - conversation?: CachedConversation; - replyMessage?: MessageWithReaction | null; - onCancelReply?: () => void; - onNewConvo?: (message: string) => void; - peerAddress?: string; + newConvo?: boolean; + disabled?: boolean; + conversation?: CachedConversation; + replyMessage?: MessageWithReaction | null; + onCancelReply?: () => void; + onNewConvo?: (message: string) => void; + peerAddress?: string; } const MessageTextField: React.FC = ({ - newConvo, - disabled, - replyMessage, - onCancelReply, - conversation, - onNewConvo, - peerAddress + newConvo, + disabled, + replyMessage, + onCancelReply, + conversation, + onNewConvo, + peerAddress, }) => { - const [messageValue, setMessageValue] = React.useState(""); - const [attachment, setAttachment] = React.useState(); - const [attachmentPreview, setAttachmentPreview] = React.useState(); - const [isNewMessageLoading, setIsNewMessageLoading] = React.useState(false); - // const [selectingAttachment, setSelectingAttachment] = React.useState(false); - const { client } = useClient(); - const { address } = useMountedAccount(); - const { mutateAsync: sendMessage } = useSendMessages(conversation); - const { mutateAsync: sendReply } = useSendReplyMessage(conversation); - const { mutateAsync: sendAttachment } = useSendAttachment(conversation); + const [messageValue, setMessageValue] = React.useState(''); + const [attachment, setAttachment] = React.useState(); + const [attachmentPreview, setAttachmentPreview] = React.useState< + string | undefined + >(); + const [isNewMessageLoading, setIsNewMessageLoading] = + React.useState(false); + // const [selectingAttachment, setSelectingAttachment] = React.useState(false); + const { client } = useClient(); + const { address } = useMountedAccount(); + const { mutateAsync: sendMessage } = useSendMessages(conversation); + const { mutateAsync: sendReply } = useSendReplyMessage(conversation); + const { mutateAsync: sendAttachment } = useSendAttachment(conversation); - const attachmentExtention = useMemo(() => { - return attachment?.mimeType.split("/")?.[1] || ""; - }, [attachment]); + const attachmentExtention = useMemo(() => { + return attachment?.mimeType.split('/')?.[1] || ''; + }, [attachment]); - const { primaryName } = usePrimaryName({ - address: peerAddress as `0x${string}`, - }); + const { primaryName } = usePrimaryName({ + address: peerAddress as `0x${string}`, + }); - // Attachments - const [acceptedTypes, setAcceptedTypes]: [ - string | string[] | undefined, - Dispatch>, - ] = useState(); - const inputFile = useRef(null); - const { onAttachmentChange } = useAttachmentChange({ - setAttachment, - setAttachmentPreview, - onError: (error) => { - // showToast("error", error); - } - }); + // Attachments + const [acceptedTypes, setAcceptedTypes]: [ + string | string[] | undefined, + Dispatch> + ] = useState(); + const inputFile = useRef(null); + const { onAttachmentChange } = useAttachmentChange({ + setAttachment, + setAttachmentPreview, + onError: (error) => { + // showToast("error", error); + }, + }); - // Recording - const { recording, startRecording, stopRecording } = useRecordVoice({ - setAttachment, - setAttachmentPreview, - }) - const { start, pause, reset, recordingValue } = useRecordingTimer({ - stopRecording, - status: recording ? "recording" : "idle", - }); + // Recording + const { recording, startRecording, stopRecording } = useRecordVoice({ + setAttachment, + setAttachmentPreview, + }); + const { start, pause, reset, recordingValue } = useRecordingTimer({ + stopRecording, + status: recording ? 'recording' : 'idle', + }); - // Sending text message - const handleSendMessage = async () => { - if (messageValue.length === 0) return; - if (!client) return; - if (disabled) return; - if (newConvo) { - setIsNewMessageLoading(true); - onNewConvo && onNewConvo(messageValue); - setIsNewMessageLoading(false); - } else { - if (replyMessage) { - sendReply({ - message: messageValue, - referenceId: replyMessage.id, - }) - onCancelReply && onCancelReply(); - } else { - sendMessage(messageValue); - } - } - setMessageValue(''); + // Sending text message + const handleSendMessage = async () => { + if (messageValue.length === 0) return; + if (!client) return; + if (disabled) return; + if (newConvo) { + setIsNewMessageLoading(true); + onNewConvo && onNewConvo(messageValue); + setIsNewMessageLoading(false); + } else { + if (replyMessage) { + sendReply({ + message: messageValue, + referenceId: replyMessage.id, + }); + onCancelReply && onCancelReply(); + } else { + sendMessage(messageValue); + } } + setMessageValue(''); + }; - // Sending attachment - const handleSendAttachment = async () => { - if (!client) return; - if (!attachment) return; - if (disabled) return; - if (newConvo) { - onNewConvo && onNewConvo(messageValue); - } else { - sendAttachment(attachment); - } - setMessageValue(''); - setAttachment(undefined); - setAttachmentPreview(undefined); - // setSelectingAttachment(false); + // Sending attachment + const handleSendAttachment = async () => { + if (!client) return; + if (!attachment) return; + if (disabled) return; + if (newConvo) { + onNewConvo && onNewConvo(messageValue); + } else { + sendAttachment(attachment); } + setMessageValue(''); + setAttachment(undefined); + setAttachmentPreview(undefined); + // setSelectingAttachment(false); + }; - const handleCancelAttachment = () => { - setAttachment(undefined); - setAttachmentPreview(undefined); - } + const handleCancelAttachment = () => { + setAttachment(undefined); + setAttachmentPreview(undefined); + }; - const onButtonClick = (contentType: AttachmentType) => { - if (contentType === "application") { - setAcceptedTypes("all"); - } else { - const acceptedFileTypeList = Object.keys(typeLookup).reduce( - (acc: string[], key: string) => { - if (typeLookup[key] === contentType) acc.push(`.${key}`); - return acc; - }, - [], - ); - setAcceptedTypes([...acceptedFileTypeList]); - } - }; + const onButtonClick = (contentType: AttachmentType) => { + if (contentType === 'application') { + setAcceptedTypes('all'); + } else { + const acceptedFileTypeList = Object.keys(typeLookup).reduce( + (acc: string[], key: string) => { + if (typeLookup[key] === contentType) acc.push(`.${key}`); + return acc; + }, + [] + ); + setAcceptedTypes([...acceptedFileTypeList]); + } + }; - // Reply message - const isSender = useMemo(() => { return address === replyMessage?.senderAddress }, [replyMessage, address]); - const isReplyVoice = useMemo(() => { - return replyMessage?.content.mimeType === "audio/wav"; - }, [replyMessage]); + // Reply message + const isSender = useMemo(() => { + return address === replyMessage?.senderAddress; + }, [replyMessage, address]); + const isReplyVoice = useMemo(() => { + return replyMessage?.content.mimeType === 'audio/wav'; + }, [replyMessage]); - const isReplyText = useMemo(() => { - if (!replyMessage) return false; - return typeof replyMessage.content === "string" - }, [replyMessage]) + const isReplyText = useMemo(() => { + if (!replyMessage) return false; + return typeof replyMessage.content === 'string'; + }, [replyMessage]); - const isReplyReply = useMemo(() => { - if (!replyMessage) return false; - return !!replyMessage.content.reference; - }, [replyMessage]); + const isReplyReply = useMemo(() => { + if (!replyMessage) return false; + return !!replyMessage.content.reference; + }, [replyMessage]); - const replyAttachmentExtention = useMemo(() => { - if (!isReplyText && !!replyMessage && !isReplyReply) - return replyMessage.content.mimeType.split("/")?.[1] || ""; - }, [isReplyText, replyMessage, isReplyReply]); + const replyAttachmentExtention = useMemo(() => { + if (!isReplyText && !!replyMessage && !isReplyReply) + return replyMessage.content.mimeType.split('/')?.[1] || ''; + }, [isReplyText, replyMessage, isReplyReply]); - const navigateToRepliedMessage = () => { - if (!replyMessage) return; - const element = document.getElementById(replyMessage.id.toString()); - if (element) { - element.scrollIntoView({ - block: "end", - behavior: "smooth" - }); - } + const navigateToRepliedMessage = () => { + if (!replyMessage) return; + const element = document.getElementById(replyMessage.id.toString()); + if (element) { + element.scrollIntoView({ + block: 'end', + behavior: 'smooth', + }); } + }; - useEffect(() => { - if (acceptedTypes) { - inputFile?.current?.click(); - } - }, [acceptedTypes]); - - const isReplyVideoOrImage = useMemo(() => { - return typeLookup[replyAttachmentExtention] === "image" || typeLookup[replyAttachmentExtention] === "video"; - }, [replyAttachmentExtention]); + useEffect(() => { + if (acceptedTypes) { + inputFile?.current?.click(); + } + }, [acceptedTypes]); + const isReplyVideoOrImage = useMemo(() => { return ( - - {!replyMessage} - {!newConvo && ( - - onButtonClick("image")} style={{ - cursor: 'pointer' - }} /> - onButtonClick("video")} style={{ - cursor: 'pointer' - }} /> - onButtonClick("application")} style={{ - cursor: 'pointer' - }} /> - + typeLookup[replyAttachmentExtention] === 'image' || + typeLookup[replyAttachmentExtention] === 'video' + ); + }, [replyAttachmentExtention]); + + return ( + + {!replyMessage} + {!newConvo && ( + + onButtonClick('image')} + style={{ + cursor: 'pointer', + }} + /> + onButtonClick('video')} + style={{ + cursor: 'pointer', + }} + /> + onButtonClick('application')} + style={{ + cursor: 'pointer', + }} + /> + + + )} +
+ {replyMessage && ( + + +

+ {isSender + ? 'YOU' + : primaryName ?? formatAddress(replyMessage.senderAddress)} +

+ {isReplyText || isReplyReply ? ( +

+ {isReplyReply + ? replyMessage.content.content + : replyMessage.content} +

+ ) : isReplyVoice ? ( + + ) : typeLookup[replyAttachmentExtention] === 'image' ? ( + {replyMessage.content.filename} + ) : typeLookup[replyAttachmentExtention] === 'video' ? ( + + ) : ( + + +

+ {replyMessage.content.filename} +

+ )} +
+ +
+ )} + {attachmentPreview ? ( + + {attachment?.mimeType !== 'audio/wav' && ( +
)} -
- {replyMessage && ( - - -

{isSender ? "YOU" : primaryName ?? formatAddress(replyMessage.senderAddress)}

- {(isReplyText || isReplyReply) ? ( -

{isReplyReply ? replyMessage.content.content : replyMessage.content}

- ) : ( - isReplyVoice ? - - : - typeLookup[replyAttachmentExtention] === "image" ? - {replyMessage.content.filename} - : - typeLookup[replyAttachmentExtention] === "video" ? - - : - - -

{replyMessage.content.filename}

-
- )} -
- -
- ) - } - { - attachmentPreview ? ( - - {attachment?.mimeType !== "audio/wav" && ( -
- )} - {attachment?.mimeType === "audio/wav" ? - - : - - {typeLookup[attachmentExtention] === "image" ? - {attachment?.filename} - : typeLookup[attachmentExtention] === "video" ? - - : - - -

{attachment?.filename ?? "Cannot preview"}

-
- } - - - - -
- } - { - if (disabled) return; - handleSendAttachment() - }} - /> - - ) : ( - recording ? ( - -

- {recordingValue} -

-

RECORDING...

- { - stopRecording(); - pause(); - reset(); - }} /> -
- ) : ( - isNewMessageLoading ? - - - - : - { - if (disabled) return; - startRecording(); - start(); - }} /> - )} - right={ - { - if (disabled) return; - handleSendMessage() - }} - /> - } - disabled={disabled} - onKeyDown={(e) => { - if (e.key === "Enter") { - handleSendMessage(); - } - }} - onChange={(e) => setMessageValue(e.target.value)} - /> - ) - ) - } -
-
- ); + {attachment?.mimeType === 'audio/wav' ? ( + + ) : ( + + {typeLookup[attachmentExtention] === 'image' ? ( + {attachment?.filename} + ) : typeLookup[attachmentExtention] === 'video' ? ( + + ) : ( + + +

+ {attachment?.filename ?? 'Cannot preview'} +

+
+ )} + + + + +
+ )} + { + if (disabled) return; + handleSendAttachment(); + }} + /> + + ) : recording ? ( + +

+ {recordingValue} +

+

+ RECORDING... +

+ { + stopRecording(); + pause(); + reset(); + }} + /> +
+ ) : isNewMessageLoading ? ( + + + + ) : ( + { + if (disabled) return; + startRecording(); + start(); + }} + /> + ) + } + right={ + { + if (disabled) return; + handleSendMessage(); + }} + /> + } + disabled={disabled} + onKeyDown={(e) => { + if (e.key === 'Enter') { + handleSendMessage(); + } + }} + onChange={(e) => setMessageValue(e.target.value)} + /> + )} +
+ + ); }; export default MessageTextField; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx index b780fef0..cc44d44b 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx @@ -1,185 +1,254 @@ -import { CachedConversation, toCachedConversation, useCanMessage, useClient, useConsent, useConversation, useStartConversation } from '@xmtp/react-sdk'; +import { + CachedConversation, + toCachedConversation, + useCanMessage, + useClient, + useConsent, + useConversation, + useStartConversation, +} from '@xmtp/react-sdk'; import React, { useEffect, useMemo } from 'react'; import MessageTextField from '../MessageTextField'; -import { useAddressResolutionName, useDebounced, useIdentityResolution } from '../../hooks'; -import { useMountedAccount, } from '@justaname.id/react'; +import { useDebounce } from '@justweb3/widget'; +import { + useMountedAccount, + usePrimaryName, + useRecords, +} from '@justaname.id/react'; import { ArrowIcon, Flex, Input, LoadingSpinner } from '@justweb3/ui'; const CancelIcon: React.FC> = (props) => ( - + ); interface NewConversationProps { - onChatStarted: (conversation: CachedConversation) => void; - onBack: () => void; - selectedAddress?: string + onChatStarted: (conversation: CachedConversation) => void; + onBack: () => void; + selectedAddress?: string; } const NewConversation: React.FC = ({ - onChatStarted, - onBack, - selectedAddress + onChatStarted, + onBack, + selectedAddress, }) => { - // States - const [newAddress, setNewAddress] = React.useState(selectedAddress ?? ""); - const [canMessage, setCanMessage] = React.useState(false); - //Queries - const { client } = useClient(); - const { startConversation } = useStartConversation() - const { getCachedByPeerAddress } = useConversation(); - const { refreshConsentList, allow } = useConsent(); - const { address } = useMountedAccount(); - const { canMessage: xmtpCanMessage, isLoading } = useCanMessage(); - const { - value: debouncedAddress, - } = useDebounced(newAddress, 500); - - // TODO: change to regex - const isAddressName = useMemo(() => { - return !debouncedAddress.startsWith("0x") && !debouncedAddress.startsWith("0X") && debouncedAddress.length > 0; - }, [debouncedAddress]) - - const { name, isAddressResolving } = useAddressResolutionName(debouncedAddress, !isAddressName); - - const { address: resolvedAddress, isIdentityResolving } = useIdentityResolution(debouncedAddress, isAddressName); - - - const handleCanMessage = async () => { - if (!client) return; - try { - if (isAddressName && !!resolvedAddress) { - const res = await xmtpCanMessage(resolvedAddress); - setCanMessage(res) - } else { - if (debouncedAddress.length == 42) { - const res = await xmtpCanMessage(debouncedAddress); - setCanMessage(res) - } - } - } catch (e) { - console.log("error", e) - setCanMessage(false) + // States + const [newAddress, setNewAddress] = React.useState( + selectedAddress ?? '' + ); + const [canMessage, setCanMessage] = React.useState(false); + //Queries + const { client } = useClient(); + const { startConversation } = useStartConversation(); + const { getCachedByPeerAddress } = useConversation(); + const { refreshConsentList, allow } = useConsent(); + const { address } = useMountedAccount(); + const { canMessage: xmtpCanMessage, isLoading } = useCanMessage(); + const { debouncedValue: debouncedAddress } = useDebounce( + newAddress, + 500 + ); + + // TODO: change to regex + const isAddressName = useMemo(() => { + return ( + !debouncedAddress.startsWith('0x') && + !debouncedAddress.startsWith('0X') && + debouncedAddress.length > 0 + ); + }, [debouncedAddress]); + + const { records, isRecordsLoading } = useRecords({ + ens: !isAddressName ? debouncedAddress : undefined, + }); + + const { primaryName: name, isPrimaryNameLoading } = usePrimaryName({ + address: isAddressName ? debouncedAddress : undefined, + }); + + // const { name, isRecordsLoading } = useAddressResolutionName(debouncedAddress, !isAddressName); + // + // const { address: resolvedAddress, isPrimaryNameLoading } = useIdentityResolution(debouncedAddress, isAddressName); + const resolvedAddress = useMemo(() => { + return records?.sanitizedRecords?.ethAddress?.value; + }, [records]); + + const handleCanMessage = async () => { + if (!client) return; + try { + if (isAddressName && !!resolvedAddress) { + const res = await xmtpCanMessage(resolvedAddress); + setCanMessage(res); + } else { + if (debouncedAddress.length == 42) { + const res = await xmtpCanMessage(debouncedAddress); + setCanMessage(res); } + } + } catch (e) { + console.log('error', e); + setCanMessage(false); } - - - - const handleNewConversation = async (message: string) => { - if (!client) return; - const peerAddress = (isAddressName && !!resolvedAddress) ? resolvedAddress : debouncedAddress; - try { - const conv = await startConversation(peerAddress, message ?? {}) - if (!conv.cachedConversation) { - if (!conv.conversation) { return } - else { - const cachedConvo = toCachedConversation(conv.conversation, address ?? ''); - await allow([conv.conversation.peerAddress]); - await refreshConsentList(); - onChatStarted(cachedConvo) - } - } else { - await allow([conv.cachedConversation.peerAddress]); - await refreshConsentList(); - onChatStarted(conv.cachedConversation) - } - } catch (error) { - const e = error as Error; - console.log('error creating chat', e) + }; + + const handleNewConversation = async (message: string) => { + if (!client) return; + const peerAddress = + isAddressName && !!resolvedAddress ? resolvedAddress : debouncedAddress; + try { + const conv = await startConversation(peerAddress, message ?? {}); + if (!conv.cachedConversation) { + if (!conv.conversation) { + return; + } else { + const cachedConvo = toCachedConversation( + conv.conversation, + address ?? '' + ); + await allow([conv.conversation.peerAddress]); + await refreshConsentList(); + onChatStarted(cachedConvo); } + } else { + await allow([conv.cachedConversation.peerAddress]); + await refreshConsentList(); + onChatStarted(conv.cachedConversation); + } + } catch (error) { + const e = error as Error; + console.log('error creating chat', e); } + }; - const checkIfConversationExists = async (peerAddress: string) => { - const convoExists = await getCachedByPeerAddress(peerAddress); - if (convoExists) { - onChatStarted(convoExists) - } + const checkIfConversationExists = async (peerAddress: string) => { + const convoExists = await getCachedByPeerAddress(peerAddress); + if (convoExists) { + onChatStarted(convoExists); } + }; - useEffect(() => { - if (!isLoading && !isIdentityResolving && debouncedAddress.length > 0) { - handleCanMessage(); - } else if (canMessage && debouncedAddress.length === 0) { - setCanMessage(false); - } - }, [debouncedAddress, isLoading, isIdentityResolving]); - - - - useEffect(() => { - if (canMessage) { - checkIfConversationExists((isAddressName && !!resolvedAddress) ? resolvedAddress : debouncedAddress); - } - }, [canMessage, resolvedAddress, debouncedAddress]) - - const isSearchLoading = useMemo(() => { - return ((isAddressName && isIdentityResolving) && debouncedAddress.length > 4) || isLoading; - }, [isLoading, debouncedAddress, resolvedAddress, isAddressName]) + useEffect(() => { + if (!isLoading && !isPrimaryNameLoading && debouncedAddress.length > 0) { + handleCanMessage(); + } else if (canMessage && debouncedAddress.length === 0) { + setCanMessage(false); + } + }, [debouncedAddress, isLoading, isPrimaryNameLoading]); - useEffect(() => { + useEffect(() => { + if (canMessage) { + checkIfConversationExists( + isAddressName && !!resolvedAddress ? resolvedAddress : debouncedAddress + ); + } + }, [canMessage, resolvedAddress, debouncedAddress]); - if (!isAddressResolving && !isIdentityResolving) { - return - } + const isSearchLoading = useMemo(() => { + return ( + (isAddressName && isPrimaryNameLoading && debouncedAddress.length > 4) || + isLoading + ); + }, [isLoading, debouncedAddress, resolvedAddress, isAddressName]); - if (name) { - setNewAddress(name) - return - } - }, [name, isAddressResolving, isIdentityResolving]) + useEffect(() => { + if (!isRecordsLoading && !isPrimaryNameLoading) { + return; + } - return ( - - - - - - To

- } - right={ - isSearchLoading ? - : - { - setNewAddress("") - }} /> - } - placeholder={'Subname, Wallet...'} - onChange={(e) => setNewAddress(e.target.value)} - - /> -
- - - + if (name) { + setNewAddress(name); + return; + } + }, [name, isRecordsLoading, isPrimaryNameLoading]); + + return ( + + + + - ); + + To +

+ } + right={ + isSearchLoading ? ( + + ) : ( + { + setNewAddress(''); + }} + /> + ) + } + placeholder={'Subname, Wallet...'} + onChange={(e) => setNewAddress(e.target.value)} + /> +
+ + + +
+ ); }; export default NewConversation; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts index 0d8c18f6..8f6b6a3d 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts @@ -1,10 +1,8 @@ -export * from './sendAttachment'; -export * from './sendMessage'; -export * from './sendReactionMessage'; -export * from './sendReplyMessage'; -export * from './useAddressResolution'; +export * from './useSendAttachment'; +export * from './useSendMessage'; +export * from './useSendReactionMessage'; +export * from './useSendReplyMessage'; export * from './useAttachmentChange'; export * from './useDebounced'; -export * from './useIdentityResolution'; export * from './useRecordingTimer'; export * from './useVoiceRecording'; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useAddressResolution/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useAddressResolution/index.ts deleted file mode 100644 index 72344758..00000000 --- a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useAddressResolution/index.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { addressResolution } from '@justaname.id/address-resolution'; -import { - getPrimaryNameParams, - useMountedAccount, - usePrimaryName, -} from '@justaname.id/react'; -import { ChainId } from '@justaname.id/sdk'; -import { useQuery } from '@tanstack/react-query'; - -export interface AddressResolutionResponse { - id: string; - name: string; - address: string; - nameHash: string; - chainId: number; -} - -export const buildAddressResolutionByAddressKey = (address: string) => [ - 'ADDRESS_RESOLUTION_BY_ADDRESS', - address, -]; -export const getAddressResolutionNameByAddress = async ( - address: string, - chainId: ChainId | undefined, - getPrimaryName: ( - params: getPrimaryNameParams, - force?: boolean - ) => Promise -): Promise => { - try { - const name = await addressResolution( - address, - // TODO: fix - process.env.NEXT_PUBLIC_PROVIDER_URL ?? '' - ); - if (!name) { - const backName = await getPrimaryName({ - address: address as `0x${string}`, - chainId, - }); - if (!!backName) { - return backName as string; - } else { - return null; - } - } else { - return name as string; - } - } catch (error) { - return null; - } -}; - -export const useAddressResolutionName = (address: string, isValid = true) => { - const { chainId } = useMountedAccount(); - const { getPrimaryName } = usePrimaryName(); - const query = useQuery({ - queryKey: buildAddressResolutionByAddressKey(address || ''), - queryFn: () => - getAddressResolutionNameByAddress( - address || '', - chainId as ChainId, - getPrimaryName - ), - enabled: address.length == 42 && isValid, - }); - return { - isAddressResolving: query.isPending, - name: query.data, - refetchAddressResolution: query.refetch, - }; -}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useIdentityResolution/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useIdentityResolution/index.ts deleted file mode 100644 index f871bd94..00000000 --- a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useIdentityResolution/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { useQuery } from '@tanstack/react-query'; -import { ethers } from 'ethers'; - -export const buildIdentityResolutionByNameKey = (name: string) => [ - 'IDENTITY_RESOLUTION_BY_NAME', - name, -]; -export const getIdentityResolutionByName = async ( - name: string -): Promise => { - try { - const provider = new ethers.JsonRpcProvider( - process.env.NEXT_PUBLIC_PROVIDER_URL - ); - const address = await provider.resolveName(name); - return address; - } catch (e) { - console.log('error', e); - return null; - } -}; - -export const useIdentityResolution = (name: string, enabled: boolean) => { - const query = useQuery({ - queryKey: buildIdentityResolutionByNameKey(name), - queryFn: () => getIdentityResolutionByName(name), - enabled: enabled && name.length > 4, - }); - - return { - isIdentityResolving: query.isLoading, - address: query.data, - refetchIdentityResolution: query.refetch, - }; -}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendAttachment/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useSendAttachment/index.ts similarity index 100% rename from packages/@justweb3/xmtp-plugin/src/lib/hooks/sendAttachment/index.ts rename to packages/@justweb3/xmtp-plugin/src/lib/hooks/useSendAttachment/index.ts diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendMessage/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useSendMessage/index.ts similarity index 100% rename from packages/@justweb3/xmtp-plugin/src/lib/hooks/sendMessage/index.ts rename to packages/@justweb3/xmtp-plugin/src/lib/hooks/useSendMessage/index.ts diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendReactionMessage/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useSendReactionMessage/index.ts similarity index 100% rename from packages/@justweb3/xmtp-plugin/src/lib/hooks/sendReactionMessage/index.ts rename to packages/@justweb3/xmtp-plugin/src/lib/hooks/useSendReactionMessage/index.ts diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/sendReplyMessage/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useSendReplyMessage/index.ts similarity index 100% rename from packages/@justweb3/xmtp-plugin/src/lib/hooks/sendReplyMessage/index.ts rename to packages/@justweb3/xmtp-plugin/src/lib/hooks/useSendReplyMessage/index.ts diff --git a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx index 40a4e83e..f69bc4e4 100644 --- a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx +++ b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx @@ -16,6 +16,11 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { WagmiProvider } from 'wagmi'; import { mainnet, sepolia } from 'wagmi/chains'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; +import { XMTPPlugin } from '../lib'; +import { EFPPlugin } from '@justweb3/efp-plugin'; +import { TalentProtocolPlugin } from '@justweb3/talent-protocol-plugin'; +import { POAPPlugin } from '@justweb3/poap-plugin'; +import { JustVerifiedPlugin } from '@justverified/plugin'; const queryClient = new QueryClient(); @@ -45,21 +50,21 @@ const JustWeb3Config: JustWeb3ProviderConfig = { // openOnWalletConnect: false, // // allowedEns: 'all', // // dev: import.meta.env.STORYBOOK_APP_DEV === 'true', - // plugins: [ - // XMTPPlugin, - // EFPPlugin, - // POAPPlugin({ - // apiKey: import.meta.env.STORYBOOK_APP_POAP_KEY, - // }), - // TalentProtocolPlugin({ - // apiKey: import.meta.env.STORYBOOK_APP_TALENT_PROTOCOL_API_KEY, - // }), - // JustVerifiedPlugin(['email', 'telegram', 'twitter', 'discord']), - // ], - // color: { - // primary: '#FF00FF', - // background: '#000000', - // }, + plugins: [ + XMTPPlugin, + EFPPlugin, + POAPPlugin({ + apiKey: import.meta.env.STORYBOOK_APP_POAP_KEY, + }), + TalentProtocolPlugin({ + apiKey: import.meta.env.STORYBOOK_APP_TALENT_PROTOCOL_API_KEY, + }), + JustVerifiedPlugin(['email', 'telegram', 'twitter', 'discord']), + ], + color: { + primary: '#FF00FF', + background: '#000000', + }, }; export const Example = () => { diff --git a/yarn.lock b/yarn.lock index 50444bfa..902a2f9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4535,6 +4535,15 @@ __metadata: languageName: node linkType: hard +"@justaname.id/address-resolution@npm:^1.1.0": + version: 1.1.0 + resolution: "@justaname.id/address-resolution@npm:1.1.0" + peerDependencies: + ethers: 6.9.0 + checksum: 10c0/f8ffb6eb96ca7497aee179a9714dc45c0dd31fe4a1564eea9faf1b26ff689c58539a20568f17ec107dbdf4d298cf1f1e6593aff0aee24023caf1d07c42d5e263 + languageName: node + linkType: hard + "@justaname.id/react@npm:0.3.158, @justaname.id/react@workspace:packages/@justaname.id/react": version: 0.0.0-use.local resolution: "@justaname.id/react@workspace:packages/@justaname.id/react" @@ -26702,6 +26711,7 @@ __metadata: "@hookform/error-message": "npm:^2.0.1" "@hookform/resolvers": "npm:^3.9.0" "@inquirer/prompts": "npm:^4.3.0" + "@justaname.id/address-resolution": "npm:^1.1.0" "@nx/cypress": "npm:19.7.3" "@nx/eslint": "npm:19.7.3" "@nx/eslint-plugin": "npm:19.7.3" From e7d8870798e438dffa124ddeb755af1e59fff38a Mon Sep 17 00:00:00 2001 From: anthony2399 Date: Wed, 4 Dec 2024 18:38:06 +0200 Subject: [PATCH 23/29] feat: finalised xmtp --- .../src/lib/components/Chat/index.tsx | 69 +-- .../src/lib/components/ChatButton/index.tsx | 54 +- .../src/lib/components/ChatSheet/index.tsx | 45 +- .../components/CustomVoicePreview/index.tsx | 7 +- .../src/lib/components/MessageCard/index.tsx | 44 +- .../src/lib/components/MessageItem/index.tsx | 10 +- .../lib/components/MessageTextField/index.tsx | 28 +- .../lib/components/NewConversation/index.tsx | 502 ++++++++++-------- .../xmtp-plugin/src/lib/hooks/index.ts | 1 + .../src/lib/hooks/useEthersSigner/index.ts | 23 + .../xmtp-plugin/src/lib/plugins/index.tsx | 47 +- .../providers/JustWeb3XMTPProvider/index.tsx | 16 + .../xmtp-plugin/src/lib/utils/xmtp/index.ts | 32 ++ 13 files changed, 538 insertions(+), 340 deletions(-) create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/useEthersSigner/index.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/utils/xmtp/index.ts diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx index f497e3ed..b8c52874 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx @@ -125,8 +125,7 @@ export const Chat: React.FC = ({ conversation, onBack }) => { await refreshConsentList(); await allow([conversation.peerAddress]); void refreshConsentList(); - // TODO: check if this is needed - // onRequestAllowed(); + setIsRequest(false) setIsRequestChangeLoading(false); }; @@ -162,6 +161,9 @@ export const Chat: React.FC = ({ conversation, onBack }) => { const computeHeight = useMemo(() => { const additionalHeight = []; const height = '100vh - 50px - 3rem - 1.5rem - 73px - 15px'; + if (isRequest) { + additionalHeight.push('-40px'); + } if (replyMessage) { if (isStringContent) { additionalHeight.push('46px'); @@ -169,6 +171,8 @@ export const Chat: React.FC = ({ conversation, onBack }) => { additionalHeight.push('61px'); } else if (type === 'video' || type === 'image') { additionalHeight.push('116px'); + } else { + additionalHeight.push('47px'); } } @@ -176,10 +180,9 @@ export const Chat: React.FC = ({ conversation, onBack }) => { additionalHeight.push('59px'); } - return `calc( ${height} ${ - additionalHeight.length > 0 ? ' - ' + additionalHeight.join(' - ') : '' - } )`; - }, [replyMessage, isMessagesSenderOnly, isStringContent, mimeType, type]); + return `calc( ${height} ${additionalHeight.length > 0 ? ' - ' + additionalHeight.join(' - ') : '' + } )`; + }, [replyMessage, isMessagesSenderOnly, isStringContent, mimeType, type, isRequest]); return ( = ({ conversation, onBack }) => { src={ primaryName ? sanitizeEnsImage({ - name: primaryName, - chainId: 1, - image: records?.sanitizedRecords?.avatar, - }) + name: primaryName, + chainId: 1, + image: records?.sanitizedRecords?.avatar, + }) : undefined } style={{ @@ -281,18 +284,22 @@ export const Chat: React.FC = ({ conversation, onBack }) => { ? primaryName : formatAddress(conversation.peerAddress)}

- {/* {(!!primaryName) && ( -

{formatAddress(conversation.peerAddress)}

- )} */} + {primaryName && ( +

+ {formatAddress(conversation.peerAddress)} +

+ )}
- + = ({ conversation, onBack }) => { }} /> - = ({ conversation, onBack }) => { }} onClick={() => blockAddress(conversation.peerAddress)} > -

- Block -

+

+ Block +

@@ -549,7 +556,7 @@ export const Chat: React.FC = ({ conversation, onBack }) => { {isMessagesSenderOnly && ( = ({ conversation, onBack }) => { fontSize: '14px', fontWeight: 900, lineHeight: '100%', - color: 'black', + color: 'var(--justweb3-foreground-color-3)', }} > Message in user’s Requests diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx index df728b2d..f0a41a67 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx @@ -1,27 +1,53 @@ +import { useMountedAccount } from '@justaname.id/react'; import { ArrowIcon, ClickableItem } from '@justweb3/ui'; -import { useClient } from '@xmtp/react-sdk'; -import { useWalletClient } from 'wagmi'; +import { Client, ClientOptions, useClient } from '@xmtp/react-sdk'; +import { useEthersSigner } from '../../hooks'; +import { XmtpEnvironment } from '../../plugins'; +import { storeKeys, loadKeys, wipeKeys } from '../../utils/xmtp'; export interface ChatButtonProps { handleOpen: (open: boolean) => void; + env: XmtpEnvironment; } -export const ChatButton: React.FC = ({ handleOpen }) => { +export const ChatButton: React.FC = ({ handleOpen, env }) => { const { initialize } = useClient(); const { client } = useClient(); - const { data: walletClient } = useWalletClient(); + const walletClient = useEthersSigner() + const { address } = useMountedAccount() const handleChat = async () => { if (!client) { - initialize({ - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - signer: walletClient, - options: { - env: 'dev', - }, - }).then(() => { - handleOpen(true); - }); + const signer = await walletClient + try { + if (!signer) { + return + } + const clientOptions: Partial> = { + appVersion: 'JustWeb3/1.0.0', + env: env + } + let keys = loadKeys(address ?? '', env) + if (!keys) { + keys = await Client.getKeys(signer, { + env: env, + skipContactPublishing: false, + // persistConversations: false, + }) + storeKeys(address ?? '', keys, env) + } + await initialize({ + keys, + options: clientOptions, + signer: signer, + }).then(() => { + handleOpen(true); + }) + + // handleClient(client) + } catch (error) { + console.error('Failed to initialize XMTP Client:', error) + wipeKeys(address ?? '', env) + } } else { handleOpen(true); } diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx index a9063ce3..54a37098 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx @@ -1,13 +1,14 @@ import { + AddIcon, + Flex, Sheet, SheetContent, SheetTitle, Tabs, TabsContent, TabsList, - TabsTrigger, + TabsTrigger } from '@justweb3/ui'; -import React, { useEffect, useMemo } from 'react'; import { CachedConversation, ContentTypeMetadata, @@ -16,6 +17,7 @@ import { useStreamAllMessages, useStreamConversations, } from '@xmtp/react-sdk'; +import React, { useEffect, useMemo } from 'react'; import { ChatList } from '../ChatList'; export interface ChatSheetProps { @@ -24,17 +26,19 @@ export interface ChatSheetProps { handleOpenChat: ( conversation: CachedConversation | null ) => void; + handleNewChat: () => void; } export const ChatSheet: React.FC = ({ open, handleOpen, handleOpenChat, + handleNewChat }) => { const [tab, setTab] = React.useState('Chats'); const { conversations, isLoading } = useConversations(); const [isConsentListLoading, setIsConsentListLoading] = React.useState(true); - const { loadConsentList, entries } = useConsent(); + const { loadConsentList, entries, } = useConsent(); const allowedConversations = useMemo(() => { return conversations.filter( @@ -74,6 +78,21 @@ export const ChatSheet: React.FC = ({ Chats + + + = ({ Requests + {requestConversations.length > 0 && ( + {requestConversations.length} + )} = ({ {playing ? = ({ }} >{playing || currentTime > 0 ? formatTime(currentTime) : formatTime(audioDuration ?? 0)}

); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx index 21c2c69f..0630fb58 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx @@ -1,11 +1,4 @@ -import React, { useEffect, useMemo, useRef, useState } from 'react'; -import { CachedConversation, DecodedMessage } from '@xmtp/react-sdk'; -import { MessageWithReaction } from '../../utils/filterReactionsMessages'; import { useMountedAccount, usePrimaryName } from '@justaname.id/react'; -import { useSendReactionMessage } from '../../hooks'; -import { typeLookup } from '../../utils/attachments'; -import { findEmojiByName } from '../../utils/emojis'; -import { formatMessageSentTime } from '../../utils/messageTimeFormat'; import { DocumentIcon, DownloadIcon, @@ -14,10 +7,17 @@ import { ReactionIcon, ReplyIcon, } from '@justweb3/ui'; -import { formatAddress } from '../../utils/formatAddress'; +import { CachedConversation, DecodedMessage } from '@xmtp/react-sdk'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { useSendReactionMessage } from '../../hooks'; +import { typeLookup } from '../../utils/attachments'; import { calculateFileSize } from '../../utils/calculateFileSize'; -import VoiceMessageCard from '../VoiceMessageCard'; +import { findEmojiByName } from '../../utils/emojis'; +import { MessageWithReaction } from '../../utils/filterReactionsMessages'; +import { formatAddress } from '../../utils/formatAddress'; +import { formatMessageSentTime } from '../../utils/messageTimeFormat'; import { CustomPlayer } from '../CustomPlayer'; +import VoiceMessageCard from '../VoiceMessageCard'; interface MessageCardProps { message: MessageWithReaction; @@ -259,17 +259,17 @@ const MessageCard: React.FC = ({ senderAddress: message.senderAddress, content: typeLookup[attachmentExtention] === 'image' || - typeLookup[attachmentExtention] === 'video' + typeLookup[attachmentExtention] === 'video' ? { - data: message.content.data, - mimeType: message.content.mimeType, - filename: message.content.filename, - url: URL.createObjectURL( - new Blob([message.content.data], { - type: message.content.mimeType, - }) - ), - } + data: message.content.data, + mimeType: message.content.mimeType, + filename: message.content.filename, + url: URL.createObjectURL( + new Blob([message.content.data], { + type: message.content.mimeType, + }) + ), + } : message.content, contentType: message.contentType, })} @@ -317,15 +317,15 @@ const MessageCard: React.FC = ({ {repliedMessage?.senderAddress === address ? 'YOU' : primaryName ?? - formatAddress(repliedMessage?.senderAddress ?? '')} + formatAddress(repliedMessage?.senderAddress ?? '')}

{isReplyText || isReplyReply ? (

= ({ src={ primaryName ? sanitizeEnsImage({ - name: primaryName, - chainId: 1, - image: records?.sanitizedRecords?.avatar, - }) + name: primaryName, + chainId: 1, + image: records?.sanitizedRecords?.avatar, + }) : undefined } /> @@ -140,7 +140,7 @@ export const MessageItem: React.FC = ({ }} > {blocked ? ( - ) : ( diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx index 4909da6b..c596cc07 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx @@ -47,6 +47,7 @@ interface MessageTextFieldProps { onCancelReply?: () => void; onNewConvo?: (message: string) => void; peerAddress?: string; + style?: React.CSSProperties; } const MessageTextField: React.FC = ({ @@ -57,6 +58,7 @@ const MessageTextField: React.FC = ({ conversation, onNewConvo, peerAddress, + style }) => { const [messageValue, setMessageValue] = React.useState(''); const [attachment, setAttachment] = React.useState(); @@ -211,7 +213,7 @@ const MessageTextField: React.FC = ({ }, [replyAttachmentExtention]); return ( - + {!replyMessage} {!newConvo && ( @@ -263,16 +265,17 @@ const MessageTextField: React.FC = ({ height: isReplyText ? '30px' : isReplyVoice - ? '45px' - : isReplyVideoOrImage - ? '100px' - : '30px', + ? '45px' + : isReplyVideoOrImage + ? '100px' + : '30px', borderRadius: '5px', background: 'white', + paddingLeft: '14px', border: '1px solid grey', borderBottom: 0, - borderTopLeftRadius: '6px', - borderTopRightRadius: '6px', + borderTopLeftRadius: '25px', + borderTopRightRadius: '25px', borderBottomRightRadius: 0, borderBottomLeftRadius: 0, }} @@ -395,9 +398,12 @@ const MessageTextField: React.FC = ({ justify="space-between" style={{ padding: '10px 15px', - borderRadius: '6px', + borderRadius: '100px', background: 'white', + height: 22, + maxHeight: 22!, border: '1px solid grey', + paddingLeft: attachment?.mimeType === 'audio/wav' ? '5px' : '15px' }} > {attachment?.mimeType !== 'audio/wav' && ( @@ -586,9 +592,9 @@ const MessageTextField: React.FC = ({ maxHeight: 22!, paddingLeft: !replyMessage && !newConvo ? '10px' : '16px', paddingRight: '10px', - borderRadius: '6px', - borderTopLeftRadius: replyMessage ? 0 : '6px', - borderTopRightRadius: replyMessage ? 0 : '6px', + borderRadius: replyMessage ? '25px' : '100px', + borderTopLeftRadius: replyMessage ? 0 : '100px', + borderTopRightRadius: replyMessage ? 0 : '100px', borderTop: replyMessage ? '0px' : '', }} placeholder={`Send message...`} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx index cc44d44b..5a5954ad 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx @@ -1,254 +1,300 @@ import { - CachedConversation, - toCachedConversation, - useCanMessage, - useClient, - useConsent, - useConversation, - useStartConversation, + CachedConversation, + toCachedConversation, + useCanMessage, + useClient, + useConsent, + useConversation, + useStartConversation, } from '@xmtp/react-sdk'; import React, { useEffect, useMemo } from 'react'; import MessageTextField from '../MessageTextField'; import { useDebounce } from '@justweb3/widget'; import { - useMountedAccount, - usePrimaryName, - useRecords, + useMountedAccount, + usePrimaryName, + useRecords, } from '@justaname.id/react'; -import { ArrowIcon, Flex, Input, LoadingSpinner } from '@justweb3/ui'; - -const CancelIcon: React.FC> = (props) => ( - -); +import { ArrowIcon, CloseIcon, Flex, Input, LoadingSpinner, P, VerificationsIcon } from '@justweb3/ui'; + interface NewConversationProps { - onChatStarted: (conversation: CachedConversation) => void; - onBack: () => void; - selectedAddress?: string; + onChatStarted: (conversation: CachedConversation) => void; + onBack: () => void; + selectedAddress?: string; } const NewConversation: React.FC = ({ - onChatStarted, - onBack, - selectedAddress, + onChatStarted, + onBack, + selectedAddress, }) => { - // States - const [newAddress, setNewAddress] = React.useState( - selectedAddress ?? '' - ); - const [canMessage, setCanMessage] = React.useState(false); - //Queries - const { client } = useClient(); - const { startConversation } = useStartConversation(); - const { getCachedByPeerAddress } = useConversation(); - const { refreshConsentList, allow } = useConsent(); - const { address } = useMountedAccount(); - const { canMessage: xmtpCanMessage, isLoading } = useCanMessage(); - const { debouncedValue: debouncedAddress } = useDebounce( - newAddress, - 500 - ); - - // TODO: change to regex - const isAddressName = useMemo(() => { - return ( - !debouncedAddress.startsWith('0x') && - !debouncedAddress.startsWith('0X') && - debouncedAddress.length > 0 + // States + const [newAddress, setNewAddress] = React.useState( + selectedAddress ?? '' + ); + const [canMessage, setCanMessage] = React.useState(false); + //Queries + const { client } = useClient(); + const { startConversation } = useStartConversation(); + const { getCachedByPeerAddress } = useConversation(); + const { refreshConsentList, allow } = useConsent(); + const { address } = useMountedAccount(); + const { canMessage: xmtpCanMessage, isLoading } = useCanMessage(); + const { debouncedValue: debouncedAddress } = useDebounce( + newAddress, + 500 ); - }, [debouncedAddress]); - - const { records, isRecordsLoading } = useRecords({ - ens: !isAddressName ? debouncedAddress : undefined, - }); - - const { primaryName: name, isPrimaryNameLoading } = usePrimaryName({ - address: isAddressName ? debouncedAddress : undefined, - }); - - // const { name, isRecordsLoading } = useAddressResolutionName(debouncedAddress, !isAddressName); - // - // const { address: resolvedAddress, isPrimaryNameLoading } = useIdentityResolution(debouncedAddress, isAddressName); - const resolvedAddress = useMemo(() => { - return records?.sanitizedRecords?.ethAddress?.value; - }, [records]); - - const handleCanMessage = async () => { - if (!client) return; - try { - if (isAddressName && !!resolvedAddress) { - const res = await xmtpCanMessage(resolvedAddress); - setCanMessage(res); - } else { - if (debouncedAddress.length == 42) { - const res = await xmtpCanMessage(debouncedAddress); - setCanMessage(res); + + const isAddressName = useMemo(() => { + const ethAddressRegex = /^0x[a-fA-F0-9]{40}$/; + return ( + !ethAddressRegex.test(debouncedAddress) && + debouncedAddress.length > 0 + ); + }, [debouncedAddress]); + + + const { records, isRecordsLoading } = useRecords({ + ens: debouncedAddress, + enabled: isAddressName + }); + + const { primaryName: name, isPrimaryNameLoading } = usePrimaryName({ + address: debouncedAddress as `0x${string}`, + enabled: !isAddressName + }); + + + const resolvedAddress = useMemo(() => { + return records?.sanitizedRecords?.ethAddress?.value; + }, [records]); + + const handleCanMessage = async () => { + if (!client) return; + try { + if (isAddressName) { + if (resolvedAddress) { + const res = await xmtpCanMessage(resolvedAddress); + setCanMessage(res); + } else { + // Resolved address is not available yet; do nothing + return; + } + } else if (debouncedAddress.length === 42) { + const res = await xmtpCanMessage(debouncedAddress); + setCanMessage(res); + } else { + setCanMessage(false); + } + } catch (e) { + console.log('error', e); + setCanMessage(false); + } + }; + + const handleNewConversation = async (message: string) => { + if (!client) return; + const peerAddress = + isAddressName && !!resolvedAddress ? resolvedAddress : debouncedAddress; + try { + const conv = await startConversation(peerAddress, message ?? {}); + if (!conv.cachedConversation) { + if (!conv.conversation) { + return; + } else { + const cachedConvo = toCachedConversation( + conv.conversation, + address ?? '' + ); + await allow([conv.conversation.peerAddress]); + await refreshConsentList(); + onChatStarted(cachedConvo); + onBack(); + } + } else { + await allow([conv.cachedConversation.peerAddress]); + await refreshConsentList(); + onChatStarted(conv.cachedConversation); + onBack(); + } + } catch (error) { + const e = error as Error; + console.log('error creating chat', e); + } + }; + + const checkIfConversationExists = async (peerAddress: string) => { + const convoExists = await getCachedByPeerAddress(peerAddress); + if (convoExists) { + onChatStarted(convoExists); + } + }; + + useEffect(() => { + if (debouncedAddress.length === 0) { + setCanMessage(false); + return; } - } - } catch (e) { - console.log('error', e); - setCanMessage(false); - } - }; - - const handleNewConversation = async (message: string) => { - if (!client) return; - const peerAddress = - isAddressName && !!resolvedAddress ? resolvedAddress : debouncedAddress; - try { - const conv = await startConversation(peerAddress, message ?? {}); - if (!conv.cachedConversation) { - if (!conv.conversation) { - return; + if (isAddressName) { + if (!isRecordsLoading && resolvedAddress) { + handleCanMessage(); + } } else { - const cachedConvo = toCachedConversation( - conv.conversation, - address ?? '' - ); - await allow([conv.conversation.peerAddress]); - await refreshConsentList(); - onChatStarted(cachedConvo); + if (!isLoading && !isPrimaryNameLoading) { + handleCanMessage(); + } + } + }, [ + debouncedAddress, + isLoading, + isPrimaryNameLoading, + isRecordsLoading, + resolvedAddress, + isAddressName + ]); + + + useEffect(() => { + const checkConversation = async () => { + if (canMessage) { + await checkIfConversationExists( + isAddressName && resolvedAddress ? resolvedAddress : debouncedAddress + ); + } + }; + + checkConversation(); + }, [canMessage, resolvedAddress, debouncedAddress]); + + + const isSearchLoading = useMemo(() => { + return ( + (isAddressName && isPrimaryNameLoading && debouncedAddress.length > 4) || + isLoading + ); + }, [isLoading, debouncedAddress, resolvedAddress, isAddressName]); + + + useEffect(() => { + if (isRecordsLoading || isPrimaryNameLoading) { + return; + } + + if (name) { + setNewAddress(name); + return; } - } else { - await allow([conv.cachedConversation.peerAddress]); - await refreshConsentList(); - onChatStarted(conv.cachedConversation); - } - } catch (error) { - const e = error as Error; - console.log('error creating chat', e); - } - }; - - const checkIfConversationExists = async (peerAddress: string) => { - const convoExists = await getCachedByPeerAddress(peerAddress); - if (convoExists) { - onChatStarted(convoExists); - } - }; - - useEffect(() => { - if (!isLoading && !isPrimaryNameLoading && debouncedAddress.length > 0) { - handleCanMessage(); - } else if (canMessage && debouncedAddress.length === 0) { - setCanMessage(false); - } - }, [debouncedAddress, isLoading, isPrimaryNameLoading]); - - useEffect(() => { - if (canMessage) { - checkIfConversationExists( - isAddressName && !!resolvedAddress ? resolvedAddress : debouncedAddress - ); - } - }, [canMessage, resolvedAddress, debouncedAddress]); - - const isSearchLoading = useMemo(() => { + }, [name, isRecordsLoading, isPrimaryNameLoading]); + return ( - (isAddressName && isPrimaryNameLoading && debouncedAddress.length > 4) || - isLoading - ); - }, [isLoading, debouncedAddress, resolvedAddress, isAddressName]); - - useEffect(() => { - if (!isRecordsLoading && !isPrimaryNameLoading) { - return; - } - - if (name) { - setNewAddress(name); - return; - } - }, [name, isRecordsLoading, isPrimaryNameLoading]); - - return ( - - - - - - To -

- } - right={ - isSearchLoading ? ( - - ) : ( - { - setNewAddress(''); + > + + + + + +

+ To +

+ {isSearchLoading ? ( + + ) : ( + debouncedAddress.length > 0 ? + + : null + )} +
+ } + right={ + isSearchLoading ? ( + + ) : ( + + { + setNewAddress(''); + }} + > + + + + ) + } + placeholder={'ENS, Wallet Address...'} + onChange={(e) => setNewAddress(e.target.value)} + style={{ + flex: 1, + height: 22, + maxHeight: 22!, + gap: 5, + }} + /> +
+ - ) - } - placeholder={'Subname, Wallet...'} - onChange={(e) => setNewAddress(e.target.value)} - /> - - - - - - ); + > + + + + ); }; export default NewConversation; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts index 8f6b6a3d..0a628dc4 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/index.ts @@ -5,4 +5,5 @@ export * from './useSendReplyMessage'; export * from './useAttachmentChange'; export * from './useDebounced'; export * from './useRecordingTimer'; +export * from './useEthersSigner'; export * from './useVoiceRecording'; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useEthersSigner/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useEthersSigner/index.ts new file mode 100644 index 00000000..6edf47fc --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useEthersSigner/index.ts @@ -0,0 +1,23 @@ +import { BrowserProvider, JsonRpcSigner } from 'ethers'; +import { useMemo } from 'react'; +import type { Account, Chain, Client, Transport } from 'viem'; +import { useWalletClient } from 'wagmi'; + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + if (!account || !chain || !transport) return undefined + const network = { + chainId: chain?.id, + name: chain?.name, + ensAddress: chain?.contracts?.ensRegistry?.address, + } + const provider = new BrowserProvider(transport, network) + const signer = new JsonRpcSigner(provider, account.address) + return signer +} + +/** Hook to convert a viem Wallet Client to an ethers.js Signer. */ +export async function useEthersSigner({ chainId }: { chainId?: number } = {}) { + const { data: client } = useWalletClient({ chainId }) + return useMemo(() => (client ? clientToSigner(client) : undefined), [client, client?.chain, client?.account, client?.transport]) +} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx index 5f0d27c9..fd6a6032 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx @@ -2,25 +2,30 @@ import { JustaPlugin } from '@justweb3/widget'; import { JustWeb3XMTPProvider } from '../providers/JustWeb3XMTPProvider'; import { ChatButton } from '../components/ChatButton'; -export const XMTPPlugin: JustaPlugin = { - name: 'XMTPPlugin', - components: { - Provider: (pluginApi, children) => { - return ( - pluginApi.setState('xmtpOpen', open)} - > - {children} - - ); - }, - SignInMenu: (pluginApi) => { - return ( - pluginApi.setState('xmtpOpen', open)} - /> - ); - }, - }, +export type XmtpEnvironment = 'local' | 'production' | 'dev'; + +export const XMTPPlugin = (env: XmtpEnvironment): JustaPlugin => { + return ({ + name: 'XMTPPlugin', + components: { + Provider: (pluginApi, children) => { + return ( + pluginApi.setState('xmtpOpen', open)} + > + {children} + + ); + }, + SignInMenu: (pluginApi) => { + return ( + pluginApi.setState('xmtpOpen', open)} + env={env} + /> + ); + }, + } + }) }; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx index c5e135b3..f7824e73 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx @@ -11,6 +11,7 @@ import { import { useJustWeb3 } from '@justweb3/widget'; import { ChatSheet } from '../../components/ChatSheet'; import { MessageSheet } from '../../components/MessageSheet'; +import { NewMessageSheet } from '../../components/NewMessageSheet'; const contentTypeConfigs = [ attachmentContentTypeConfig, @@ -36,18 +37,27 @@ export const JustWeb3XMTPProvider: React.FC = ({ handleOpen, }) => { const [isXmtpEnabled, setIsXmtpEnabled] = React.useState(false); + const [isNewChat, setIsNewChat] = React.useState(false); const [conversation, setConversation] = React.useState | null>(null); const handleXmtpEnabled = (enabled: boolean) => { setIsXmtpEnabled(enabled); }; + const handleOpenNewChat = (open: boolean) => { + setIsNewChat(open); + }; + const handleOpenChat = ( conversation: CachedConversation | null ) => { setConversation(conversation); }; + const handleNewChat = () => { + setIsNewChat(true); + } + return ( @@ -57,11 +67,17 @@ export const JustWeb3XMTPProvider: React.FC = ({ openChat={!!conversation} conversation={conversation} /> + {isXmtpEnabled && ( )} {children} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/utils/xmtp/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/utils/xmtp/index.ts new file mode 100644 index 00000000..7907a5f2 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/utils/xmtp/index.ts @@ -0,0 +1,32 @@ +import { XmtpEnvironment } from '../../plugins'; + +export const buildLocalStorageKey = ( + walletAddress: string, + env: XmtpEnvironment +) => { + return `xmtp:${env}:keys:${walletAddress}`; +}; +const ENCODING = 'binary'; + +export const storeKeys = ( + walletAddress: string, + keys: Uint8Array, + env: XmtpEnvironment +) => { + localStorage.setItem( + buildLocalStorageKey(walletAddress, env), + Buffer.from(keys).toString(ENCODING) + ); +}; + +export const loadKeys = ( + walletAddress: string, + env: XmtpEnvironment +): Uint8Array | null => { + const val = localStorage.getItem(buildLocalStorageKey(walletAddress, env)); + return val ? Buffer.from(val, ENCODING) : null; +}; + +export const wipeKeys = (walletAddress: string, env: XmtpEnvironment) => { + localStorage.removeItem(buildLocalStorageKey(walletAddress, env)); +}; From fb31ee794f466d664b500bae7c3f265a6b5ded2c Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Thu, 5 Dec 2024 09:39:18 +0200 Subject: [PATCH 24/29] feat: chat from profile --- .../react/src/lib/helpers/validateEns.ts | 15 + .../hooks/primaryName/usePrimaryNameBatch.ts | 6 +- .../react/src/lib/hooks/records/useRecords.ts | 59 +- .../sdk/src/lib/api/axiosController.ts | 1 + .../src/lib/dialogs/ProfileDialog/index.tsx | 1 + .../lib/providers/JustWeb3Provider/index.tsx | 12 +- .../xmtp-plugin/.storybook/preview.tsx | 14 +- .../src/lib/components/Chat/index.tsx | 45 +- .../src/lib/components/ChatList/index.tsx | 20 +- .../src/lib/components/ChatSheet/index.tsx | 53 +- .../ChatWithProfileButton/index.tsx | 82 +++ .../src/lib/components/MessageItem/index.tsx | 22 +- .../lib/components/NewConversation/index.tsx | 538 +++++++++--------- .../lib/components/NewMessageSheet/index.tsx | 20 +- .../xmtp-plugin/src/lib/plugins/index.tsx | 10 +- .../providers/JustWeb3XMTPProvider/index.tsx | 30 +- .../xmtp-plugin/src/stories/xmtp.stories.tsx | 13 +- 17 files changed, 591 insertions(+), 350 deletions(-) create mode 100644 packages/@justaname.id/react/src/lib/helpers/validateEns.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatWithProfileButton/index.tsx diff --git a/packages/@justaname.id/react/src/lib/helpers/validateEns.ts b/packages/@justaname.id/react/src/lib/helpers/validateEns.ts new file mode 100644 index 00000000..0f58d763 --- /dev/null +++ b/packages/@justaname.id/react/src/lib/helpers/validateEns.ts @@ -0,0 +1,15 @@ +import { normalize } from 'viem/ens'; + +export const validateEns = (name: string | undefined): string | undefined => { + if (typeof name !== 'string' || name.trim() === '') { + return; + } + + try { + const normalized = normalize(name); + + return normalized; + } catch (error) { + return; + } +}; diff --git a/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryNameBatch.ts b/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryNameBatch.ts index ddd06a45..48ff1dce 100644 --- a/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryNameBatch.ts +++ b/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryNameBatch.ts @@ -17,10 +17,10 @@ export const buildPrimaryNameBatchKey = (chainId: ChainId | undefined) => [ chainId, ]; -export type PrimaryNameRecord = Record; +export type PrimaryNameRecord = Record; export interface UsePrimaryNameBatchParams { - addresses?: Address[]; + addresses?: string[]; chainId?: ChainId; enabled?: boolean; } @@ -143,7 +143,7 @@ export const usePrimaryNameBatch = ( ), queryFn: () => getPrimaryNameBatch({ - addresses: params?.addresses, + addresses: params?.addresses as Address[], }), enabled: Boolean(params?.addresses) && Boolean(ensClient) && Boolean(_enabled), diff --git a/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts b/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts index 58557c3b..b9918bd8 100644 --- a/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts +++ b/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts @@ -18,10 +18,11 @@ import { useMemo } from 'react'; import { Records } from '../../types'; import { defaultOptions } from '../../query'; import { RecordsTaskQueue } from './records-task-queue'; -import { checkEnsValid } from '../../helpers/checkEnsValid'; import { useEnsPublicClient } from '../client/useEnsPublicClient'; import { useOffchainResolvers } from '../offchainResolver'; import { getRecords as getEnsRecords } from '@ensdomains/ensjs/public'; +import { checkEnsValid } from '../../helpers/checkEnsValid'; +import { validateEns } from '../../helpers/validateEns'; export const buildRecordsBySubnameKey = ( subname: string, @@ -72,6 +73,7 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { () => params?.chainId || chainId, [params?.chainId, chainId] ); + const _ens = useMemo(() => validateEns(params?.ens), [params?.ens]); const { offchainResolvers } = useOffchainResolvers(); const { ensClient } = useEnsPublicClient({ chainId: _chainId, @@ -86,12 +88,19 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { const getRecords = async ( _params: SubnameRecordsRoute['params'] ): Promise => { + const __ens = validateEns(_params.ens); + + if (!__ens) { + throw new Error('Invalid ENS name'); + } + const result = await justaname.subnames.getRecords({ - ens: _params.ens, + ens: __ens, providerUrl: _params.providerUrl, chainId: _params.chainId, }); + console.log(__ens, result); checkEnsValid(result); const sanitized = sanitizeRecords(result); @@ -109,8 +118,14 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { throw new Error('Public client not found'); } + const __ens = validateEns(_params.ens) || _ens; + + if (!__ens) { + throw new Error('Invalid ENS name'); + } + const result = await getEnsRecords(ensClient, { - name: _params.ens, + name: __ens, coins: Object.keys(coinTypeMap), texts: [ ...generalKeys, @@ -126,7 +141,7 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { ); const record = { - ens: _params.ens, + ens: __ens, isJAN: result.resolverAddress === offchainResolver?.resolverAddress, records: { ...result, @@ -137,6 +152,7 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { }, }; + console.log(__ens, record); checkEnsValid(record); const sanitized = sanitizeRecords(record); @@ -152,11 +168,15 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { forceUpdate = false ): Promise => { const __chainId = _params?.chainId || _chainId; + const __ens = validateEns(_params?.ens) || _ens; + if (!__ens) { + throw new Error('Invalid ENS name'); + } // const __standard = _params?.standard || params?.standard; const __standard = false; if (!forceUpdate) { const cachedRecords = queryClient.getQueryData( - buildRecordsBySubnameKey(_params?.ens, __chainId, __standard) + buildRecordsBySubnameKey(__ens, __chainId, __standard) ) as Records; if (cachedRecords) { return cachedRecords; @@ -176,13 +196,16 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { let records: Records; try { records = await getRecords({ - ens: _params.ens, + ens: __ens, chainId: __chainId, providerUrl: __providerUrl, }); } catch (error) { + if (error instanceof Error && error.message.includes('NotFound')) { + throw error; + } records = await getStandardRecords({ - ens: _params.ens, + ens: __ens, chainId: __chainId, providerUrl: __providerUrl, }); @@ -195,7 +218,7 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { // if (__standard) { // records = await getStandardRecords({ - // ens: _params.ens, + // ens: __ens, // chainId: __chainId, // providerUrl: __providerUrl, // }); @@ -208,7 +231,7 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { // } queryClient.setQueryData( - buildRecordsBySubnameKey(_params.ens, __chainId, __standard), + buildRecordsBySubnameKey(__ens, __chainId, __standard), records ); return records; @@ -216,21 +239,33 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { const query = useQuery({ ...defaultOptions, + retry: (failureCount, error) => { + console.log(error); + if (error instanceof Error) { + if ( + error.message.includes('NotFound') || + error.message.includes('ETH address not found') + ) { + return false; + } + } + return failureCount < 3; + }, queryKey: buildRecordsBySubnameKey( - params?.ens || '', + _ens || '', _chainId // params?.standard ), queryFn: () => getRecordsInternal( { - ens: params?.ens || '', + ens: _ens || '', chainId: _chainId, }, true ), enabled: - Boolean(params?.ens) && + Boolean(_ens) && Boolean(_chainId) && Boolean(_providerUrl) && Boolean(_enabled), diff --git a/packages/@justaname.id/sdk/src/lib/api/axiosController.ts b/packages/@justaname.id/sdk/src/lib/api/axiosController.ts index 4e84ddc5..9a2dad0b 100644 --- a/packages/@justaname.id/sdk/src/lib/api/axiosController.ts +++ b/packages/@justaname.id/sdk/src/lib/api/axiosController.ts @@ -42,6 +42,7 @@ export const controlledAxiosPromise = >( return res.data.result.data as T; }) .catch((err: AxiosError>) => { + console.error(err); if (err?.response) { if (err?.response?.data?.result) { if (err?.response?.data?.result?.error) { diff --git a/packages/@justweb3/widget/src/lib/dialogs/ProfileDialog/index.tsx b/packages/@justweb3/widget/src/lib/dialogs/ProfileDialog/index.tsx index beedc810..15146d32 100644 --- a/packages/@justweb3/widget/src/lib/dialogs/ProfileDialog/index.tsx +++ b/packages/@justweb3/widget/src/lib/dialogs/ProfileDialog/index.tsx @@ -350,6 +350,7 @@ export const ProfileDialog: FC = ({ contentStyle={{ width: '100%', height: '100%', + pointerEvents: 'auto', }} fullScreen={minimized} header={ diff --git a/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx b/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx index f670f2f8..90058cf0 100644 --- a/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx +++ b/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx @@ -47,6 +47,7 @@ export interface JustWeb3ContextProps { ) => Promise; handleJustWeb3Config: (config: JustWeb3ProviderConfig) => void; handleOpenEnsProfile: (ens: string, chainId?: ChainId) => void; + handleCloseEnsProfile: () => void; isSignInOpen: boolean; config: JustWeb3ProviderConfig; plugins: JustaPlugin[]; @@ -58,6 +59,7 @@ export const JustWeb3Context = createContext({ handleOpenSignInDialog: () => {}, handleUpdateRecords: async () => {}, handleOpenEnsProfile: () => {}, + handleCloseEnsProfile: () => {}, handleJustWeb3Config: () => {}, config: {}, plugins: [], @@ -129,6 +131,10 @@ export const JustWeb3Provider: FC = ({ setEnsOpen({ ens, chainId }); }; + const handleCloseEnsProfile = () => { + setEnsOpen(null); + }; + useEffect(() => { if (!updateRecord && updateRecordPromiseResolveRef.current) { updateRecordPromiseResolveRef.current(); @@ -212,6 +218,7 @@ export const JustWeb3Provider: FC = ({ handleUpdateRecords: handleUpdateRecords, handleJustWeb3Config, handleOpenEnsProfile, + handleCloseEnsProfile, }} > void; connectedEns: UseEnsAuthReturn['connectedEns']; openEnsProfile: (ens: string, chainId?: ChainId) => void; + closeEnsProfile: () => void; updateRecords: ( records: Omit & { ens?: string } ) => Promise; @@ -305,7 +313,8 @@ export const useJustWeb3 = (): useJustWeb3 => { } = useEnsAuth({ local: !context.config.enableAuth, }); - const { handleUpdateRecords, handleOpenEnsProfile } = context; + const { handleUpdateRecords, handleOpenEnsProfile, handleCloseEnsProfile } = + context; const handleUpdateRecordsInternal = async ( records: Omit & { ens?: string; @@ -362,6 +371,7 @@ export const useJustWeb3 = (): useJustWeb3 => { connectedEns, refreshEnsAuth, openEnsProfile: handleOpenEnsProfile, + closeEnsProfile: handleCloseEnsProfile, chainId: justanameContext?.chainId, }; }; diff --git a/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx b/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx index ef63dacb..d4619ace 100644 --- a/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx +++ b/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx @@ -1,12 +1,10 @@ import './polyfills'; -import { scan } from 'react-scan'; // import this BEFORE react - -if (typeof window !== 'undefined') { - scan({ - enabled: true, - log: true, // logs render info to console (default: false) - }); -} +// if (typeof window !== 'undefined') { +// scan({ +// enabled: true, +// log: true, // logs render info to console (default: false) +// }); +// } export const decorators = [(Story) => ]; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx index b8c52874..9ff2c0d1 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx @@ -38,6 +38,7 @@ import EmojiSelector from '../EmojiSelector'; import MessageCard from '../MessageCard'; import { MessageSkeletonCard } from '../MessageSkeletonCard'; import MessageTextField from '../MessageTextField'; +import { useJustWeb3 } from '@justweb3/widget'; export interface ChatProps { conversation: CachedConversation; @@ -45,6 +46,7 @@ export interface ChatProps { } export const Chat: React.FC = ({ conversation, onBack }) => { + const { openEnsProfile } = useJustWeb3(); const [replyMessage, setReplyMessage] = React.useState(null); const [reactionMessage, setReactionMessage] = @@ -125,7 +127,7 @@ export const Chat: React.FC = ({ conversation, onBack }) => { await refreshConsentList(); await allow([conversation.peerAddress]); void refreshConsentList(); - setIsRequest(false) + setIsRequest(false); setIsRequestChangeLoading(false); }; @@ -180,9 +182,17 @@ export const Chat: React.FC = ({ conversation, onBack }) => { additionalHeight.push('59px'); } - return `calc( ${height} ${additionalHeight.length > 0 ? ' - ' + additionalHeight.join(' - ') : '' - } )`; - }, [replyMessage, isMessagesSenderOnly, isStringContent, mimeType, type, isRequest]); + return `calc( ${height} ${ + additionalHeight.length > 0 ? ' - ' + additionalHeight.join(' - ') : '' + } )`; + }, [ + replyMessage, + isMessagesSenderOnly, + isStringContent, + mimeType, + type, + isRequest, + ]); return ( = ({ conversation, onBack }) => { }} /> - + { + if (primaryName) { + openEnsProfile(primaryName); + } + }} + > = ({ conversation, onBack }) => { - + = ({ conversation, onBack }) => { }} /> - = ({ conversation, onBack }) => { style={{ cursor: 'pointer', }} - fill='var(--justweb3-background-color)' + fill="var(--justweb3-background-color)" />

[]; handleOpenChat: ( conversation: CachedConversation | null ) => void; - blockedList?: boolean + blockedList?: boolean; } export const ChatList: React.FC = ({ conversations, handleOpenChat, - blockedList + blockedList, }) => { + const { allPrimaryNames } = usePrimaryNameBatch({ + addresses: conversations.map((conversation) => conversation.peerAddress), + }); + return ( - + {conversations.map((conversation) => ( handleOpenChat(conversation)} key={conversation.topic} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx index 54a37098..780480f3 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, - TabsTrigger + TabsTrigger, } from '@justweb3/ui'; import { CachedConversation, @@ -33,12 +33,12 @@ export const ChatSheet: React.FC = ({ open, handleOpen, handleOpenChat, - handleNewChat + handleNewChat, }) => { const [tab, setTab] = React.useState('Chats'); const { conversations, isLoading } = useConversations(); const [isConsentListLoading, setIsConsentListLoading] = React.useState(true); - const { loadConsentList, entries, } = useConsent(); + const { loadConsentList, entries } = useConsent(); const allowedConversations = useMemo(() => { return conversations.filter( @@ -78,20 +78,27 @@ export const ChatSheet: React.FC = ({ Chats - + + width={35} + height={35} + /> = ({ Requests {requestConversations.length > 0 && ( = ({ height: 17, borderRadius: '50%', lineHeight: 0.5, - fontSize: '10px' + fontSize: '10px', }} - >{requestConversations.length} + > + {requestConversations.length} + )} = ({

Loading...
) : ( <> - + - + - + = ({ + ens, + env, +}) => { + const { closeEnsProfile } = useJustWeb3(); + const { handleOpenChatWithAddressOrEns } = useJustWeb3XMTP(); + const { records } = useRecords({ + ens, + chainId: 1, + }); + const [canMessageAddress, setCanMessageAddress] = useState( + null + ); + + console.log('records', records, canMessageAddress); + const { canMessage } = useCanMessage(); + + useEffect(() => { + if (canMessageAddress === null) { + if (records) { + if (records?.sanitizedRecords?.ethAddress) { + console.log( + 'records?.sanitizedRecords?.ethAddress?.value', + records?.sanitizedRecords?.ethAddress?.value + ); + Client.canMessage(records?.sanitizedRecords?.ethAddress?.value, { + env: 'production', + }).then((canMessage) => { + console.log('canMessage', canMessage); + setCanMessageAddress(canMessage); + }); + } + } + } + }, [canMessage, canMessageAddress, records]); + + return ( +
+ { + if (!canMessageAddress) { + return; + } + closeEnsProfile(); + handleOpenChatWithAddressOrEns(ens); + }} + > + + +
+ ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx index 0babf793..e7abb66d 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx @@ -8,7 +8,7 @@ import { useLastMessage, useStreamMessages, } from '@xmtp/react-sdk'; -import { useEnsAvatar, usePrimaryName, useRecords } from '@justaname.id/react'; +import { useEnsAvatar, useRecords } from '@justaname.id/react'; import { Avatar, Button, Flex, formatText, P, SPAN } from '@justweb3/ui'; import React, { useMemo } from 'react'; import { formatChatDate } from '../../utils/formatChatDate'; @@ -17,18 +17,20 @@ export interface MessageItemProps { conversation: CachedConversation; onClick?: () => void; blocked?: boolean; + primaryName?: string; } export const MessageItem: React.FC = ({ conversation, onClick, blocked, + primaryName, }) => { const lastMessage = useLastMessage(conversation.topic); useStreamMessages(conversation); - const { primaryName } = usePrimaryName({ - address: conversation.peerAddress as `0x${string}`, - }); + // const { primaryName } = usePrimaryName({ + // address: conversation.peerAddress as `0x${string}`, + // }); const { records } = useRecords({ ens: primaryName, }); @@ -89,10 +91,10 @@ export const MessageItem: React.FC = ({ src={ primaryName ? sanitizeEnsImage({ - name: primaryName, - chainId: 1, - image: records?.sanitizedRecords?.avatar, - }) + name: primaryName, + chainId: 1, + image: records?.sanitizedRecords?.avatar, + }) : undefined } /> @@ -101,7 +103,9 @@ export const MessageItem: React.FC = ({ direction={'column'} style={{ marginLeft: '10px', - maxWidth: 'calc(100% - 50px - 32px - 10px)', + maxWidth: blocked + ? 'calc(100% - 120px)' + : 'calc(100% - 50px - 32px - 10px)', justifyContent: 'space-between', }} > diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx index 5a5954ad..40d89c38 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx @@ -1,300 +1,320 @@ import { - CachedConversation, - toCachedConversation, - useCanMessage, - useClient, - useConsent, - useConversation, - useStartConversation, + CachedConversation, + toCachedConversation, + useCanMessage, + useClient, + useConsent, + useConversation, + useStartConversation, } from '@xmtp/react-sdk'; import React, { useEffect, useMemo } from 'react'; import MessageTextField from '../MessageTextField'; import { useDebounce } from '@justweb3/widget'; import { - useMountedAccount, - usePrimaryName, - useRecords, + useMountedAccount, + usePrimaryName, + useRecords, } from '@justaname.id/react'; -import { ArrowIcon, CloseIcon, Flex, Input, LoadingSpinner, P, VerificationsIcon } from '@justweb3/ui'; - +import { + ArrowIcon, + CloseIcon, + Flex, + Input, + LoadingSpinner, + P, + VerificationsIcon, +} from '@justweb3/ui'; interface NewConversationProps { - onChatStarted: (conversation: CachedConversation) => void; - onBack: () => void; - selectedAddress?: string; + onChatStarted: (conversation: CachedConversation) => void; + onBack: () => void; + selectedAddress?: string; } const NewConversation: React.FC = ({ - onChatStarted, - onBack, - selectedAddress, + onChatStarted, + onBack, + selectedAddress, }) => { - // States - const [newAddress, setNewAddress] = React.useState( - selectedAddress ?? '' - ); - const [canMessage, setCanMessage] = React.useState(false); - //Queries - const { client } = useClient(); - const { startConversation } = useStartConversation(); - const { getCachedByPeerAddress } = useConversation(); - const { refreshConsentList, allow } = useConsent(); - const { address } = useMountedAccount(); - const { canMessage: xmtpCanMessage, isLoading } = useCanMessage(); - const { debouncedValue: debouncedAddress } = useDebounce( - newAddress, - 500 - ); - - const isAddressName = useMemo(() => { - const ethAddressRegex = /^0x[a-fA-F0-9]{40}$/; - return ( - !ethAddressRegex.test(debouncedAddress) && - debouncedAddress.length > 0 - ); - }, [debouncedAddress]); + // States + const [newAddress, setNewAddress] = React.useState( + selectedAddress ?? '' + ); + const [canMessage, setCanMessage] = React.useState(false); + //Queries + const { client } = useClient(); + const { startConversation } = useStartConversation(); + const { getCachedByPeerAddress } = useConversation(); + const { refreshConsentList, allow } = useConsent(); + const { address } = useMountedAccount(); + const { canMessage: xmtpCanMessage, isLoading } = useCanMessage(); + const { + debouncedValue: debouncedAddress, + isDebouncing: isDebouncingAddress, + } = useDebounce(newAddress, 500); + const isAddressName = useMemo(() => { + const ethAddressRegex = /^0x[a-fA-F0-9]{40}$/; + return ( + !ethAddressRegex.test(debouncedAddress) && debouncedAddress.length > 0 + ); + }, [debouncedAddress]); - const { records, isRecordsLoading } = useRecords({ - ens: debouncedAddress, - enabled: isAddressName - }); - - const { primaryName: name, isPrimaryNameLoading } = usePrimaryName({ - address: debouncedAddress as `0x${string}`, - enabled: !isAddressName - }); + const { records, isRecordsLoading, isRecordsFetching } = useRecords({ + ens: debouncedAddress, + enabled: isAddressName, + }); + const { + primaryName: name, + isPrimaryNameLoading, + isPrimaryNameFetching, + } = usePrimaryName({ + address: debouncedAddress as `0x${string}`, + enabled: !isAddressName, + }); - const resolvedAddress = useMemo(() => { - return records?.sanitizedRecords?.ethAddress?.value; - }, [records]); + console.log(records); + const resolvedAddress = useMemo(() => { + return records?.sanitizedRecords?.ethAddress?.value; + }, [records]); - const handleCanMessage = async () => { - if (!client) return; - try { - if (isAddressName) { - if (resolvedAddress) { - const res = await xmtpCanMessage(resolvedAddress); - setCanMessage(res); - } else { - // Resolved address is not available yet; do nothing - return; - } - } else if (debouncedAddress.length === 42) { - const res = await xmtpCanMessage(debouncedAddress); - setCanMessage(res); - } else { - setCanMessage(false); - } - } catch (e) { - console.log('error', e); - setCanMessage(false); - } - }; - - const handleNewConversation = async (message: string) => { - if (!client) return; - const peerAddress = - isAddressName && !!resolvedAddress ? resolvedAddress : debouncedAddress; - try { - const conv = await startConversation(peerAddress, message ?? {}); - if (!conv.cachedConversation) { - if (!conv.conversation) { - return; - } else { - const cachedConvo = toCachedConversation( - conv.conversation, - address ?? '' - ); - await allow([conv.conversation.peerAddress]); - await refreshConsentList(); - onChatStarted(cachedConvo); - onBack(); - } - } else { - await allow([conv.cachedConversation.peerAddress]); - await refreshConsentList(); - onChatStarted(conv.cachedConversation); - onBack(); - } - } catch (error) { - const e = error as Error; - console.log('error creating chat', e); - } - }; - - const checkIfConversationExists = async (peerAddress: string) => { - const convoExists = await getCachedByPeerAddress(peerAddress); - if (convoExists) { - onChatStarted(convoExists); + const handleCanMessage = async () => { + if (!client) return; + try { + if (isAddressName) { + if (resolvedAddress) { + const res = await xmtpCanMessage(resolvedAddress); + setCanMessage(res); + } else { + // Resolved address is not available yet; do nothing + return; } - }; + } else if (debouncedAddress.length === 42) { + const res = await xmtpCanMessage(debouncedAddress); + setCanMessage(res); + } else { + setCanMessage(false); + } + } catch (e) { + console.log('error', e); + setCanMessage(false); + } + }; - useEffect(() => { - if (debouncedAddress.length === 0) { - setCanMessage(false); - return; - } - if (isAddressName) { - if (!isRecordsLoading && resolvedAddress) { - handleCanMessage(); - } + const handleNewConversation = async (message: string) => { + if (!client) return; + const peerAddress = + isAddressName && !!resolvedAddress ? resolvedAddress : debouncedAddress; + try { + const conv = await startConversation(peerAddress, message ?? {}); + if (!conv.cachedConversation) { + if (!conv.conversation) { + return; } else { - if (!isLoading && !isPrimaryNameLoading) { - handleCanMessage(); - } + const cachedConvo = toCachedConversation( + conv.conversation, + address ?? '' + ); + await allow([conv.conversation.peerAddress]); + await refreshConsentList(); + onChatStarted(cachedConvo); + onBack(); } - }, [ - debouncedAddress, - isLoading, - isPrimaryNameLoading, - isRecordsLoading, - resolvedAddress, - isAddressName - ]); - + } else { + await allow([conv.cachedConversation.peerAddress]); + await refreshConsentList(); + onChatStarted(conv.cachedConversation); + onBack(); + } + } catch (error) { + const e = error as Error; + console.log('error creating chat', e); + } + }; - useEffect(() => { - const checkConversation = async () => { - if (canMessage) { - await checkIfConversationExists( - isAddressName && resolvedAddress ? resolvedAddress : debouncedAddress - ); - } - }; + const checkIfConversationExists = async (peerAddress: string) => { + const convoExists = await getCachedByPeerAddress(peerAddress); + if (convoExists) { + onChatStarted(convoExists); + } + }; - checkConversation(); - }, [canMessage, resolvedAddress, debouncedAddress]); + useEffect(() => { + if (debouncedAddress.length === 0) { + setCanMessage(false); + return; + } + if (isAddressName) { + if (!isRecordsLoading && resolvedAddress) { + handleCanMessage(); + } + } else { + if (!isLoading && !isPrimaryNameLoading) { + handleCanMessage(); + } + } + }, [ + debouncedAddress, + isLoading, + isPrimaryNameLoading, + isRecordsLoading, + resolvedAddress, + isAddressName, + ]); - - const isSearchLoading = useMemo(() => { - return ( - (isAddressName && isPrimaryNameLoading && debouncedAddress.length > 4) || - isLoading + useEffect(() => { + const checkConversation = async () => { + if (canMessage) { + await checkIfConversationExists( + isAddressName && resolvedAddress ? resolvedAddress : debouncedAddress ); - }, [isLoading, debouncedAddress, resolvedAddress, isAddressName]); + } + }; + checkConversation(); + }, [ + canMessage, + resolvedAddress, + debouncedAddress, + checkIfConversationExists, + isAddressName, + ]); - useEffect(() => { - if (isRecordsLoading || isPrimaryNameLoading) { - return; - } + const isSearchLoading = useMemo(() => { + return ( + // (isAddressName && isPrimaryNameLoading && debouncedAddress.length > 4) || + // isLoading + isDebouncingAddress || isRecordsFetching || isPrimaryNameFetching + ); + }, [isDebouncingAddress, isRecordsFetching, isPrimaryNameFetching]); + // }, [isAddressName, isPrimaryNameLoading, debouncedAddress.length, isLoading]); - if (name) { - setNewAddress(name); - return; - } - }, [name, isRecordsLoading, isPrimaryNameLoading]); + useEffect(() => { + if (isRecordsLoading || isPrimaryNameLoading) { + return; + } - return ( + if (name) { + setNewAddress(name); + return; + } + }, [name, isRecordsLoading, isPrimaryNameLoading]); + + return ( + + + - - - - - -

- To -

- {isSearchLoading ? ( - - ) : ( - debouncedAddress.length > 0 ? - - : null - )} -
- } - right={ - isSearchLoading ? ( - - ) : ( - - { - setNewAddress(''); - }} - > - - - - ) - } - placeholder={'ENS, Wallet Address...'} - onChange={(e) => setNewAddress(e.target.value)} - style={{ - flex: 1, - height: 22, - maxHeight: 22!, - gap: 5, - }} - /> -
- + + +

- + To +

+ {isSearchLoading ? ( + + ) : debouncedAddress.length > 0 ? ( + + ) : null}
-
- ); + } + right={ + isSearchLoading ? ( + + ) : ( + + { + setNewAddress(''); + }} + > + + + + ) + } + placeholder={'ENS, Wallet Address...'} + onChange={(e) => setNewAddress(e.target.value)} + style={{ + flex: 1, + height: 22, + maxHeight: 22!, + gap: 5, + }} + /> +
+ + + + + ); }; export default NewConversation; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/NewMessageSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/NewMessageSheet/index.tsx index 33213d9e..69a14e41 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/NewMessageSheet/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/NewMessageSheet/index.tsx @@ -4,25 +4,33 @@ import NewConversation from '../NewConversation'; export interface MessageSheetProps { openNewChat: boolean; - handleOpenNewChat: ( - open: boolean - ) => void; + handleOpenNewChat: (open: boolean) => void; onChatStarted: (conversation: CachedConversation) => void; + addressOrEns?: string; } export const NewMessageSheet: React.FC = ({ handleOpenNewChat, openNewChat, - onChatStarted + onChatStarted, + addressOrEns, }) => { return ( !open && handleOpenNewChat(false)} > - + New Conversation - handleOpenNewChat(false)} /> + handleOpenNewChat(false)} + selectedAddress={addressOrEns} + /> ); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx index fd6a6032..8f826f08 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx @@ -1,11 +1,12 @@ import { JustaPlugin } from '@justweb3/widget'; import { JustWeb3XMTPProvider } from '../providers/JustWeb3XMTPProvider'; import { ChatButton } from '../components/ChatButton'; +import { ChatWithProfileButton } from '../components/ChatWithProfileButton'; export type XmtpEnvironment = 'local' | 'production' | 'dev'; export const XMTPPlugin = (env: XmtpEnvironment): JustaPlugin => { - return ({ + return { name: 'XMTPPlugin', components: { Provider: (pluginApi, children) => { @@ -18,6 +19,9 @@ export const XMTPPlugin = (env: XmtpEnvironment): JustaPlugin => { ); }, + ProfileHeader: (pluginApi, ens, chainId, address) => { + return ; + }, SignInMenu: (pluginApi) => { return ( { /> ); }, - } - }) + }, + }; }; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx index f7824e73..a8b0297d 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx @@ -19,7 +19,9 @@ const contentTypeConfigs = [ replyContentTypeConfig, ]; -interface JustWeb3XMTPContextProps { } +interface JustWeb3XMTPContextProps { + handleOpenChatWithAddressOrEns: (addressOrEns: string) => void; +} const JustWeb3XMTPContext = React.createContext< JustWeb3XMTPContextProps | undefined @@ -38,6 +40,8 @@ export const JustWeb3XMTPProvider: React.FC = ({ }) => { const [isXmtpEnabled, setIsXmtpEnabled] = React.useState(false); const [isNewChat, setIsNewChat] = React.useState(false); + const [isNewChatWithAddressOrEns, setIsNewChatWithAddressOrEns] = + React.useState(''); const [conversation, setConversation] = React.useState | null>(null); const handleXmtpEnabled = (enabled: boolean) => { @@ -56,11 +60,20 @@ export const JustWeb3XMTPProvider: React.FC = ({ const handleNewChat = () => { setIsNewChat(true); - } + }; + + const handleNewChatWithAddressOrEns = (addressOrEns: string) => { + setIsNewChat(true); + setIsNewChatWithAddressOrEns(addressOrEns); + }; return ( - + = ({ openNewChat={isNewChat} handleOpenNewChat={handleOpenNewChat} onChatStarted={handleOpenChat} + addressOrEns={isNewChatWithAddressOrEns} /> {isXmtpEnabled && ( = ({ open, handleXmtpEnabled }) => { return null; }; + +export const useJustWeb3XMTP = () => { + const context = React.useContext(JustWeb3XMTPContext); + if (context === undefined) { + throw new Error( + 'useJustWeb3XMTP must be used within a JustWeb3XMTPProvider' + ); + } + return context; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx index f69bc4e4..097feea4 100644 --- a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx +++ b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx @@ -20,7 +20,6 @@ import { XMTPPlugin } from '../lib'; import { EFPPlugin } from '@justweb3/efp-plugin'; import { TalentProtocolPlugin } from '@justweb3/talent-protocol-plugin'; import { POAPPlugin } from '@justweb3/poap-plugin'; -import { JustVerifiedPlugin } from '@justverified/plugin'; const queryClient = new QueryClient(); @@ -51,7 +50,7 @@ const JustWeb3Config: JustWeb3ProviderConfig = { // // allowedEns: 'all', // // dev: import.meta.env.STORYBOOK_APP_DEV === 'true', plugins: [ - XMTPPlugin, + XMTPPlugin('production'), EFPPlugin, POAPPlugin({ apiKey: import.meta.env.STORYBOOK_APP_POAP_KEY, @@ -59,12 +58,12 @@ const JustWeb3Config: JustWeb3ProviderConfig = { TalentProtocolPlugin({ apiKey: import.meta.env.STORYBOOK_APP_TALENT_PROTOCOL_API_KEY, }), - JustVerifiedPlugin(['email', 'telegram', 'twitter', 'discord']), + // JustVerifiedPlugin(['email', 'telegram', 'twitter', 'discord']), ], - color: { - primary: '#FF00FF', - background: '#000000', - }, + // color: { + // primary: '#FF00FF', + // background: '#000000', + // }, }; export const Example = () => { From f5a98b2af3747c46fbd0e135fcbbdd968c168305 Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Thu, 5 Dec 2024 12:31:40 +0200 Subject: [PATCH 25/29] feat: console xmtp --- .../PluginsSection/{Verified => JustVerified}/index.tsx | 0 .../{Verified => JustVerified}/socialCard/index.tsx | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename apps/console/src/components/sections/customizer/PluginsSection/{Verified => JustVerified}/index.tsx (100%) rename apps/console/src/components/sections/customizer/PluginsSection/{Verified => JustVerified}/socialCard/index.tsx (100%) diff --git a/apps/console/src/components/sections/customizer/PluginsSection/Verified/index.tsx b/apps/console/src/components/sections/customizer/PluginsSection/JustVerified/index.tsx similarity index 100% rename from apps/console/src/components/sections/customizer/PluginsSection/Verified/index.tsx rename to apps/console/src/components/sections/customizer/PluginsSection/JustVerified/index.tsx diff --git a/apps/console/src/components/sections/customizer/PluginsSection/Verified/socialCard/index.tsx b/apps/console/src/components/sections/customizer/PluginsSection/JustVerified/socialCard/index.tsx similarity index 100% rename from apps/console/src/components/sections/customizer/PluginsSection/Verified/socialCard/index.tsx rename to apps/console/src/components/sections/customizer/PluginsSection/JustVerified/socialCard/index.tsx From 3ade8bebc60b157da8a439be1d5b1ae73e2c98cd Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Thu, 5 Dec 2024 14:56:06 +0200 Subject: [PATCH 26/29] feat: console --- apps/console/src/app/page.tsx | 1 + apps/console/src/app/providers.tsx | 1 + .../sections/code/CodeSection/index.tsx | 22 ++- .../PluginsSection/JustVerified/index.tsx | 2 +- .../customizer/PluginsSection/XMTP/index.tsx | 49 ++++++ .../customizer/PluginsSection/index.tsx | 7 +- apps/console/src/layout/navbar/index.tsx | 2 +- .../react/src/lib/hooks/records/useRecords.ts | 3 - .../xmtp-plugin/.storybook/preview.tsx | 13 +- .../lib/components/AllMessageSheet/index.tsx | 56 +++++++ .../src/lib/components/Chat/index.tsx | 11 +- .../src/lib/components/ChatButton/index.tsx | 26 ++-- .../src/lib/components/ChatList/index.tsx | 2 +- .../src/lib/components/ChatSheet/index.tsx | 3 +- .../ChatWithProfileButton/index.tsx | 76 ++++++++-- .../src/lib/components/MessageItem/index.tsx | 4 +- .../lib/components/MessageTextField/index.tsx | 15 +- .../lib/components/NewConversation/index.tsx | 1 - .../src/lib/hooks/useEthersSigner/index.ts | 28 ++-- .../xmtp-plugin/src/lib/plugins/index.tsx | 3 +- .../providers/JustWeb3XMTPProvider/index.tsx | 141 ++++++++++++------ .../xmtp-plugin/src/stories/xmtp.stories.tsx | 36 +++-- 22 files changed, 372 insertions(+), 130 deletions(-) create mode 100644 apps/console/src/components/sections/customizer/PluginsSection/XMTP/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/AllMessageSheet/index.tsx diff --git a/apps/console/src/app/page.tsx b/apps/console/src/app/page.tsx index 197422c9..3de9aa76 100644 --- a/apps/console/src/app/page.tsx +++ b/apps/console/src/app/page.tsx @@ -40,6 +40,7 @@ export default function Page() { + diff --git a/apps/console/src/app/providers.tsx b/apps/console/src/app/providers.tsx index f709020d..b4b11657 100644 --- a/apps/console/src/app/providers.tsx +++ b/apps/console/src/app/providers.tsx @@ -63,6 +63,7 @@ export const Providers: React.FC = (props) => { providerUrl: process.env.NEXT_PUBLIC_SEPOLIA_PROVIDER_URL as string, }, ], + enableAuth: true, openOnWalletConnect: true, allowedEns: 'all', disableOverlay: true, diff --git a/apps/console/src/components/sections/code/CodeSection/index.tsx b/apps/console/src/components/sections/code/CodeSection/index.tsx index c4da154f..31b2bc7d 100644 --- a/apps/console/src/components/sections/code/CodeSection/index.tsx +++ b/apps/console/src/components/sections/code/CodeSection/index.tsx @@ -32,6 +32,11 @@ export const CodeSection: React.FC = ({ mobile }) => { [config] ); + const xmtpPluginEnabled = useMemo( + () => config.plugins?.find((p) => p.name === 'XMTPPlugin'), + [config] + ); + const codeSnippet = useMemo(() => { const plugins = []; @@ -57,6 +62,10 @@ export const CodeSection: React.FC = ({ mobile }) => { ); } + if (xmtpPluginEnabled) { + plugins.push("%%XMTPPlugin('production')%%"); + } + return ` import '@rainbow-me/rainbowkit/styles.css'; import '@justweb3/widget/styles.css'; @@ -97,6 +106,9 @@ ${ ? "import { TalentProtocolPlugin } from '@justweb3/talent-protocol-plugin';" : '' } +${ + xmtpPluginEnabled ? "import { XMTPPlugin } from '@justweb3/xmtp-plugin';" : '' +} export const App: React.FC = () => { const { wallets } = getDefaultWallets(); @@ -163,6 +175,7 @@ export default App;`.trim(); justVerifiedEnabled, poapPluginEnabled, talentProtocolPluginEnabled, + xmtpPluginEnabled, ]); const code = useMemo(() => { @@ -172,9 +185,11 @@ export default App;`.trim(); }, [codeSnippet]); const dependencies = useMemo(() => { - return `yarn add ${justVerifiedEnabled ? '@justverified/plugin' : ''} ${ - poapPluginEnabled ? '@justweb3/poap-plugin' : '' - } ${efpPluginEnabled ? '@justweb3/efp-plugin' : ''} + return `yarn add ${xmtpPluginEnabled ? '@justweb3/xmtp-plugin' : ''} ${ + justVerifiedEnabled ? '@justverified/plugin' : '' + } ${poapPluginEnabled ? '@justweb3/poap-plugin' : ''} ${ + efpPluginEnabled ? '@justweb3/efp-plugin' : '' + } ${talentProtocolPluginEnabled ? '@justweb3/talent-protocol-plugin' : ''} @justweb3/widget viem wagmi @rainbow-me/rainbowkit @tanstack/react-query ethers`; }, [ @@ -182,6 +197,7 @@ export default App;`.trim(); justVerifiedEnabled, poapPluginEnabled, talentProtocolPluginEnabled, + xmtpPluginEnabled, ]); const handleDependenciesCopy = () => { diff --git a/apps/console/src/components/sections/customizer/PluginsSection/JustVerified/index.tsx b/apps/console/src/components/sections/customizer/PluginsSection/JustVerified/index.tsx index 1c6ca75e..882d8b18 100644 --- a/apps/console/src/components/sections/customizer/PluginsSection/JustVerified/index.tsx +++ b/apps/console/src/components/sections/customizer/PluginsSection/JustVerified/index.tsx @@ -45,7 +45,7 @@ const socials: { logo: ReactNode; title: string; credential: Credentials }[] = [ }, ]; -export const Verified = () => { +export const JustVerified = () => { const { handleJustWeb3Config, config } = useContext(JustWeb3Context); const { justVerified, setJustVerified } = useConsole(); diff --git a/apps/console/src/components/sections/customizer/PluginsSection/XMTP/index.tsx b/apps/console/src/components/sections/customizer/PluginsSection/XMTP/index.tsx new file mode 100644 index 00000000..aa17765f --- /dev/null +++ b/apps/console/src/components/sections/customizer/PluginsSection/XMTP/index.tsx @@ -0,0 +1,49 @@ +// import { AccordionItem, AccordionTrigger } from '../../../../ui/accordion'; +import { Switch } from '../../../../ui/switch'; +import { useContext } from 'react'; +import { JustWeb3Context } from '@justweb3/widget'; +import { XMTPPlugin } from '@justweb3/xmtp-plugin'; + +export const XMTP = () => { + const { handleJustWeb3Config, config } = useContext(JustWeb3Context); + + const handleEFPConfig = (enabled: boolean) => { + if (enabled) { + handleJustWeb3Config({ + ...config, + plugins: [ + ...(config?.plugins || []).filter( + (plugin) => plugin.name !== XMTPPlugin.name + ), + XMTPPlugin('production'), + ], + }); + } else { + handleJustWeb3Config({ + ...config, + plugins: (config?.plugins || []).filter( + (plugin) => plugin.name !== XMTPPlugin.name + ), + }); + } + }; + + return ( +
+

+ XMTP +

+ plugin.name === XMTPPlugin.name) + } + onClick={(e) => { + e.stopPropagation(); + }} + onCheckedChange={(checked) => { + handleEFPConfig(checked); + }} + /> +
+ ); +}; diff --git a/apps/console/src/components/sections/customizer/PluginsSection/index.tsx b/apps/console/src/components/sections/customizer/PluginsSection/index.tsx index 5d4e59bd..06321f97 100644 --- a/apps/console/src/components/sections/customizer/PluginsSection/index.tsx +++ b/apps/console/src/components/sections/customizer/PluginsSection/index.tsx @@ -1,9 +1,10 @@ import { FC } from 'react'; import { Accordion } from '../../../ui/accordion'; -import { Verified } from './Verified'; +import { JustVerified } from './JustVerified'; import { EFP } from './EFP'; import { POAP } from './POAP'; import { TalentProtocol } from './TalentProtocol'; +import { XMTP } from './XMTP'; export const PluginsSection: FC = () => { return ( @@ -13,12 +14,14 @@ export const PluginsSection: FC = () => {

- +
+
+
); diff --git a/apps/console/src/layout/navbar/index.tsx b/apps/console/src/layout/navbar/index.tsx index e0cc0afb..0c376170 100644 --- a/apps/console/src/layout/navbar/index.tsx +++ b/apps/console/src/layout/navbar/index.tsx @@ -5,7 +5,7 @@ import Link from 'next/link'; export const Navbar = () => { return ( -
+
{/*JustName*/} diff --git a/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts b/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts index b9918bd8..04913bc8 100644 --- a/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts +++ b/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts @@ -100,7 +100,6 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { chainId: _params.chainId, }); - console.log(__ens, result); checkEnsValid(result); const sanitized = sanitizeRecords(result); @@ -152,7 +151,6 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { }, }; - console.log(__ens, record); checkEnsValid(record); const sanitized = sanitizeRecords(record); @@ -240,7 +238,6 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { const query = useQuery({ ...defaultOptions, retry: (failureCount, error) => { - console.log(error); if (error instanceof Error) { if ( error.message.includes('NotFound') || diff --git a/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx b/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx index d4619ace..0b60c255 100644 --- a/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx +++ b/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx @@ -1,10 +1,11 @@ import './polyfills'; +import { scan } from 'react-scan'; -// if (typeof window !== 'undefined') { -// scan({ -// enabled: true, -// log: true, // logs render info to console (default: false) -// }); -// } +if (typeof window !== 'undefined') { + scan({ + enabled: true, + log: true, // logs render info to console (default: false) + }); +} export const decorators = [(Story) => ]; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/AllMessageSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/AllMessageSheet/index.tsx new file mode 100644 index 00000000..95052086 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/AllMessageSheet/index.tsx @@ -0,0 +1,56 @@ +import { CachedConversation, ContentTypeMetadata } from '@xmtp/react-sdk'; +import { Sheet, SheetContent, SheetTitle } from '@justweb3/ui'; +import { Chat } from '../Chat'; +import { useMemo } from 'react'; +import NewConversation from '../NewConversation'; + +export interface MessageSheetProps { + // peerAddress?: string | null; + peer: CachedConversation | string | null; + openChat: boolean; + closeChat: () => void; + onChangePeer: ( + peer: CachedConversation | string + ) => void; +} + +export const AllMessageSheet: React.FC = ({ + peer, + closeChat, + openChat, + onChangePeer, +}) => { + const isPeerConversation = useMemo(() => { + return typeof peer !== 'string'; + }, [peer]); + + return ( + !open && closeChat()}> + + + {isPeerConversation ? 'Messages' : 'New Conversation'} + + + {peer !== null && + (isPeerConversation ? ( + } + onBack={closeChat} + /> + ) : ( + { + onChangePeer(conversation); + }} + /> + ))} + + + ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx index 9ff2c0d1..3f454e35 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx @@ -214,7 +214,7 @@ export const Chat: React.FC = ({ conversation, onBack }) => { width: '100%', minWidth: '412px', height: '100%', - backgroundColor: 'rgba(255, 255, 255, 0.05)', + // backgroundColor: 'rgba(255, 255, 255, 0.05)', borderRadius: '16px', backdropFilter: reactionMessage ? 'blur(5px)' : 'none', @@ -280,10 +280,11 @@ export const Chat: React.FC = ({ conversation, onBack }) => { }) : undefined } - style={{ - width: 30, - height: 30, - }} + size={30} + // style={{ + // width: 30, + // height: 30, + // }} /> void; @@ -12,28 +12,28 @@ export interface ChatButtonProps { export const ChatButton: React.FC = ({ handleOpen, env }) => { const { initialize } = useClient(); const { client } = useClient(); - const walletClient = useEthersSigner() - const { address } = useMountedAccount() + const walletClient = useEthersSigner(); + const { address } = useMountedAccount(); const handleChat = async () => { if (!client) { - const signer = await walletClient + const signer = walletClient; try { if (!signer) { - return + return; } const clientOptions: Partial> = { appVersion: 'JustWeb3/1.0.0', - env: env - } - let keys = loadKeys(address ?? '', env) + env: env, + }; + let keys = loadKeys(address ?? '', env); if (!keys) { keys = await Client.getKeys(signer, { env: env, skipContactPublishing: false, // persistConversations: false, - }) - storeKeys(address ?? '', keys, env) + }); + storeKeys(address ?? '', keys, env); } await initialize({ keys, @@ -41,12 +41,12 @@ export const ChatButton: React.FC = ({ handleOpen, env }) => { signer: signer, }).then(() => { handleOpen(true); - }) + }); // handleClient(client) } catch (error) { - console.error('Failed to initialize XMTP Client:', error) - wipeKeys(address ?? '', env) + console.error('Failed to initialize XMTP Client:', error); + wipeKeys(address ?? '', env); } } else { handleOpen(true); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx index f9b4211e..3ff94d5f 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx @@ -7,7 +7,7 @@ import { usePrimaryNameBatch } from '@justaname.id/react'; export interface ChatListProps { conversations: CachedConversation[]; handleOpenChat: ( - conversation: CachedConversation | null + conversation: CachedConversation ) => void; blockedList?: boolean; } diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx index 780480f3..2bc46271 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx @@ -24,7 +24,7 @@ export interface ChatSheetProps { open?: boolean; handleOpen?: (open: boolean) => void; handleOpenChat: ( - conversation: CachedConversation | null + conversation: CachedConversation ) => void; handleNewChat: () => void; } @@ -37,6 +37,7 @@ export const ChatSheet: React.FC = ({ }) => { const [tab, setTab] = React.useState('Chats'); const { conversations, isLoading } = useConversations(); + console.log(conversations); const [isConsentListLoading, setIsConsentListLoading] = React.useState(true); const { loadConsentList, entries } = useConsent(); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatWithProfileButton/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatWithProfileButton/index.tsx index 7f9721cb..0e839180 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatWithProfileButton/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatWithProfileButton/index.tsx @@ -1,50 +1,96 @@ import { useJustWeb3XMTP } from '../../providers/JustWeb3XMTPProvider'; -import { useRecords } from '@justaname.id/react'; -import { useCanMessage } from '@xmtp/react-sdk'; +import { useMountedAccount, useRecords } from '@justaname.id/react'; +import { ClientOptions, useCanMessage, useClient } from '@xmtp/react-sdk'; import { useEffect, useState } from 'react'; import { useJustWeb3 } from '@justweb3/widget'; import { Client } from '@xmtp/xmtp-js'; +import { useEthersSigner } from '../../hooks'; +import { loadKeys, storeKeys, wipeKeys } from '../../utils/xmtp'; +import { ChainId } from '@justaname.id/sdk'; export interface ChatWithProfileButtonProps { ens: string; - env?: 'local' | 'production' | 'dev'; + env: 'local' | 'production' | 'dev'; + chainId: ChainId; } export const ChatWithProfileButton: React.FC = ({ ens, env, + chainId, }) => { const { closeEnsProfile } = useJustWeb3(); - const { handleOpenChatWithAddressOrEns } = useJustWeb3XMTP(); + const { handleOpenChat } = useJustWeb3XMTP(); const { records } = useRecords({ ens, - chainId: 1, + chainId: chainId, }); const [canMessageAddress, setCanMessageAddress] = useState( null ); - console.log('records', records, canMessageAddress); const { canMessage } = useCanMessage(); + const { initialize } = useClient(); + const { client } = useClient(); + const walletClient = useEthersSigner(); + const { address } = useMountedAccount(); + + const handleChat = async () => { + if (!records?.sanitizedRecords?.ethAddress?.value) { + return; + } + + if (!client) { + const signer = await walletClient; + try { + if (!signer) { + return; + } + const clientOptions: Partial> = { + appVersion: 'JustWeb3/1.0.0', + env: env, + }; + let keys = loadKeys(address ?? '', env); + if (!keys) { + keys = await Client.getKeys(signer, { + env: env, + skipContactPublishing: false, + // persistConversations: false, + }); + storeKeys(address ?? '', keys, env); + } + await initialize({ + keys, + options: clientOptions, + signer: signer, + }).then(() => { + handleOpenChat(ens); + }); + + // handleClient(client) + } catch (error) { + console.error('Failed to initialize XMTP Client:', error); + wipeKeys(address ?? '', env); + } + } else { + handleOpenChat(ens); + } + }; + useEffect(() => { if (canMessageAddress === null) { if (records) { if (records?.sanitizedRecords?.ethAddress) { - console.log( - 'records?.sanitizedRecords?.ethAddress?.value', - records?.sanitizedRecords?.ethAddress?.value - ); Client.canMessage(records?.sanitizedRecords?.ethAddress?.value, { - env: 'production', + env: env, }).then((canMessage) => { - console.log('canMessage', canMessage); setCanMessageAddress(canMessage); }); } } } - }, [canMessage, canMessageAddress, records]); + }, [canMessage, canMessageAddress, env, records]); return (
= ({ return; } closeEnsProfile(); - handleOpenChatWithAddressOrEns(ens); + if (records?.sanitizedRecords?.ethAddress?.value) { + handleChat(); + } }} > ; onClick?: () => void; blocked?: boolean; - primaryName?: string; + primaryName?: string | null; } export const MessageItem: React.FC = ({ @@ -32,7 +32,7 @@ export const MessageItem: React.FC = ({ // address: conversation.peerAddress as `0x${string}`, // }); const { records } = useRecords({ - ens: primaryName, + ens: primaryName || undefined, }); const { sanitizeEnsImage } = useEnsAvatar(); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx index c596cc07..6c6acbfc 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx @@ -58,7 +58,7 @@ const MessageTextField: React.FC = ({ conversation, onNewConvo, peerAddress, - style + style, }) => { const [messageValue, setMessageValue] = React.useState(''); const [attachment, setAttachment] = React.useState(); @@ -265,10 +265,10 @@ const MessageTextField: React.FC = ({ height: isReplyText ? '30px' : isReplyVoice - ? '45px' - : isReplyVideoOrImage - ? '100px' - : '30px', + ? '45px' + : isReplyVideoOrImage + ? '100px' + : '30px', borderRadius: '5px', background: 'white', paddingLeft: '14px', @@ -278,6 +278,7 @@ const MessageTextField: React.FC = ({ borderTopRightRadius: '25px', borderBottomRightRadius: 0, borderBottomLeftRadius: 0, + boxSizing: 'content-box', }} > = ({ height: 22, maxHeight: 22!, border: '1px solid grey', - paddingLeft: attachment?.mimeType === 'audio/wav' ? '5px' : '15px' + boxSizing: 'content-box', + paddingLeft: + attachment?.mimeType === 'audio/wav' ? '5px' : '15px', }} > {attachment?.mimeType !== 'audio/wav' && ( diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx index 40d89c38..8190c568 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx @@ -75,7 +75,6 @@ const NewConversation: React.FC = ({ enabled: !isAddressName, }); - console.log(records); const resolvedAddress = useMemo(() => { return records?.sanitizedRecords?.ethAddress?.value; }, [records]); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useEthersSigner/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useEthersSigner/index.ts index 6edf47fc..a9d0763a 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useEthersSigner/index.ts +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useEthersSigner/index.ts @@ -4,20 +4,28 @@ import type { Account, Chain, Client, Transport } from 'viem'; import { useWalletClient } from 'wagmi'; export function clientToSigner(client: Client) { - const { account, chain, transport } = client - if (!account || !chain || !transport) return undefined + const { account, chain, transport } = client; + if (!account || !chain || !transport) return undefined; const network = { chainId: chain?.id, name: chain?.name, ensAddress: chain?.contracts?.ensRegistry?.address, - } - const provider = new BrowserProvider(transport, network) - const signer = new JsonRpcSigner(provider, account.address) - return signer + }; + const provider = new BrowserProvider(transport, network); + const signer = new JsonRpcSigner(provider, account.address); + return signer; } /** Hook to convert a viem Wallet Client to an ethers.js Signer. */ -export async function useEthersSigner({ chainId }: { chainId?: number } = {}) { - const { data: client } = useWalletClient({ chainId }) - return useMemo(() => (client ? clientToSigner(client) : undefined), [client, client?.chain, client?.account, client?.transport]) -} +export const useEthersSigner = ({ chainId }: { chainId?: number } = {}): + | JsonRpcSigner + | undefined => { + const { data: client } = useWalletClient({ chainId }); + console.log(client); + const signer = useMemo( + () => (client ? clientToSigner(client) : undefined), + [client] + ); + console.log(signer); + return signer; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx index 8f826f08..63c919a9 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx @@ -14,13 +14,14 @@ export const XMTPPlugin = (env: XmtpEnvironment): JustaPlugin => { pluginApi.setState('xmtpOpen', open)} + env={env} > {children} ); }, ProfileHeader: (pluginApi, ens, chainId, address) => { - return ; + return ; }, SignInMenu: (pluginApi) => { return ( diff --git a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx index a8b0297d..fa2a772b 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx @@ -2,16 +2,19 @@ import React, { useEffect } from 'react'; import { attachmentContentTypeConfig, CachedConversation, + Client, + ClientOptions, ContentTypeMetadata, reactionContentTypeConfig, replyContentTypeConfig, useClient, XMTPProvider, } from '@xmtp/react-sdk'; -import { useJustWeb3 } from '@justweb3/widget'; import { ChatSheet } from '../../components/ChatSheet'; -import { MessageSheet } from '../../components/MessageSheet'; -import { NewMessageSheet } from '../../components/NewMessageSheet'; +import { useEthersSigner } from '../../hooks'; +import { useMountedAccount } from '@justaname.id/react'; +import { loadKeys, storeKeys, wipeKeys } from '../../utils/xmtp'; +import { AllMessageSheet } from '../../components/AllMessageSheet'; const contentTypeConfigs = [ attachmentContentTypeConfig, @@ -20,7 +23,7 @@ const contentTypeConfigs = [ ]; interface JustWeb3XMTPContextProps { - handleOpenChatWithAddressOrEns: (addressOrEns: string) => void; + handleOpenChat: (address: string) => void; } const JustWeb3XMTPContext = React.createContext< @@ -31,69 +34,59 @@ export interface JustWeb3XMTPProviderProps { children: React.ReactNode; open?: boolean; handleOpen?: (open: boolean) => void; + env: 'local' | 'production' | 'dev'; } export const JustWeb3XMTPProvider: React.FC = ({ children, open, handleOpen, + env, }) => { const [isXmtpEnabled, setIsXmtpEnabled] = React.useState(false); - const [isNewChat, setIsNewChat] = React.useState(false); - const [isNewChatWithAddressOrEns, setIsNewChatWithAddressOrEns] = - React.useState(''); const [conversation, setConversation] = React.useState | null>(null); const handleXmtpEnabled = (enabled: boolean) => { setIsXmtpEnabled(enabled); }; - - const handleOpenNewChat = (open: boolean) => { - setIsNewChat(open); - }; + const [peerAddress, setPeerAddress] = React.useState(null); const handleOpenChat = ( - conversation: CachedConversation | null + peer: string | CachedConversation ) => { - setConversation(conversation); - }; - - const handleNewChat = () => { - setIsNewChat(true); - }; - - const handleNewChatWithAddressOrEns = (addressOrEns: string) => { - setIsNewChat(true); - setIsNewChatWithAddressOrEns(addressOrEns); + if (typeof peer === 'string') { + setPeerAddress(peer); + } else { + setConversation(peer); + } }; return ( - - - + {isXmtpEnabled && ( handleOpenChat('')} /> )} + + { + setPeerAddress(null); + setConversation(null); + }} + onChangePeer={handleOpenChat} + peer={conversation ?? peerAddress ?? null} + /> {children} @@ -103,21 +96,81 @@ export const JustWeb3XMTPProvider: React.FC = ({ interface ChecksProps { open?: boolean; handleXmtpEnabled: (enabled: boolean) => void; + env: 'local' | 'production' | 'dev'; } -export const Checks: React.FC = ({ open, handleXmtpEnabled }) => { - const { connectedEns } = useJustWeb3(); - const { disconnect, client } = useClient(); +export const Checks: React.FC = ({ + open, + handleXmtpEnabled, + env, +}) => { + const { client, initialize, isLoading } = useClient(); + const signer = useEthersSigner(); + const { address } = useMountedAccount(); + const [isInitializing, setIsInitializing] = React.useState(false); + const [rejected, setRejected] = React.useState(false); + useEffect(() => { + async function initializeXmtp() { + if (isInitializing || isLoading || rejected) return; + console.log(signer); + try { + if (client) { + return; + } + + if (!signer) { + return; + } + setIsInitializing(true); + const clientOptions: Partial> = { + appVersion: 'JustWeb3/1.0.0/' + env + '/0', + env: env, + }; + let keys = loadKeys(address ?? '', env); + if (!keys) { + keys = await Client.getKeys(signer, { + env: env, + skipContactPublishing: false, + // persistConversations: false, + }); + storeKeys(address ?? '', keys, env); + } + console.log('Initializing XMTP Client:', keys); + await initialize({ + keys, + options: clientOptions, + signer: signer, + }); + setIsInitializing(false); + } catch (error) { + console.error('Failed to initialize XMTP Client:', error); + wipeKeys(address ?? '', env); + setIsInitializing(false); + setRejected(true); + } + } + initializeXmtp(); + }, [ + address, + client, + env, + handleXmtpEnabled, + initialize, + isInitializing, + isLoading, + rejected, + signer, + ]); useEffect(() => { handleXmtpEnabled(!!client); }, [client, handleXmtpEnabled]); - useEffect(() => { - if (!connectedEns?.ens) { - disconnect(); - } - }, [connectedEns?.ens, disconnect]); + // useEffect(() => { + // if (!address) { + // disconnect(); + // } + // }, [connectedEns?.ens, disconnect]); return null; }; diff --git a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx index 097feea4..03c180ca 100644 --- a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx +++ b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx @@ -94,22 +94,26 @@ export const Example = () => {
- - - - - - - - - - - - - - - - + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + {/**/} + Date: Thu, 5 Dec 2024 18:37:32 +0200 Subject: [PATCH 27/29] feat: xmtp fix nextjs config --- apps/console/next.config.js | 3 +++ .../react/src/lib/helpers/validateEns.ts | 12 +++++++++- .../react/src/lib/hooks/records/useRecords.ts | 23 +++++++++++++++---- .../src/lib/components/ChatSheet/index.tsx | 1 - .../src/lib/hooks/useEthersSigner/index.ts | 2 -- .../providers/JustWeb3XMTPProvider/index.tsx | 2 -- 6 files changed, 32 insertions(+), 11 deletions(-) diff --git a/apps/console/next.config.js b/apps/console/next.config.js index cffac9d0..55fe2990 100644 --- a/apps/console/next.config.js +++ b/apps/console/next.config.js @@ -13,6 +13,9 @@ const nextConfig = { // See: https://github.com/gregberge/svgr svgr: false, }, + experimental: { + serverComponentsExternalPackages: ['@xmtp/user-preferences-bindings-wasm'], + }, }; const plugins = [ diff --git a/packages/@justaname.id/react/src/lib/helpers/validateEns.ts b/packages/@justaname.id/react/src/lib/helpers/validateEns.ts index 0f58d763..684da86d 100644 --- a/packages/@justaname.id/react/src/lib/helpers/validateEns.ts +++ b/packages/@justaname.id/react/src/lib/helpers/validateEns.ts @@ -1,6 +1,6 @@ import { normalize } from 'viem/ens'; -export const validateEns = (name: string | undefined): string | undefined => { +export const normalizeEns = (name: string | undefined): string | undefined => { if (typeof name !== 'string' || name.trim() === '') { return; } @@ -13,3 +13,13 @@ export const validateEns = (name: string | undefined): string | undefined => { return; } }; + +export const validateEns = (name: string | undefined): boolean => { + const ensRegex = /(?:^|[^a-zA-Z0-9-_.])(([^\s.]{1,63}\.)+[^\s.]{2,63})/; + + if (typeof name !== 'string' || name.trim() === '') { + return false; + } + + return ensRegex.test(name); +}; diff --git a/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts b/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts index 04913bc8..2feb6b87 100644 --- a/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts +++ b/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts @@ -22,7 +22,7 @@ import { useEnsPublicClient } from '../client/useEnsPublicClient'; import { useOffchainResolvers } from '../offchainResolver'; import { getRecords as getEnsRecords } from '@ensdomains/ensjs/public'; import { checkEnsValid } from '../../helpers/checkEnsValid'; -import { validateEns } from '../../helpers/validateEns'; +import { normalizeEns, validateEns } from '../../helpers/validateEns'; export const buildRecordsBySubnameKey = ( subname: string, @@ -73,7 +73,7 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { () => params?.chainId || chainId, [params?.chainId, chainId] ); - const _ens = useMemo(() => validateEns(params?.ens), [params?.ens]); + const _ens = useMemo(() => normalizeEns(params?.ens), [params?.ens]); const { offchainResolvers } = useOffchainResolvers(); const { ensClient } = useEnsPublicClient({ chainId: _chainId, @@ -88,12 +88,16 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { const getRecords = async ( _params: SubnameRecordsRoute['params'] ): Promise => { - const __ens = validateEns(_params.ens); + const __ens = normalizeEns(_params.ens); if (!__ens) { throw new Error('Invalid ENS name'); } + if (!validateEns(__ens)) { + throw new Error('Invalid ENS name'); + } + const result = await justaname.subnames.getRecords({ ens: __ens, providerUrl: _params.providerUrl, @@ -117,12 +121,16 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { throw new Error('Public client not found'); } - const __ens = validateEns(_params.ens) || _ens; + const __ens = normalizeEns(_params.ens) || _ens; if (!__ens) { throw new Error('Invalid ENS name'); } + if (!validateEns(__ens)) { + throw new Error('Invalid ENS name'); + } + const result = await getEnsRecords(ensClient, { name: __ens, coins: Object.keys(coinTypeMap), @@ -166,10 +174,14 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { forceUpdate = false ): Promise => { const __chainId = _params?.chainId || _chainId; - const __ens = validateEns(_params?.ens) || _ens; + const __ens = normalizeEns(_params?.ens) || _ens; if (!__ens) { throw new Error('Invalid ENS name'); } + + if (!validateEns(__ens)) { + throw new Error('Invalid ENS name'); + } // const __standard = _params?.standard || params?.standard; const __standard = false; if (!forceUpdate) { @@ -265,6 +277,7 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { Boolean(_ens) && Boolean(_chainId) && Boolean(_providerUrl) && + Boolean(validateEns(_ens)) && Boolean(_enabled), }); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx index 2bc46271..98960a88 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx @@ -37,7 +37,6 @@ export const ChatSheet: React.FC = ({ }) => { const [tab, setTab] = React.useState('Chats'); const { conversations, isLoading } = useConversations(); - console.log(conversations); const [isConsentListLoading, setIsConsentListLoading] = React.useState(true); const { loadConsentList, entries } = useConsent(); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useEthersSigner/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useEthersSigner/index.ts index a9d0763a..ce6ac392 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useEthersSigner/index.ts +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useEthersSigner/index.ts @@ -21,11 +21,9 @@ export const useEthersSigner = ({ chainId }: { chainId?: number } = {}): | JsonRpcSigner | undefined => { const { data: client } = useWalletClient({ chainId }); - console.log(client); const signer = useMemo( () => (client ? clientToSigner(client) : undefined), [client] ); - console.log(signer); return signer; }; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx index fa2a772b..05d06fc5 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx @@ -112,7 +112,6 @@ export const Checks: React.FC = ({ useEffect(() => { async function initializeXmtp() { if (isInitializing || isLoading || rejected) return; - console.log(signer); try { if (client) { return; @@ -135,7 +134,6 @@ export const Checks: React.FC = ({ }); storeKeys(address ?? '', keys, env); } - console.log('Initializing XMTP Client:', keys); await initialize({ keys, options: clientOptions, From d4572e609e65b1298b73b75013de9728317c465d Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Fri, 6 Dec 2024 15:02:26 +0200 Subject: [PATCH 28/29] feat: xmtp refactor and unread count --- .../NotificationBadge.module.css | 27 + .../ui/src/lib/ui/NotificationBadge/index.tsx | 30 + packages/@justweb3/ui/src/lib/ui/index.ts | 1 + .../stories/ui/notification-badge.stories.tsx | 57 ++ .../lib/components/JustWeb3Button/index.tsx | 35 +- .../lib/components/AllMessageSheet/index.tsx | 56 -- .../src/lib/components/Chat/index.tsx | 618 ----------------- .../{ChatButton => ChatMenuButton}/index.tsx | 48 +- .../ChatSheet/Chat/ChatHeader/index.tsx | 157 +++++ .../ChatMessagesList/DateDivider/index.tsx | 43 ++ .../ChatMessagesList/EmojiSelector/index.tsx | 85 +++ .../ChatMessagesList}/MessageCard/index.tsx | 50 +- .../ChatSheet/Chat/ChatMessagesList/index.tsx | 102 +++ .../Chat/ChatReactionOverlay/index.tsx | 29 + .../Chat/ChatRequestControl/index.tsx | 47 ++ .../ChatTextField/AttachmentButtons/index.tsx | 45 ++ .../ChatTextField/AttachmentPreview/index.tsx | 220 ++++++ .../Chat/ChatTextField/MessageInput/index.tsx | 72 ++ .../Chat/ChatTextField/ReplyPreview/index.tsx | 184 +++++ .../VoiceNoteRecording/index.tsx | 115 ++++ .../ChatSheet/Chat/ChatTextField/index.tsx | 225 ++++++ .../MessageSkeletonCard/index.tsx | 0 .../Chat/LoadingMessagesList/index.tsx | 25 + .../Chat/VideoPlayerPreview/index.tsx | 119 ++++ .../Chat/VoiceNotePreview}/index.tsx | 48 +- .../lib/components/ChatSheet/Chat/index.tsx | 257 +++++++ .../NewChat/NewChatTextField/index.tsx | 68 ++ .../NewChat}/index.tsx | 15 +- .../src/lib/components/ChatSheet/index.tsx | 213 ++---- .../src/lib/components/CustomPlayer/index.tsx | 106 --- .../components/CustomVoicePreview/index.tsx | 86 --- .../lib/components/EmojiSelector/index.tsx | 82 --- .../ChatList}/MessageItem/index.tsx | 87 ++- .../{ => InboxSheet}/ChatList/index.tsx | 24 +- .../src/lib/components/InboxSheet/index.tsx | 274 ++++++++ .../src/lib/components/MessageSheet/index.tsx | 29 - .../lib/components/MessageTextField/index.tsx | 651 ------------------ .../lib/components/NewMessageSheet/index.tsx | 37 - .../index.tsx | 4 +- .../src/lib/content-types/readReceipt.ts | 120 ++++ .../lib/hooks/useGetAudioDuration/index.tsx | 71 +- .../src/lib/hooks/useReadReceipt/index.tsx | 14 + .../src/lib/hooks/useSendMessage/index.ts | 52 +- .../xmtp-plugin/src/lib/plugins/index.tsx | 8 +- .../providers/JustWeb3XMTPProvider/index.tsx | 279 +++++++- 45 files changed, 2900 insertions(+), 2015 deletions(-) create mode 100644 packages/@justweb3/ui/src/lib/ui/NotificationBadge/NotificationBadge.module.css create mode 100644 packages/@justweb3/ui/src/lib/ui/NotificationBadge/index.tsx create mode 100644 packages/@justweb3/ui/src/stories/ui/notification-badge.stories.tsx delete mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/AllMessageSheet/index.tsx delete mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx rename packages/@justweb3/xmtp-plugin/src/lib/components/{ChatButton => ChatMenuButton}/index.tsx (64%) create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatHeader/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/DateDivider/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/EmojiSelector/index.tsx rename packages/@justweb3/xmtp-plugin/src/lib/components/{ => ChatSheet/Chat/ChatMessagesList}/MessageCard/index.tsx (93%) create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatReactionOverlay/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatRequestControl/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/AttachmentButtons/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/AttachmentPreview/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/MessageInput/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/ReplyPreview/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/VoiceNoteRecording/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/index.tsx rename packages/@justweb3/xmtp-plugin/src/lib/components/{ => ChatSheet/Chat/LoadingMessagesList}/MessageSkeletonCard/index.tsx (100%) create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/LoadingMessagesList/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/VideoPlayerPreview/index.tsx rename packages/@justweb3/xmtp-plugin/src/lib/components/{VoiceMessageCard => ChatSheet/Chat/VoiceNotePreview}/index.tsx (81%) create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/NewChat/NewChatTextField/index.tsx rename packages/@justweb3/xmtp-plugin/src/lib/components/{NewConversation => ChatSheet/NewChat}/index.tsx (96%) delete mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/CustomPlayer/index.tsx delete mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/CustomVoicePreview/index.tsx delete mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/EmojiSelector/index.tsx rename packages/@justweb3/xmtp-plugin/src/lib/components/{ => InboxSheet/ChatList}/MessageItem/index.tsx (56%) rename packages/@justweb3/xmtp-plugin/src/lib/components/{ => InboxSheet}/ChatList/index.tsx (60%) create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/index.tsx delete mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx delete mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx delete mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/NewMessageSheet/index.tsx rename packages/@justweb3/xmtp-plugin/src/lib/components/{ChatWithProfileButton => ProfileChatButton}/index.tsx (96%) create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/content-types/readReceipt.ts create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/hooks/useReadReceipt/index.tsx diff --git a/packages/@justweb3/ui/src/lib/ui/NotificationBadge/NotificationBadge.module.css b/packages/@justweb3/ui/src/lib/ui/NotificationBadge/NotificationBadge.module.css new file mode 100644 index 00000000..d5c0f5a4 --- /dev/null +++ b/packages/@justweb3/ui/src/lib/ui/NotificationBadge/NotificationBadge.module.css @@ -0,0 +1,27 @@ +.notificationIcon { + position: relative; + display: inline-block; + +} + +.icon { + font-size: 24px; /* Adjust icon size */ + line-height: 40px; /* Center the icon vertically */ + text-align: center; +} + +.badge { + position: absolute; + top: 0; + right: 4px; + background-color: red; + color: white; + font-size: 8px; + font-weight: bold; + line-height: 1; + border-radius: 100px; + padding: 2px 4px; + transform: translate(50%, -50%); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + white-space: nowrap; +} diff --git a/packages/@justweb3/ui/src/lib/ui/NotificationBadge/index.tsx b/packages/@justweb3/ui/src/lib/ui/NotificationBadge/index.tsx new file mode 100644 index 00000000..b83fe06d --- /dev/null +++ b/packages/@justweb3/ui/src/lib/ui/NotificationBadge/index.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import styles from './NotificationBadge.module.css'; +import { SPAN } from '../Text'; + +interface NotificationBadgeProps { + count: number; + icon?: React.ReactNode; + maxCount?: number; +} + +export const NotificationBadge: React.FC = ({ + count, + icon, + maxCount = 99, +}) => { + return ( +
+ {/*
{icon}
*/} + {icon} + {/*{count > 0 && {count}}*/} + {count > 0 && ( + + {count > maxCount ? `${maxCount}+` : count} + + )} +
+ ); +}; + +export default NotificationBadge; diff --git a/packages/@justweb3/ui/src/lib/ui/index.ts b/packages/@justweb3/ui/src/lib/ui/index.ts index 3cd6c64c..53e68816 100644 --- a/packages/@justweb3/ui/src/lib/ui/index.ts +++ b/packages/@justweb3/ui/src/lib/ui/index.ts @@ -18,3 +18,4 @@ export * from './Sheet'; export * from './Label'; export * from './Checkbox'; export * from './Skeleton'; +export * from './NotificationBadge'; diff --git a/packages/@justweb3/ui/src/stories/ui/notification-badge.stories.tsx b/packages/@justweb3/ui/src/stories/ui/notification-badge.stories.tsx new file mode 100644 index 00000000..7477aa44 --- /dev/null +++ b/packages/@justweb3/ui/src/stories/ui/notification-badge.stories.tsx @@ -0,0 +1,57 @@ +import { Meta, StoryObj } from '@storybook/react'; +import { NotificationBadge } from '../../lib/ui'; +import React from 'react'; + +const meta: Meta = { + component: NotificationBadge, + title: 'Design System/UI/NotificationBadge', + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +const ChatIcon = () => { + return ( + + + + ); +}; + +export const Normal: Story = { + args: { + count: 1, + icon: , + }, +}; + +export const Zero: Story = { + args: { + count: 0, + icon: , + }, +}; + +export const Many: Story = { + args: { + count: 50, + icon: , + }, +}; + +export const ManyWithMax: Story = { + args: { + count: 1000, + icon: , + }, +}; diff --git a/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx b/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx index c16067a0..2c10fd20 100644 --- a/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx @@ -35,12 +35,14 @@ import styles from './JustWeb3Button.module.css'; export interface JustWeb3Buttonrops { children: ReactNode; + style?: React.CSSProperties; logout?: () => void; } export const JustWeb3Button: FC = ({ children, logout, + style, }) => { const [openMApps, setOpenMApps] = useState(false); const { plugins, mApps, config } = useContext(JustWeb3Context); @@ -89,6 +91,9 @@ export const JustWeb3Button: FC = ({ = ({ onClick={() => { handleOpenSignInDialog(true); }} + style={{ + ...style, + }} left={} right={ = ({ style={{ backgroundColor: 'var(--justweb3-background-color)', color: 'var(--justweb3-primary-color)', + ...style, }} contentStyle={{ alignItems: 'start', @@ -187,32 +196,6 @@ export const JustWeb3Button: FC = ({ const connectedEnsProfileContent = ( - {/**/} - {/* */} - {/* Profile Overview*/} - {/*

*/} - {/* */} - {/* }*/} - {/* onClick={() => {*/} - {/* openEnsProfile(connectedEns?.ens, connectedEns?.chainId);*/} - {/* }}*/} - {/* >*/} - {/* View Full Profile*/} - {/* */} - {/*
*/} - {/* Profile */} | string | null; - openChat: boolean; - closeChat: () => void; - onChangePeer: ( - peer: CachedConversation | string - ) => void; -} - -export const AllMessageSheet: React.FC = ({ - peer, - closeChat, - openChat, - onChangePeer, -}) => { - const isPeerConversation = useMemo(() => { - return typeof peer !== 'string'; - }, [peer]); - - return ( - !open && closeChat()}> - - - {isPeerConversation ? 'Messages' : 'New Conversation'} - - - {peer !== null && - (isPeerConversation ? ( - } - onBack={closeChat} - /> - ) : ( - { - onChangePeer(conversation); - }} - /> - ))} - - - ); -}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx deleted file mode 100644 index 3f454e35..00000000 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/Chat/index.tsx +++ /dev/null @@ -1,618 +0,0 @@ -import { - useEnsAvatar, - useMountedAccount, - usePrimaryName, - useRecords, -} from '@justaname.id/react'; -import { - ArrowIcon, - Avatar, - BlockedAccountIcon, - Button, - Flex, - LoadingSpinner, - P, - Popover, - PopoverContent, - PopoverTrigger, - TuneIcon, -} from '@justweb3/ui'; -import { - CachedConversation, - ContentTypeMetadata, - useCanMessage, - useConsent, - useMessages, - useStreamMessages, -} from '@xmtp/react-sdk'; -import React, { useEffect, useMemo } from 'react'; -import { useSendReactionMessage } from '../../hooks'; -import { typeLookup } from '../../utils/attachments'; -import { - filterReactionsMessages, - MessageWithReaction, -} from '../../utils/filterReactionsMessages'; -import { formatAddress } from '../../utils/formatAddress'; -import { groupMessagesByDate } from '../../utils/groupMessageByDate'; -import EmojiSelector from '../EmojiSelector'; -import MessageCard from '../MessageCard'; -import { MessageSkeletonCard } from '../MessageSkeletonCard'; -import MessageTextField from '../MessageTextField'; -import { useJustWeb3 } from '@justweb3/widget'; - -export interface ChatProps { - conversation: CachedConversation; - onBack: () => void; -} - -export const Chat: React.FC = ({ conversation, onBack }) => { - const { openEnsProfile } = useJustWeb3(); - const [replyMessage, setReplyMessage] = - React.useState(null); - const [reactionMessage, setReactionMessage] = - React.useState(null); - const [isRequest, setIsRequest] = React.useState(false); - const [isRequestChangeLoading, setIsRequestChangeLoading] = - React.useState(false); - const { entries, allow, refreshConsentList, deny } = useConsent(); - const { mutateAsync: sendReaction } = useSendReactionMessage(conversation); - - const { primaryName } = usePrimaryName({ - address: conversation.peerAddress as `0x${string}`, - }); - const { records } = useRecords({ - ens: primaryName, - }); - const { sanitizeEnsImage } = useEnsAvatar(); - - const { address } = useMountedAccount(); - - const [canMessage, setCanMessage] = React.useState(true); - - const { messages, isLoading } = useMessages(conversation); - - // Queries - - const blockAddress = async (peerAddress: string) => { - setIsRequestChangeLoading(true); - await refreshConsentList(); - await deny([peerAddress]); - await refreshConsentList(); - setIsRequestChangeLoading(false); - onBack(); - }; - - const { canMessage: canMessageFn, isLoading: isCanMessageLoading } = - useCanMessage(); - - useEffect(() => { - if (isCanMessageLoading) return; - canMessageFn(conversation.peerAddress).then((result) => { - setCanMessage(result); - }); - }, [isCanMessageLoading, conversation, canMessageFn]); - - useStreamMessages(conversation); - - // Memo - const filteredMessages = useMemo(() => { - const messagesWithoutRead = messages.filter( - (message) => !(message.contentType === 'xmtp.org/readReceipt:1.0') - ); - const res = filterReactionsMessages(messagesWithoutRead); - return res; - }, [messages]); - - const groupedMessages = useMemo(() => { - return groupMessagesByDate(filteredMessages ?? []); - }, [filteredMessages]); - - useEffect(() => { - const convoConsentState = entries[conversation.peerAddress]?.permissionType; - if (convoConsentState === 'unknown' || convoConsentState === undefined) { - setIsRequest(true); - } else { - setIsRequest(false); - } - }, [entries, conversation.peerAddress]); - - const isMessagesSenderOnly = useMemo(() => { - return filteredMessages.every( - (message) => message.senderAddress === address - ); - }, [filteredMessages, address]); - - const handleAllowAddress = async () => { - setIsRequestChangeLoading(true); - await refreshConsentList(); - await allow([conversation.peerAddress]); - void refreshConsentList(); - setIsRequest(false); - setIsRequestChangeLoading(false); - }; - - const handleEmojiSelect = (emoji: string) => { - if (!reactionMessage) return; - sendReaction({ - action: 'added', - content: emoji, - referenceId: reactionMessage.id, - }); - }; - - useEffect(() => { - if (messages.length == 0) return; - setTimeout(() => { - const lastMessageId = messages[messages.length - 1]?.id; - const element = document.getElementById(lastMessageId); - if (element) { - element.scrollIntoView({ behavior: 'smooth' }); - } - }, 500); - - // await checkMessageIfRead(); - }, [messages, conversation]); - - const isStringContent = - typeof replyMessage?.content === 'string' || - typeof replyMessage?.content?.content === 'string'; - - const mimeType = replyMessage?.content?.mimeType; - const type = mimeType ? typeLookup[mimeType.split('/')?.[1]] : null; - - const computeHeight = useMemo(() => { - const additionalHeight = []; - const height = '100vh - 50px - 3rem - 1.5rem - 73px - 15px'; - if (isRequest) { - additionalHeight.push('-40px'); - } - if (replyMessage) { - if (isStringContent) { - additionalHeight.push('46px'); - } else if (mimeType === 'audio/wav') { - additionalHeight.push('61px'); - } else if (type === 'video' || type === 'image') { - additionalHeight.push('116px'); - } else { - additionalHeight.push('47px'); - } - } - - if (isMessagesSenderOnly) { - additionalHeight.push('59px'); - } - - return `calc( ${height} ${ - additionalHeight.length > 0 ? ' - ' + additionalHeight.join(' - ') : '' - } )`; - }, [ - replyMessage, - isMessagesSenderOnly, - isStringContent, - mimeType, - type, - isRequest, - ]); - - return ( - -
{ - setReactionMessage(null); - const replica = document.getElementById( - `${reactionMessage?.id}-replica` - ); - replica?.remove(); - }} - >
- - - - - - { - if (primaryName) { - openEnsProfile(primaryName); - } - }} - > - - -

- {primaryName - ? primaryName - : formatAddress(conversation.peerAddress)} -

- {primaryName && ( -

- {formatAddress(conversation.peerAddress)} -

- )} -
-
-
- - - - - - - - blockAddress(conversation.peerAddress)} - > - -

- Block -

-
-
-
-
-
-
- - {isCanMessageLoading || isLoading ? ( - - {[...Array(8)].map((_, index) => ( - - ))} - - ) : ( - - {canMessage ? ( - - {groupedMessages && - Object.keys(groupedMessages).map((date, index) => ( - - -
-

- {date} -

-
- - {groupedMessages[date].map((message) => ( - setReplyMessage(msg)} - message={message} - peerAddress={conversation.peerAddress} - key={`message-${message.id}`} - onReaction={(message) => { - setReactionMessage(message); - - const element = document.getElementById( - message.id.toString() - ); - if (!element) return; - const replica = element?.cloneNode( - true - ) as HTMLElement; - replica.id = `${message.id}-replica`; - replica.style.position = 'absolute'; - replica.style.bottom = '310px'; - replica.style.minHeight = '20px'; - replica.style.left = '4.2vw'; - replica.style.zIndex = '90'; - element?.parentElement?.appendChild(replica); - replica.classList.add('replica-animate'); - }} - /> - ))} - - ))} - {reactionMessage && ( -
- { - handleEmojiSelect(emoji); - setReactionMessage(null); - const replica = document.getElementById( - `${reactionMessage?.id}-replica` - ); - replica?.remove(); - }} - /> -
- )} - - ) : ( -
-

Cannot message {conversation.peerAddress}

-
- )} - - )} - - {isRequest ? ( - isRequestChangeLoading ? ( - - - - ) : ( - - - - - ) - ) : ( - - {isMessagesSenderOnly && ( - -

- Message in user’s Requests -

-

- This user has not accepted your message request yet -

-
- )} - setReplyMessage(null)} - conversation={conversation} - replyMessage={replyMessage} - peerAddress={conversation.peerAddress} - /> -
- )} - - - ); -}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatMenuButton/index.tsx similarity index 64% rename from packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx rename to packages/@justweb3/xmtp-plugin/src/lib/components/ChatMenuButton/index.tsx index 4c39d872..6e209868 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatButton/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatMenuButton/index.tsx @@ -1,15 +1,26 @@ import { useMountedAccount } from '@justaname.id/react'; -import { ArrowIcon, ClickableItem } from '@justweb3/ui'; +import { ArrowIcon, ClickableItem, SPAN } from '@justweb3/ui'; import { Client, ClientOptions, useClient } from '@xmtp/react-sdk'; import { useEthersSigner } from '../../hooks'; import { XmtpEnvironment } from '../../plugins'; import { loadKeys, storeKeys, wipeKeys } from '../../utils/xmtp'; +import { useJustWeb3XMTP } from '../../providers/JustWeb3XMTPProvider'; +import { useMemo } from 'react'; -export interface ChatButtonProps { +export interface ChatMenuButtonProps { handleOpen: (open: boolean) => void; env: XmtpEnvironment; } -export const ChatButton: React.FC = ({ handleOpen, env }) => { +export const ChatMenuButton: React.FC = ({ + handleOpen, + env, +}) => { + const { conversationsInfo } = useJustWeb3XMTP(); + const totalUnreadCount = useMemo(() => { + return conversationsInfo + .filter((conversation) => conversation.consent === 'allowed') + .reduce((acc, curr) => acc + curr.unreadCount, 0); + }, [conversationsInfo]); const { initialize } = useClient(); const { client } = useClient(); const walletClient = useEthersSigner(); @@ -74,7 +85,36 @@ export const ChatButton: React.FC = ({ handleOpen, env }) => { width: '100%', }} onClick={handleChat} - right={} + right={ + <> + {totalUnreadCount > 0 && ( +
+ + {totalUnreadCount} + +
+ )} + + + } /> ); }; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatHeader/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatHeader/index.tsx new file mode 100644 index 00000000..2d90fed0 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatHeader/index.tsx @@ -0,0 +1,157 @@ +import { + ArrowIcon, + Avatar, + BlockedAccountIcon, + Flex, + P, + Popover, + PopoverContent, + PopoverTrigger, + TuneIcon, +} from '@justweb3/ui'; +import { formatAddress } from '../../../../utils/formatAddress'; +import { useEnsAvatar } from '@justaname.id/react'; + +export interface ChatHeaderProps { + primaryName: string | undefined; + peerAddress: string; + onBack: () => void; + openEnsProfile: (ens: string) => void; + records: any; + blockAddressHandler: (peerAddress: string) => void; +} + +export const ChatHeader: React.FC = ({ + primaryName, + peerAddress, + onBack, + openEnsProfile, + records, + blockAddressHandler, +}) => { + const { sanitizeEnsImage } = useEnsAvatar(); + + return ( + + + + + + { + if (primaryName) openEnsProfile(primaryName); + }} + > + + +

+ {primaryName || formatAddress(peerAddress)} +

+ {primaryName && ( +

+ {formatAddress(peerAddress)} +

+ )} +
+
+
+ + + + + + + + + blockAddressHandler(peerAddress)} + > + +

+ Block +

+
+
+
+
+
+
+ ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/DateDivider/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/DateDivider/index.tsx new file mode 100644 index 00000000..6b0b7307 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/DateDivider/index.tsx @@ -0,0 +1,43 @@ +import { Flex, P } from '@justweb3/ui'; + +interface DateDividerProps { + date: string; +} + +export const DateDivider: React.FC = ({ date }) => ( + +
+

+ {date} +

+
+ +); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/EmojiSelector/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/EmojiSelector/index.tsx new file mode 100644 index 00000000..4dd8f6ba --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/EmojiSelector/index.tsx @@ -0,0 +1,85 @@ +import { Flex, Input } from '@justweb3/ui'; +import React, { useMemo } from 'react'; +import { useDebounce } from '@justweb3/widget'; +import { EmojiObject, emojis } from '../../../../../utils/emojis'; + +interface EmojiSelectorProps { + onEmojiSelect: (emoji: string) => void; +} + +export const EmojiSelector: React.FC = ({ + onEmojiSelect, +}) => { + const [searchValue, setSearchValue] = React.useState(''); + + const { debouncedValue: debouncedSearch } = useDebounce( + searchValue, + 50 + ); + + const onEmojiClickHandler = (emoji: EmojiObject) => { + onEmojiSelect(emoji.name); + }; + + const filteredEmojis = useMemo(() => { + if (debouncedSearch.length === 0) return emojis; + const filteredEmojis = emojis.filter((emoji) => + emoji.name.toLowerCase().includes(debouncedSearch.toLowerCase()) + ); + return filteredEmojis; + }, [debouncedSearch]); + + return ( + + setSearchValue(e.target.value)} + /> +
+ {filteredEmojis.map((emoji, index) => ( + + ))} +
+
+ ); +}; + +export default EmojiSelector; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/MessageCard/index.tsx similarity index 93% rename from packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx rename to packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/MessageCard/index.tsx index 0630fb58..8ad5ce6c 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageCard/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/MessageCard/index.tsx @@ -9,15 +9,15 @@ import { } from '@justweb3/ui'; import { CachedConversation, DecodedMessage } from '@xmtp/react-sdk'; import React, { useEffect, useMemo, useRef, useState } from 'react'; -import { useSendReactionMessage } from '../../hooks'; -import { typeLookup } from '../../utils/attachments'; -import { calculateFileSize } from '../../utils/calculateFileSize'; -import { findEmojiByName } from '../../utils/emojis'; -import { MessageWithReaction } from '../../utils/filterReactionsMessages'; -import { formatAddress } from '../../utils/formatAddress'; -import { formatMessageSentTime } from '../../utils/messageTimeFormat'; -import { CustomPlayer } from '../CustomPlayer'; -import VoiceMessageCard from '../VoiceMessageCard'; +import { useSendReactionMessage } from '../../../../../hooks'; +import { typeLookup } from '../../../../../utils/attachments'; +import { calculateFileSize } from '../../../../../utils/calculateFileSize'; +import { findEmojiByName } from '../../../../../utils/emojis'; +import { MessageWithReaction } from '../../../../../utils/filterReactionsMessages'; +import { formatAddress } from '../../../../../utils/formatAddress'; +import { formatMessageSentTime } from '../../../../../utils/messageTimeFormat'; +import VoiceNotePreview from '../../VoiceNotePreview'; +import { VideoPlayerPreview } from '../../VideoPlayerPreview'; interface MessageCardProps { message: MessageWithReaction; @@ -107,7 +107,7 @@ const MeasureAndHyphenateText: React.FC<{ ); }; -const MessageCard: React.FC = ({ +export const MessageCard: React.FC = ({ message, peerAddress, onReply, @@ -259,17 +259,17 @@ const MessageCard: React.FC = ({ senderAddress: message.senderAddress, content: typeLookup[attachmentExtention] === 'image' || - typeLookup[attachmentExtention] === 'video' + typeLookup[attachmentExtention] === 'video' ? { - data: message.content.data, - mimeType: message.content.mimeType, - filename: message.content.filename, - url: URL.createObjectURL( - new Blob([message.content.data], { - type: message.content.mimeType, - }) - ), - } + data: message.content.data, + mimeType: message.content.mimeType, + filename: message.content.filename, + url: URL.createObjectURL( + new Blob([message.content.data], { + type: message.content.mimeType, + }) + ), + } : message.content, contentType: message.contentType, })} @@ -317,7 +317,7 @@ const MessageCard: React.FC = ({ {repliedMessage?.senderAddress === address ? 'YOU' : primaryName ?? - formatAddress(repliedMessage?.senderAddress ?? '')} + formatAddress(repliedMessage?.senderAddress ?? '')}

{isReplyText || isReplyReply ? ( @@ -340,7 +340,7 @@ const MessageCard: React.FC = ({ : repliedMessage.content}

) : isReplyVoice ? ( - = ({ }} /> ) : typeLookup[replyAttachmentExtention] === 'video' ? ( - = ({ ) : ( {isVoice ? ( - + ) : ( {typeLookup[attachmentExtention] === 'image' ? ( @@ -469,7 +469,7 @@ const MessageCard: React.FC = ({
) : typeLookup[attachmentExtention] === 'video' ? ( - ; + setReplyMessage: (msg: MessageWithReaction | null) => void; + setReactionMessage: (msg: MessageWithReaction | null) => void; + reactionMessage: MessageWithReaction | null; + handleEmojiSelect: (emoji: string) => void; + computeHeight: string; +} + +export const ChatMessagesList: React.FC = ({ + canMessage, + groupedMessages, + conversation, + setReplyMessage, + setReactionMessage, + reactionMessage, + handleEmojiSelect, + computeHeight, +}) => { + if (!canMessage) { + return ( + +

Cannot message {conversation.peerAddress}

+
+ ); + } + + return ( + + + {groupedMessages && + Object.keys(groupedMessages).map((date, index) => ( + + + {groupedMessages[date].map((message) => ( + { + setReactionMessage(msg); + const element = document.getElementById(msg.id); + if (!element) return; + const replica = element.cloneNode(true) as HTMLElement; + replica.id = `${msg.id}-replica`; + replica.style.position = 'absolute'; + replica.style.bottom = '310px'; + replica.style.minHeight = '20px'; + replica.style.left = '4.2vw'; + replica.style.zIndex = '90'; + element.parentElement?.appendChild(replica); + replica.classList.add('replica-animate'); + }} + /> + ))} + + ))} + + {reactionMessage && ( +
+ +
+ )} +
+
+ ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatReactionOverlay/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatReactionOverlay/index.tsx new file mode 100644 index 00000000..46ede4df --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatReactionOverlay/index.tsx @@ -0,0 +1,29 @@ +import { MessageWithReaction } from '../../../utils/filterReactionsMessages'; + +interface ChatReactionOverlayProps { + reactionMessage: MessageWithReaction | null; + onOverlayClick: () => void; +} + +export const ChatReactionOverlay: React.FC = ({ + reactionMessage, + onOverlayClick, +}) => ( +
+); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatRequestControl/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatRequestControl/index.tsx new file mode 100644 index 00000000..26d1497b --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatRequestControl/index.tsx @@ -0,0 +1,47 @@ +import { Button, Flex, LoadingSpinner } from '@justweb3/ui'; + +interface ChatRequestControlsProps { + isRequestChangeLoading: boolean; + blockAddressHandler: (peerAddress: string) => void; + peerAddress: string; + handleAllowAddress: () => void; +} + +export const ChatRequestControls: React.FC = ({ + isRequestChangeLoading, + blockAddressHandler, + peerAddress, + handleAllowAddress, +}) => { + if (isRequestChangeLoading) { + return ( + + + + ); + } + + return ( + + + + + ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/AttachmentButtons/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/AttachmentButtons/index.tsx new file mode 100644 index 00000000..5958e761 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/AttachmentButtons/index.tsx @@ -0,0 +1,45 @@ +// ChatTextField/AttachmentButtons.tsx +import React, { RefObject } from 'react'; +import { AddFolderIcon, AddImageIcon, AddVideoIcon, Flex } from '@justweb3/ui'; + +export interface AttachmentButtonsProps { + onButtonClick: (contentType: 'image' | 'video' | 'application') => void; + acceptedTypes: string | string[] | undefined; + onAttachmentChange: (e: React.ChangeEvent) => void; +} + +export const AttachmentButtons: React.FC< + AttachmentButtonsProps & { inputFileRef: RefObject } +> = ({ onButtonClick, acceptedTypes, onAttachmentChange, inputFileRef }) => ( + + onButtonClick('image')} + style={{ cursor: 'pointer' }} + /> + onButtonClick('video')} + style={{ cursor: 'pointer' }} + /> + onButtonClick('application')} + style={{ cursor: 'pointer' }} + /> + + +); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/AttachmentPreview/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/AttachmentPreview/index.tsx new file mode 100644 index 00000000..71abf76e --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/AttachmentPreview/index.tsx @@ -0,0 +1,220 @@ +// ChatTextField/AttachmentPreview.tsx +import React from 'react'; +import { + Button, + DocumentIcon, + Flex, + P, + SendIcon, + StopIcon, +} from '@justweb3/ui'; +import { VideoPlayerPreview } from '../../VideoPlayerPreview'; +import { VoiceNoteRecording } from './../VoiceNoteRecording'; +import { typeLookup } from '../../../../../utils/attachments'; +import { Attachment } from '@xmtp/content-type-remote-attachment'; + +export interface AttachmentPreviewProps { + attachment: Attachment | undefined; + attachmentPreview: string | undefined; + disabled?: boolean; + onCancelAttachment: () => void; + onSendAttachment: () => void; + recording: boolean; + recordingValue: string | null; + stopRecording: () => void; + pause: () => void; + reset: () => void; +} + +export const AttachmentPreview: React.FC = ({ + attachment, + attachmentPreview, + disabled, + onCancelAttachment, + onSendAttachment, + recording, + recordingValue, + stopRecording, + pause, + reset, +}) => { + const attachmentExtention = attachment?.mimeType.split('/')?.[1] || ''; + + if (attachmentPreview) { + return ( + + {attachment?.mimeType !== 'audio/wav' && ( +
+ )} + {attachment?.mimeType === 'audio/wav' ? ( + + ) : ( + + {typeLookup[attachmentExtention] === 'image' ? ( + {attachment?.filename} + ) : typeLookup[attachmentExtention] === 'video' ? ( + + ) : ( + + +

+ {attachment?.filename ?? 'Cannot preview'} +

+
+ )} + + + + +
+ )} + { + if (!disabled) onSendAttachment(); + }} + /> + + ); + } else if (recording) { + return ( + +

+ {recordingValue} +

+

+ RECORDING... +

+ { + stopRecording(); + pause(); + reset(); + }} + /> +
+ ); + } + + return null; +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/MessageInput/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/MessageInput/index.tsx new file mode 100644 index 00000000..c9c61261 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/MessageInput/index.tsx @@ -0,0 +1,72 @@ +import React from 'react'; +import { Input, MicIcon, SendIcon } from '@justweb3/ui'; + +interface MessageInputProps { + replyMessage: boolean; + disabled?: boolean; + messageValue: string; + setMessageValue: (value: string) => void; + handleSendMessage: () => void; + startRecording: () => void; + start: () => void; +} + +export const MessageInput: React.FC = ({ + replyMessage, + disabled, + messageValue, + setMessageValue, + handleSendMessage, + startRecording, + start, +}) => { + return ( + { + if (disabled) return; + startRecording(); + start(); + }} + /> + ) + } + right={ + + } + disabled={disabled} + onKeyDown={(e) => { + if (e.key === 'Enter') { + handleSendMessage(); + } + }} + onChange={(e) => setMessageValue(e.target.value)} + /> + ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/ReplyPreview/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/ReplyPreview/index.tsx new file mode 100644 index 00000000..7445ea5a --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/ReplyPreview/index.tsx @@ -0,0 +1,184 @@ +// ChatTextField/ReplyPreview.tsx +import React, { useMemo } from 'react'; +import { CloseIcon, DocumentIcon, Flex, P } from '@justweb3/ui'; +import VoiceNotePreview from '../../VoiceNotePreview'; +import { VideoPlayerPreview } from '../../VideoPlayerPreview'; +import { formatAddress } from '../../../../../utils/formatAddress'; +import { typeLookup } from '../../../../../utils/attachments'; +import { MessageWithReaction } from '../../../../../utils/filterReactionsMessages'; + +export interface ReplyPreviewProps { + replyMessage: MessageWithReaction | null; + onCancelReply: () => void; + isSender: boolean; + primaryName: string | null | undefined; + navigateToRepliedMessage: () => void; +} + +export const ReplyPreview: React.FC = ({ + replyMessage, + onCancelReply, + isSender, + primaryName, + navigateToRepliedMessage, +}) => { + const isReplyText = useMemo(() => { + if (!replyMessage) return false; + return typeof replyMessage.content === 'string'; + }, [replyMessage]); + + const isReplyReply = useMemo(() => { + if (!replyMessage) return false; + return !!replyMessage.content.reference; + }, [replyMessage]); + + const isReplyVoice = useMemo( + () => replyMessage?.content.mimeType === 'audio/wav', + [replyMessage] + ); + + const replyAttachmentExtension = useMemo(() => { + if (!isReplyText && replyMessage && !isReplyReply) { + return replyMessage.content.mimeType.split('/')?.[1] || ''; + } + }, [isReplyText, replyMessage, isReplyReply]); + + const isReplyVideoOrImage = useMemo(() => { + return ( + typeLookup[replyAttachmentExtension] === 'image' || + typeLookup[replyAttachmentExtension] === 'video' + ); + }, [replyAttachmentExtension]); + + if (!replyMessage) return null; + + return ( + + +

+ {isSender + ? 'YOU' + : primaryName ?? formatAddress(replyMessage.senderAddress)} +

+ {isReplyText || isReplyReply ? ( +

+ {isReplyReply ? replyMessage.content.content : replyMessage.content} +

+ ) : isReplyVoice ? ( + + ) : typeLookup[replyAttachmentExtension] === 'image' ? ( + {replyMessage.content.filename} + ) : typeLookup[replyAttachmentExtension] === 'video' ? ( + + ) : ( + + +

+ {replyMessage.content.filename} +

+
+ )} +
+ +
+ ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/VoiceNoteRecording/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/VoiceNoteRecording/index.tsx new file mode 100644 index 00000000..33cf8749 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/VoiceNoteRecording/index.tsx @@ -0,0 +1,115 @@ +import { CloseIcon, Flex, P, PauseIcon, PlayIcon } from '@justweb3/ui'; +import React, { useEffect, useRef, useState } from 'react'; +import { formatTime } from '../../../../../utils/formatVoiceTime'; +import { useGetAudioDuration } from '../../../../../hooks/useGetAudioDuration'; + +interface VoiceNoteRecordingProps { + audioUrl: string; + onCancel: () => void; +} + +export const VoiceNoteRecording: React.FC = ({ + audioUrl, + onCancel, +}) => { + const [playing, setPlaying] = useState(false); + const [currentTime, setCurrentTime] = useState(0); + const audioRef = useRef(new Audio()); + + const audioDuration = useGetAudioDuration(audioUrl); + + useEffect(() => { + const audio = new Audio(); + audioRef.current = audio; + + const onTimeUpdate = () => { + setCurrentTime(audio.currentTime); + }; + + const onEnded = () => { + setPlaying(false); + setCurrentTime(0); + }; + + audio.src = audioUrl; + audio.addEventListener('timeupdate', onTimeUpdate); + audio.addEventListener('ended', onEnded); + + return () => { + audio.removeEventListener('timeupdate', onTimeUpdate); + audio.removeEventListener('ended', onEnded); + }; + }, [audioUrl]); + + const handlePlayPause = () => { + const audio = audioRef.current; + if (!audio) return; + + if (playing) { + audio.pause(); + } else { + audio.play(); + } + setPlaying(!playing); + }; + + return ( + + {playing ? ( + + ) : ( + + )} +

+ {playing || currentTime > 0 + ? formatTime(currentTime) + : formatTime(audioDuration ?? 0)} +

+ +
+ ); +}; + +export default VoiceNoteRecording; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/index.tsx new file mode 100644 index 00000000..6698b6ab --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatTextField/index.tsx @@ -0,0 +1,225 @@ +// ChatTextField/index.tsx +import React, { + Dispatch, + SetStateAction, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; +import { + CachedConversation, + ContentTypeMetadata, + useClient, +} from '@xmtp/react-sdk'; +import { useMountedAccount, usePrimaryName } from '@justaname.id/react'; +import { Flex, P } from '@justweb3/ui'; +import { AttachmentButtons } from './AttachmentButtons'; +import { ReplyPreview } from './ReplyPreview'; +import { AttachmentPreview } from './AttachmentPreview'; +import { MessageInput } from './MessageInput'; +import { + useAttachmentChange, + useRecordingTimer, + useRecordVoice, + useSendAttachment, + useSendMessages, + useSendReplyMessage, +} from '../../../../hooks'; +import { AttachmentType, typeLookup } from '../../../../utils/attachments'; +import type { Attachment } from '@xmtp/content-type-remote-attachment'; +import { MessageWithReaction } from '../../../../utils/filterReactionsMessages'; + +export interface ChatTextFieldProps { + isMessagesSenderOnly: boolean; + replyMessage: MessageWithReaction | null; + conversation: CachedConversation; + peerAddress: string; + onCancelReply: () => void; + disabled?: boolean; + style?: React.CSSProperties; +} + +export const ChatTextField: React.FC = ({ + isMessagesSenderOnly, + replyMessage, + conversation, + peerAddress, + onCancelReply, + disabled, + style, +}) => { + const [messageValue, setMessageValue] = useState(''); + const [attachment, setAttachment] = useState(); + const [attachmentPreview, setAttachmentPreview] = useState< + string | undefined + >(); + const { client } = useClient(); + const { address } = useMountedAccount(); + const { mutateAsync: sendMessage } = useSendMessages(conversation); + const { mutateAsync: sendReply } = useSendReplyMessage(conversation); + const { mutateAsync: sendAttachment } = useSendAttachment(conversation); + const { primaryName } = usePrimaryName({ + address: peerAddress as `0x${string}`, + }); + + const [acceptedTypes, setAcceptedTypes]: [ + string | string[] | undefined, + Dispatch> + ] = useState(); + const inputFile = useRef(null); + + const { onAttachmentChange } = useAttachmentChange({ + setAttachment, + setAttachmentPreview, + }); + + const { recording, startRecording, stopRecording } = useRecordVoice({ + setAttachment, + setAttachmentPreview, + }); + const { start, pause, reset, recordingValue } = useRecordingTimer({ + stopRecording, + status: recording ? 'recording' : 'idle', + }); + + const handleSendMessage = async () => { + if (!client || disabled || messageValue.length === 0) return; + + if (replyMessage) { + await sendReply({ + message: messageValue, + referenceId: replyMessage.id, + }); + onCancelReply && onCancelReply(); + } else { + await sendMessage(messageValue); + } + + setMessageValue(''); + }; + + const handleSendAttachment = async () => { + if (!client || !attachment || disabled) return; + await sendAttachment(attachment); + setMessageValue(''); + setAttachment(undefined); + setAttachmentPreview(undefined); + }; + + const handleCancelAttachment = () => { + setAttachment(undefined); + setAttachmentPreview(undefined); + }; + + const onButtonClick = (contentType: AttachmentType) => { + if (contentType === 'application') { + setAcceptedTypes('all'); + } else { + const acceptedFileTypeList = Object.keys(typeLookup).reduce( + (acc: string[], key: string) => { + if (typeLookup[key] === contentType) acc.push(`.${key}`); + return acc; + }, + [] + ); + setAcceptedTypes([...acceptedFileTypeList]); + } + }; + + const isSender = useMemo( + () => address === replyMessage?.senderAddress, + [replyMessage, address] + ); + + const navigateToRepliedMessage = () => { + if (!replyMessage) return; + const element = document.getElementById(replyMessage.id.toString()); + if (element) { + element.scrollIntoView({ + block: 'end', + behavior: 'smooth', + }); + } + }; + + useEffect(() => { + if (acceptedTypes) { + inputFile?.current?.click(); + } + }, [acceptedTypes]); + + return ( + + {isMessagesSenderOnly && ( + +

+ Message in user’s Requests +

+

+ This user has not accepted your message request yet +

+
+ )} + + + + +
+ + + + + {!attachmentPreview && !recording && ( + + )} +
+
+
+ ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSkeletonCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/LoadingMessagesList/MessageSkeletonCard/index.tsx similarity index 100% rename from packages/@justweb3/xmtp-plugin/src/lib/components/MessageSkeletonCard/index.tsx rename to packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/LoadingMessagesList/MessageSkeletonCard/index.tsx diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/LoadingMessagesList/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/LoadingMessagesList/index.tsx new file mode 100644 index 00000000..5a65dcdc --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/LoadingMessagesList/index.tsx @@ -0,0 +1,25 @@ +import { Flex } from '@justweb3/ui'; +import { MessageSkeletonCard } from './MessageSkeletonCard'; + +interface LoadingMessagesListProps { + computeHeight: string; +} + +export const LoadingMessagesList: React.FC = ({ + computeHeight, +}) => ( + + {Array.from({ length: 8 }).map((_, index) => ( + + ))} + +); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/VideoPlayerPreview/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/VideoPlayerPreview/index.tsx new file mode 100644 index 00000000..dd4de5d0 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/VideoPlayerPreview/index.tsx @@ -0,0 +1,119 @@ +import { DownloadIcon, Flex, PauseIcon, PlayIcon } from '@justweb3/ui'; +import React, { useEffect, useRef, useState } from 'react'; + +export interface VideoPlayerPreviewProps { + style?: React.CSSProperties; + url?: string; + disabled?: boolean; + fileName?: string; +} + +export const VideoPlayerPreview: React.FC = ({ + style, + url = '', + disabled, + fileName, +}) => { + const [playing, setPlaying] = React.useState(false); + const videoRef = useRef(null); + const [hovered, setHovered] = useState(false); + + const togglePlay = () => { + if (disabled) return; + if (videoRef.current) { + if (playing) { + videoRef.current.pause(); + } else { + videoRef.current.play(); + } + setPlaying(!playing); + } + }; + + useEffect(() => { + const handleVisibilityChange = () => { + if (document.hidden && playing && videoRef.current) { + videoRef.current.pause(); + } + }; + document.addEventListener('visibilitychange', handleVisibilityChange); + return () => { + document.removeEventListener('visibilitychange', handleVisibilityChange); + if (videoRef.current && playing) { + videoRef.current.pause(); + setPlaying(false); + } + }; + }, [playing]); + + return ( + { + setHovered(true); + }} + onMouseLeave={() => { + setHovered(false); + }} + onClick={togglePlay} + style={{ + aspectRatio: '16/9', + position: 'relative', + // TODO: check background color + background: 'var(--justweb3-background-color)', + cursor: 'pointer', + borderRadius: '10px', + border: '1px solid var(--justweb3-primary-color)', + ...style, + }} + > + + ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/VoiceNotePreview/index.tsx similarity index 81% rename from packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx rename to packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/VoiceNotePreview/index.tsx index 0664a88b..819df525 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/VoiceMessageCard/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/VoiceNotePreview/index.tsx @@ -2,18 +2,18 @@ import { Flex, P, PauseIcon, PlayIcon } from '@justweb3/ui'; import * as Slider from '@radix-ui/react-slider'; import { DecodedMessage } from '@xmtp/xmtp-js'; import React, { useEffect, useMemo, useRef, useState } from 'react'; -import useGetAudioDuration from '../../hooks/useGetAudioDuration'; -import { MessageWithReaction } from '../../utils/filterReactionsMessages'; -import { formatTime } from '../../utils/formatVoiceTime'; +import { formatTime } from '../../../../utils/formatVoiceTime'; +import { useGetAudioDuration } from '../../../../hooks/useGetAudioDuration'; +import { MessageWithReaction } from '../../../../utils/filterReactionsMessages'; -interface VoiceMessageCardProps { +interface VoiceNotePreviewProps { message: MessageWithReaction | DecodedMessage; style?: React.CSSProperties; disabled?: boolean; isReceiver: boolean; } -const VoiceMessageCard: React.FC = ({ +const VoiceNotePreview: React.FC = ({ message, style, disabled, @@ -115,12 +115,11 @@ const VoiceMessageCard: React.FC = ({ width="22" height="22" fill={ - disabled ? - 'var(--justweb3-primary-color)' - : - isReceiver - ? 'var(--justweb3-primary-color)' - : 'var(--justweb3-foreground-color-4)' + disabled + ? 'var(--justweb3-primary-color)' + : isReceiver + ? 'var(--justweb3-primary-color)' + : 'var(--justweb3-foreground-color-4)' } style={{ cursor: 'pointer', @@ -193,19 +192,26 @@ const VoiceMessageCard: React.FC = ({ aria-label="Volume" /> - -

{playing || currentTime > 0 ? formatTime(currentTime) : formatTime(duration ?? 0)}

- + +

+ {playing || currentTime > 0 + ? formatTime(currentTime) + : formatTime(duration ?? 0)} +

); }; -export default VoiceMessageCard; +export default VoiceNotePreview; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/index.tsx new file mode 100644 index 00000000..de637057 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/index.tsx @@ -0,0 +1,257 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { + useMountedAccount, + usePrimaryName, + useRecords, +} from '@justaname.id/react'; +import { Flex } from '@justweb3/ui'; +import { + CachedConversation, + ContentTypeMetadata, + useCanMessage, + useConsent, + useMessages, + useStreamMessages, +} from '@xmtp/react-sdk'; +import { useJustWeb3 } from '@justweb3/widget'; +import { ChatTextField } from './ChatTextField'; +import { ChatMessagesList } from './ChatMessagesList'; +import { LoadingMessagesList } from './LoadingMessagesList'; +import { ChatRequestControls } from './ChatRequestControl'; +import { ChatHeader } from './ChatHeader'; +import { ChatReactionOverlay } from './ChatReactionOverlay'; +import { + filterReactionsMessages, + MessageWithReaction, +} from '../../../utils/filterReactionsMessages'; +import { useSendReactionMessage } from '../../../hooks'; +import { groupMessagesByDate } from '../../../utils/groupMessageByDate'; +import { typeLookup } from '../../../utils/attachments'; +import { ContentTypeReadReceipt } from '@xmtp/content-type-read-receipt'; +import { useReadReceipt } from '../../../hooks/useReadReceipt'; + +export interface ChatProps { + conversation: CachedConversation; + onBack: () => void; +} + +export const Chat: React.FC = ({ conversation, onBack }) => { + const { openEnsProfile } = useJustWeb3(); + const [replyMessage, setReplyMessage] = useState( + null + ); + const [reactionMessage, setReactionMessage] = + useState(null); + const [isRequest, setIsRequest] = useState(false); + const [isRequestChangeLoading, setIsRequestChangeLoading] = + useState(false); + + const { entries, allow, refreshConsentList, deny } = useConsent(); + const { mutateAsync: sendReaction } = useSendReactionMessage(conversation); + const { primaryName } = usePrimaryName({ + address: conversation.peerAddress as `0x${string}`, + }); + const { records } = useRecords({ ens: primaryName }); + const { address } = useMountedAccount(); + const [canMessage, setCanMessage] = useState(true); + const { messages, isLoading } = useMessages(conversation); + const { canMessage: canMessageFn, isLoading: isCanMessageLoading } = + useCanMessage(); + const { mutateAsync: readReceipt, isPending: isReadReceiptSending } = + useReadReceipt(conversation); + useStreamMessages(conversation); + + useEffect(() => { + const lastMessage = messages[messages.length - 1]; + + if (!lastMessage || isReadReceiptSending) return; + + if (lastMessage?.contentType === ContentTypeReadReceipt.toString()) { + return; + } + + readReceipt(); + }, [messages, readReceipt, isReadReceiptSending]); + + // Determine if user can message + useEffect(() => { + if (isCanMessageLoading) return; + canMessageFn(conversation.peerAddress).then(setCanMessage); + }, [isCanMessageLoading, conversation, canMessageFn]); + + // Check if conversation is in "request" state + useEffect(() => { + const convoConsentState = entries[conversation.peerAddress]?.permissionType; + setIsRequest( + convoConsentState === 'unknown' || convoConsentState === undefined + ); + }, [entries, conversation.peerAddress]); + + // Scroll to last message when messages change + useEffect(() => { + if (messages.length === 0) return; + setTimeout(() => { + const lastMessageId = messages[messages.length - 1]?.id; + const element = document.getElementById(lastMessageId); + if (element) { + element.scrollIntoView({ behavior: 'smooth' }); + } + }, 500); + }, [messages, conversation]); + + // Filter out read receipts and group messages by date + const filteredMessages = useMemo(() => { + const withoutRead = messages.filter( + (message) => message.contentType !== 'xmtp.org/readReceipt:1.0' + ); + return filterReactionsMessages(withoutRead); + }, [messages]); + + const groupedMessages = useMemo(() => { + return groupMessagesByDate(filteredMessages ?? []); + }, [filteredMessages]); + + const isMessagesSenderOnly = useMemo(() => { + return filteredMessages.every( + (message) => message.senderAddress === address + ); + }, [filteredMessages, address]); + + const isStringContent = + typeof replyMessage?.content === 'string' || + typeof replyMessage?.content?.content === 'string'; + + const mimeType = replyMessage?.content?.mimeType; + const type = mimeType ? typeLookup[mimeType.split('/')?.[1]] : null; + + const computeHeight = useMemo(() => { + const baseHeight = 'calc(100vh - 50px - 3rem - 1.5rem - 73px - 15px)'; + const adjustments: string[] = []; + + if (isRequest) adjustments.push('40px'); + if (replyMessage) { + if (isStringContent) { + adjustments.push('46px'); + } else if (mimeType === 'audio/wav') { + adjustments.push('61px'); + } else if (type === 'video' || type === 'image') { + adjustments.push('116px'); + } else { + adjustments.push('47px'); + } + } + if (isMessagesSenderOnly) adjustments.push('59px'); + + if (adjustments.length === 0) return baseHeight; + return `${baseHeight}${adjustments.map((val) => ` - ${val}`).join('')}`; + }, [ + replyMessage, + isMessagesSenderOnly, + isStringContent, + mimeType, + type, + isRequest, + ]); + + // Handlers + const blockAddressHandler = async (peerAddress: string) => { + setIsRequestChangeLoading(true); + await refreshConsentList(); + await deny([peerAddress]); + await refreshConsentList(); + setIsRequestChangeLoading(false); + onBack(); + }; + + const handleAllowAddress = async () => { + setIsRequestChangeLoading(true); + await refreshConsentList(); + await allow([conversation.peerAddress]); + await refreshConsentList(); + setIsRequest(false); + setIsRequestChangeLoading(false); + }; + + const handleEmojiSelect = (emoji: string) => { + if (!reactionMessage) return; + sendReaction({ + action: 'added', + content: emoji, + referenceId: reactionMessage.id, + }); + setReactionMessage(null); + const replica = document.getElementById(`${reactionMessage?.id}-replica`); + replica?.remove(); + }; + + return ( + + {/* Overlay for reaction */} + { + setReactionMessage(null); + const replica = document.getElementById( + `${reactionMessage?.id}-replica` + ); + replica?.remove(); + }} + /> + + + + + {isCanMessageLoading || isLoading ? ( + + ) : ( + + )} + + {isRequest ? ( + + ) : ( + setReplyMessage(null)} + /> + )} + + + ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/NewChat/NewChatTextField/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/NewChat/NewChatTextField/index.tsx new file mode 100644 index 00000000..81b5e15d --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/NewChat/NewChatTextField/index.tsx @@ -0,0 +1,68 @@ +import React, { useState } from 'react'; +import { Flex, Input, LoadingSpinner, SendIcon } from '@justweb3/ui'; + +interface NewChatTextFieldProps { + disabled?: boolean; + onNewConvo: (message: string) => void; + style?: React.CSSProperties; +} + +export const NewChatTextField: React.FC = ({ + disabled, + onNewConvo, + style, +}) => { + const [messageValue, setMessageValue] = useState(''); + const [isNewMessageLoading, setIsNewMessageLoading] = + useState(false); + + const handleSendMessage = async () => { + if (messageValue.trim().length === 0 || disabled) return; + setIsNewMessageLoading(true); + await onNewConvo(messageValue); + setIsNewMessageLoading(false); + setMessageValue(''); + }; + + return ( + + {isNewMessageLoading ? ( + + + + ) : ( + + } + onKeyDown={(e) => { + if (e.key === 'Enter') { + handleSendMessage(); + } + }} + onChange={(e) => setMessageValue(e.target.value)} + /> + )} + + ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/NewChat/index.tsx similarity index 96% rename from packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx rename to packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/NewChat/index.tsx index 8190c568..6d8e2df6 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/NewConversation/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/NewChat/index.tsx @@ -8,7 +8,6 @@ import { useStartConversation, } from '@xmtp/react-sdk'; import React, { useEffect, useMemo } from 'react'; -import MessageTextField from '../MessageTextField'; import { useDebounce } from '@justweb3/widget'; import { useMountedAccount, @@ -25,14 +24,15 @@ import { P, VerificationsIcon, } from '@justweb3/ui'; +import { NewChatTextField } from './NewChatTextField'; -interface NewConversationProps { +interface NewChatProps { onChatStarted: (conversation: CachedConversation) => void; onBack: () => void; selectedAddress?: string; } -const NewConversation: React.FC = ({ +export const NewChat: React.FC = ({ onChatStarted, onBack, selectedAddress, @@ -102,7 +102,7 @@ const NewConversation: React.FC = ({ } }; - const handleNewConversation = async (message: string) => { + const handleNewChat = async (message: string) => { if (!client) return; const peerAddress = isAddressName && !!resolvedAddress ? resolvedAddress : debouncedAddress; @@ -303,10 +303,9 @@ const NewConversation: React.FC = ({ padding: '0px 1.5rem', }} > - = ({ ); }; -export default NewConversation; +export default NewChat; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx index 98960a88..a4c57e5e 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/index.tsx @@ -1,184 +1,55 @@ -import { - AddIcon, - Flex, - Sheet, - SheetContent, - SheetTitle, - Tabs, - TabsContent, - TabsList, - TabsTrigger, -} from '@justweb3/ui'; -import { - CachedConversation, - ContentTypeMetadata, - useConsent, - useConversations, - useStreamAllMessages, - useStreamConversations, -} from '@xmtp/react-sdk'; -import React, { useEffect, useMemo } from 'react'; -import { ChatList } from '../ChatList'; +import { CachedConversation, ContentTypeMetadata } from '@xmtp/react-sdk'; +import { Sheet, SheetContent, SheetTitle } from '@justweb3/ui'; +import { Chat } from './Chat'; +import { useMemo } from 'react'; +import { NewChat } from './NewChat'; export interface ChatSheetProps { - open?: boolean; - handleOpen?: (open: boolean) => void; - handleOpenChat: ( - conversation: CachedConversation + // peerAddress?: string | null; + peer: CachedConversation | string | null; + openChat: boolean; + closeChat: () => void; + onChangePeer: ( + peer: CachedConversation | string ) => void; - handleNewChat: () => void; } export const ChatSheet: React.FC = ({ - open, - handleOpen, - handleOpenChat, - handleNewChat, + peer, + closeChat, + openChat, + onChangePeer, }) => { - const [tab, setTab] = React.useState('Chats'); - const { conversations, isLoading } = useConversations(); - const [isConsentListLoading, setIsConsentListLoading] = React.useState(true); - const { loadConsentList, entries } = useConsent(); - - const allowedConversations = useMemo(() => { - return conversations.filter( - (convo) => - entries && - entries[convo.peerAddress] && - entries[convo.peerAddress]?.permissionType === 'allowed' - ); - }, [conversations, entries]); - - const blockedConversations = useMemo(() => { - return conversations.filter( - (convo) => - entries && - entries[convo.peerAddress] && - entries[convo.peerAddress]?.permissionType === 'denied' - ); - }, [conversations, entries]); - - const requestConversations = useMemo(() => { - return conversations.filter((convo) => { - if (!entries[convo.peerAddress]) return true; - return entries[convo.peerAddress]?.permissionType === 'unknown'; - }); - }, [conversations, entries]); - - useEffect(() => { - loadConsentList().then(() => { - setIsConsentListLoading(false); - }); - }, [loadConsentList]); - - useStreamConversations(); - useStreamAllMessages(); + const isPeerConversation = useMemo(() => { + return typeof peer !== 'string'; + }, [peer]); return ( - - - Chats - - - - setTab(value)} - style={{ - display: 'flex', - flexDirection: 'column', - marginBottom: '0px', - overflow: 'hidden', - marginTop: '10px', - flex: '1', - }} - > - - - Chats - - - Requests - {requestConversations.length > 0 && ( - - {requestConversations.length} - - )} - - - Blocked - - - {isLoading || isConsentListLoading ? ( -
Loading...
+ !open && closeChat()}> + + + {isPeerConversation ? 'Messages' : 'New Conversation'} + + + {peer !== null && + (isPeerConversation ? ( + } + onBack={closeChat} + /> ) : ( - <> - - - - - - - - - - - )} -
+ { + onChangePeer(conversation); + }} + /> + ))}
); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/CustomPlayer/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/CustomPlayer/index.tsx deleted file mode 100644 index 1ab77a3c..00000000 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/CustomPlayer/index.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { DownloadIcon, Flex, PauseIcon, PlayIcon } from '@justweb3/ui'; -import React, { useEffect, useRef, useState } from 'react'; - - -export interface CustomPlayerProps { - style?: React.CSSProperties; - url?: string; - disabled?: boolean; - fileName?: string; -} - -export const CustomPlayer: React.FC = ({ - style, - url = '', - disabled, - fileName -}) => { - const [playing, setPlaying] = React.useState(false); - const videoRef = useRef(null); - const [hovered, setHovered] = useState(false) - - const togglePlay = () => { - if (disabled) return; - if (videoRef.current) { - if (playing) { - videoRef.current.pause(); - } else { - videoRef.current.play(); - } - setPlaying(!playing); - } - }; - - useEffect(() => { - const handleVisibilityChange = () => { - if (document.hidden && playing && videoRef.current) { - videoRef.current.pause(); - } - }; - document.addEventListener('visibilitychange', handleVisibilityChange); - return () => { - document.removeEventListener('visibilitychange', handleVisibilityChange); - if (videoRef.current && playing) { - videoRef.current.pause(); - setPlaying(false); - } - }; - }, [playing]); - - return ( - { setHovered(true) }} - onMouseLeave={() => { setHovered(false) }} - onClick={togglePlay} - style={{ - aspectRatio: '16/9', - position: 'relative', - // TODO: check background color - background: 'var(--justweb3-background-color)', - cursor: 'pointer', - borderRadius: '10px', - border: '1px solid var(--justweb3-primary-color)', - ...style - }}> - - ); -} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/CustomVoicePreview/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/CustomVoicePreview/index.tsx deleted file mode 100644 index f90bd51d..00000000 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/CustomVoicePreview/index.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { CloseIcon, Flex, P, PauseIcon, PlayIcon } from '@justweb3/ui'; -import React, { useEffect, useRef, useState } from 'react'; -import useGetAudioDuration from '../../hooks/useGetAudioDuration'; -import { formatTime } from '../../utils/formatVoiceTime'; - - -interface CustomVoicePreviewProps { - audioUrl: string; - onCancel: () => void; -} - -const CustomVoicePreview: React.FC = ({ - audioUrl, - onCancel -}) => { - const [playing, setPlaying] = useState(false); - const [currentTime, setCurrentTime] = useState(0); - const audioRef = useRef(new Audio()); - - const audioDuration = useGetAudioDuration(audioUrl); - - useEffect(() => { - const audio = new Audio(); - audioRef.current = audio; - - const onTimeUpdate = () => { - setCurrentTime(audio.currentTime); - }; - - const onEnded = () => { - setPlaying(false); - setCurrentTime(0); - }; - - audio.src = audioUrl; - audio.addEventListener('timeupdate', onTimeUpdate); - audio.addEventListener('ended', onEnded); - - return () => { - audio.removeEventListener('timeupdate', onTimeUpdate); - audio.removeEventListener('ended', onEnded); - }; - }, [audioUrl]); - - const handlePlayPause = () => { - const audio = audioRef.current; - if (!audio) return; - - if (playing) { - audio.pause(); - } else { - audio.play(); - } - setPlaying(!playing); - }; - - return ( - - {playing ? - - : - - } -

{playing || currentTime > 0 ? formatTime(currentTime) : formatTime(audioDuration ?? 0)}

- -
- ); -}; - -export default CustomVoicePreview; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/EmojiSelector/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/EmojiSelector/index.tsx deleted file mode 100644 index c57959d1..00000000 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/EmojiSelector/index.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { Flex, Input } from '@justweb3/ui'; -import React, { useMemo } from 'react'; -import { EmojiObject, emojis } from '../../utils/emojis'; -import { useDebounced } from '../../hooks'; - - -interface EmojiSelectorProps { - onEmojiSelect: (emoji: string) => void; -} - -const EmojiSelector: React.FC = ({ - onEmojiSelect, -}) => { - const [searchValue, setSearchValue] = React.useState(""); - - const { - value: debouncedSearch, - } = useDebounced(searchValue, 50); - - const onEmojiClickHandler = (emoji: EmojiObject) => { - onEmojiSelect(emoji.name); - - } - - const filteredEmojis = useMemo(() => { - if (debouncedSearch.length === 0) return emojis; - const filteredEmojis = emojis.filter(emoji => - emoji.name.toLowerCase().includes(debouncedSearch.toLowerCase()) - ); - return filteredEmojis; - }, [debouncedSearch]); - - - return ( - - setSearchValue(e.target.value)} - /> -
- {filteredEmojis.map((emoji, index) => ( - - ))} -
-
- - ); -}; - -export default EmojiSelector; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/ChatList/MessageItem/index.tsx similarity index 56% rename from packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx rename to packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/ChatList/MessageItem/index.tsx index 19b1bf23..a994b787 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageItem/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/ChatList/MessageItem/index.tsx @@ -1,41 +1,50 @@ import { attachmentContentTypeConfig, CachedConversation, + CachedMessage, ContentTypeMetadata, reactionContentTypeConfig, replyContentTypeConfig, useConsent, - useLastMessage, useStreamMessages, } from '@xmtp/react-sdk'; import { useEnsAvatar, useRecords } from '@justaname.id/react'; import { Avatar, Button, Flex, formatText, P, SPAN } from '@justweb3/ui'; import React, { useMemo } from 'react'; -import { formatChatDate } from '../../utils/formatChatDate'; +import { formatChatDate } from '../../../../utils/formatChatDate'; export interface MessageItemProps { conversation: CachedConversation; onClick?: () => void; blocked?: boolean; primaryName?: string | null; + conversationInfo?: { + conversationId: string; + unreadCount: number; + consent: 'allowed' | 'blocked' | 'requested'; + lastMessage: CachedMessage; + }; } -export const MessageItem: React.FC = ({ +const MessageItem: React.FC = ({ conversation, onClick, blocked, primaryName, + conversationInfo, }) => { - const lastMessage = useLastMessage(conversation.topic); useStreamMessages(conversation); - // const { primaryName } = usePrimaryName({ - // address: conversation.peerAddress as `0x${string}`, - // }); + // const { messages } = useMessages(conversation); const { records } = useRecords({ ens: primaryName || undefined, }); const { sanitizeEnsImage } = useEnsAvatar(); + // const unreadMessages = useMemo(() => { + // if (!lastMessage) return false; + // return lastMessage.contentType !== ContentTypeReadReceipt.toString(); + // }, [lastMessage]); + const { allow, refreshConsentList } = useConsent(); const allowUser = async () => { @@ -44,7 +53,10 @@ export const MessageItem: React.FC = ({ await refreshConsentList(); }; + console.log('conversationInfo', conversationInfo); + const lastContent = useMemo(() => { + const lastMessage = conversationInfo?.lastMessage; if (!lastMessage) return ''; if (typeof lastMessage.content === 'string') { @@ -72,7 +84,9 @@ export const MessageItem: React.FC = ({ } return lastMessage.contentFallback; - }, [lastMessage]); + }, [conversationInfo, conversationInfo?.lastMessage]); + + console.log(lastContent); return ( = ({ lineHeight: '12px', }} > - {lastMessage - ? lastMessage.senderAddress !== conversation.peerAddress + {conversationInfo?.lastMessage + ? conversationInfo?.lastMessage.senderAddress !== + conversation.peerAddress ? 'You: ' : '' : ''} - {lastMessage + {conversationInfo?.lastMessage ? lastContent ? lastContent : 'No preview available' @@ -148,11 +163,55 @@ export const MessageItem: React.FC = ({ Unblock ) : ( - - {lastMessage?.sentAt ? formatChatDate(lastMessage.sentAt) : ''} - +
+ + {conversationInfo?.lastMessage?.sentAt + ? formatChatDate(conversationInfo?.lastMessage.sentAt) + : ''} + + {!!conversationInfo?.unreadCount && + conversationInfo?.unreadCount > 0 && ( +
+ + {conversationInfo?.unreadCount} + +
+ )} +
)}
); }; + +const MessageItemMemo = React.memo(MessageItem, (prevProps, nextProps) => { + return JSON.stringify(prevProps) === JSON.stringify(nextProps); +}); + +export { MessageItemMemo as MessageItem }; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/ChatList/index.tsx similarity index 60% rename from packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx rename to packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/ChatList/index.tsx index 3ff94d5f..c9cd170e 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatList/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/ChatList/index.tsx @@ -1,7 +1,11 @@ import { Flex } from '@justweb3/ui'; -import { CachedConversation, ContentTypeMetadata } from '@xmtp/react-sdk'; +import { + CachedConversation, + CachedMessage, + ContentTypeMetadata, +} from '@xmtp/react-sdk'; import React from 'react'; -import { MessageItem } from '../MessageItem'; +import { MessageItem } from './MessageItem'; import { usePrimaryNameBatch } from '@justaname.id/react'; export interface ChatListProps { @@ -10,12 +14,19 @@ export interface ChatListProps { conversation: CachedConversation ) => void; blockedList?: boolean; + conversationsInfo?: { + conversationId: string; + unreadCount: number; + consent: 'allowed' | 'blocked' | 'requested'; + lastMessage: CachedMessage; + }[]; } export const ChatList: React.FC = ({ conversations, handleOpenChat, blockedList, + conversationsInfo, }) => { const { allPrimaryNames } = usePrimaryNameBatch({ addresses: conversations.map((conversation) => conversation.peerAddress), @@ -33,6 +44,15 @@ export const ChatList: React.FC = ({ item.conversationId === conversation.topic + // )?.unreadCount + // } + // + conversationInfo={conversationsInfo?.find( + (item) => item.conversationId === conversation.topic + )} onClick={() => handleOpenChat(conversation)} key={conversation.topic} blocked={blockedList} diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/index.tsx new file mode 100644 index 00000000..c4496252 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/index.tsx @@ -0,0 +1,274 @@ +import { + AddIcon, + Flex, + Sheet, + SheetContent, + SheetTitle, + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from '@justweb3/ui'; +import { + CachedConversation, + CachedMessage, + ContentTypeMetadata, + useConsent, + useConversations, + useStreamAllMessages, + useStreamConversations, +} from '@xmtp/react-sdk'; +import React, { useEffect, useMemo } from 'react'; +import { ChatList } from './ChatList'; + +export interface InboxSheetProps { + open?: boolean; + handleOpen?: (open: boolean) => void; + handleOpenChat: ( + conversation: CachedConversation + ) => void; + handleNewChat: () => void; + onConversationsUpdated: ({ + allowed, + blocked, + requested, + }: { + allowed: CachedConversation[]; + blocked: CachedConversation[]; + requested: CachedConversation[]; + }) => void; + allConversations: { + allowed: CachedConversation[]; + blocked: CachedConversation[]; + requested: CachedConversation[]; + }; + conversationsInfo?: { + conversationId: string; + unreadCount: number; + consent: 'allowed' | 'blocked' | 'requested'; + lastMessage: CachedMessage; + }[]; +} + +export const InboxSheet: React.FC = ({ + open, + handleOpen, + handleOpenChat, + handleNewChat, + onConversationsUpdated, + allConversations, + conversationsInfo, +}) => { + const [tab, setTab] = React.useState('Chats'); + const { conversations, isLoading } = useConversations(); + + const [isConsentListLoading, setIsConsentListLoading] = React.useState(true); + const { loadConsentList, entries } = useConsent(); + + const allowedConversations = useMemo(() => { + return conversations.filter( + (convo) => + entries && + entries[convo.peerAddress] && + entries[convo.peerAddress]?.permissionType === 'allowed' + ); + }, [conversations, entries]); + + const blockedConversations = useMemo(() => { + return conversations.filter( + (convo) => + entries && + entries[convo.peerAddress] && + entries[convo.peerAddress]?.permissionType === 'denied' + ); + }, [conversations, entries]); + + const requestConversations = useMemo(() => { + return conversations.filter((convo) => { + if (!entries[convo.peerAddress]) return true; + return entries[convo.peerAddress]?.permissionType === 'unknown'; + }); + }, [conversations, entries]); + + useEffect(() => { + let _allowedConversations = [] as CachedConversation[]; + let _blockedConversations = [] as CachedConversation[]; + let _requestConversations = [] as CachedConversation[]; + + if ( + allowedConversations.some( + (convo) => + !allConversations.allowed.some((c) => c.topic === convo.topic) + ) + ) { + _allowedConversations = allowedConversations.filter( + (convo) => + !allConversations.allowed.some((c) => c.topic === convo.topic) + ); + // onConversationsUpdated([...allConversations, ...newConversations]); + } + + if ( + blockedConversations.some( + (convo) => + !allConversations.blocked.some((c) => c.topic === convo.topic) + ) + ) { + _blockedConversations = blockedConversations.filter( + (convo) => + !allConversations.blocked.some((c) => c.topic === convo.topic) + ); + } + + if ( + requestConversations.some( + (convo) => + !allConversations.requested.some((c) => c.topic === convo.topic) + ) + ) { + _requestConversations = requestConversations.filter( + (convo) => + !allConversations.requested.some((c) => c.topic === convo.topic) + ); + } + + if ( + _allowedConversations.length > 0 || + _blockedConversations.length > 0 || + _requestConversations.length > 0 + ) { + onConversationsUpdated({ + allowed: [...allConversations.allowed, ..._allowedConversations], + blocked: [...allConversations.blocked, ..._blockedConversations], + requested: [...allConversations.requested, ..._requestConversations], + }); + } + }, [ + allConversations, + allowedConversations, + blockedConversations, + onConversationsUpdated, + requestConversations, + ]); + + useEffect(() => { + loadConsentList().then(() => { + setIsConsentListLoading(false); + }); + }, [loadConsentList]); + + useStreamConversations(); + useStreamAllMessages(); + + return ( + + + Chats + + + + setTab(value)} + style={{ + display: 'flex', + flexDirection: 'column', + marginBottom: '0px', + overflow: 'hidden', + marginTop: '10px', + flex: '1', + }} + > + + + Chats + + + Requests + {requestConversations.length > 0 && ( + + {requestConversations.length} + + )} + + + Blocked + + + {isLoading || isConsentListLoading ? ( +
Loading...
+ ) : ( + <> + + + + + + + + + + + )} +
+
+
+ ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx deleted file mode 100644 index f39ebfbf..00000000 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageSheet/index.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { CachedConversation, ContentTypeMetadata } from '@xmtp/react-sdk'; -import { Sheet, SheetContent, SheetTitle } from '@justweb3/ui'; -import { Chat } from '../Chat'; - -export interface MessageSheetProps { - conversation: CachedConversation | null; - openChat: boolean; - handleOpenChat: ( - conversation: CachedConversation | null - ) => void; -} - -export const MessageSheet: React.FC = ({ - conversation, - handleOpenChat, - openChat, -}) => { - return ( - !open && handleOpenChat(null)} - > - - Messages - {conversation && handleOpenChat(null)} />} - - - ); -}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx deleted file mode 100644 index 6c6acbfc..00000000 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/MessageTextField/index.tsx +++ /dev/null @@ -1,651 +0,0 @@ -import type { Attachment } from '@xmtp/content-type-remote-attachment'; -import { CachedConversation, useClient } from '@xmtp/react-sdk'; -import React, { - Dispatch, - SetStateAction, - useEffect, - useMemo, - useRef, - useState, -} from 'react'; -import { MessageWithReaction } from '../../utils/filterReactionsMessages'; -import { useMountedAccount, usePrimaryName } from '@justaname.id/react'; -import { - useAttachmentChange, - useRecordingTimer, - useRecordVoice, - useSendAttachment, - useSendMessages, - useSendReplyMessage, -} from '../../hooks'; -import { AttachmentType, typeLookup } from '../../utils/attachments'; -import { - AddFolderIcon, - AddImageIcon, - AddVideoIcon, - Button, - CloseIcon, - DocumentIcon, - Flex, - Input, - LoadingSpinner, - MicIcon, - P, - SendIcon, - StopIcon, -} from '@justweb3/ui'; -import { formatAddress } from '../../utils/formatAddress'; -import VoiceMessageCard from '../VoiceMessageCard'; -import { CustomPlayer } from '../CustomPlayer'; -import CustomVoicePreview from '../CustomVoicePreview'; - -interface MessageTextFieldProps { - newConvo?: boolean; - disabled?: boolean; - conversation?: CachedConversation; - replyMessage?: MessageWithReaction | null; - onCancelReply?: () => void; - onNewConvo?: (message: string) => void; - peerAddress?: string; - style?: React.CSSProperties; -} - -const MessageTextField: React.FC = ({ - newConvo, - disabled, - replyMessage, - onCancelReply, - conversation, - onNewConvo, - peerAddress, - style, -}) => { - const [messageValue, setMessageValue] = React.useState(''); - const [attachment, setAttachment] = React.useState(); - const [attachmentPreview, setAttachmentPreview] = React.useState< - string | undefined - >(); - const [isNewMessageLoading, setIsNewMessageLoading] = - React.useState(false); - // const [selectingAttachment, setSelectingAttachment] = React.useState(false); - const { client } = useClient(); - const { address } = useMountedAccount(); - const { mutateAsync: sendMessage } = useSendMessages(conversation); - const { mutateAsync: sendReply } = useSendReplyMessage(conversation); - const { mutateAsync: sendAttachment } = useSendAttachment(conversation); - - const attachmentExtention = useMemo(() => { - return attachment?.mimeType.split('/')?.[1] || ''; - }, [attachment]); - - const { primaryName } = usePrimaryName({ - address: peerAddress as `0x${string}`, - }); - - // Attachments - const [acceptedTypes, setAcceptedTypes]: [ - string | string[] | undefined, - Dispatch> - ] = useState(); - const inputFile = useRef(null); - const { onAttachmentChange } = useAttachmentChange({ - setAttachment, - setAttachmentPreview, - onError: (error) => { - // showToast("error", error); - }, - }); - - // Recording - const { recording, startRecording, stopRecording } = useRecordVoice({ - setAttachment, - setAttachmentPreview, - }); - const { start, pause, reset, recordingValue } = useRecordingTimer({ - stopRecording, - status: recording ? 'recording' : 'idle', - }); - - // Sending text message - const handleSendMessage = async () => { - if (messageValue.length === 0) return; - if (!client) return; - if (disabled) return; - if (newConvo) { - setIsNewMessageLoading(true); - onNewConvo && onNewConvo(messageValue); - setIsNewMessageLoading(false); - } else { - if (replyMessage) { - sendReply({ - message: messageValue, - referenceId: replyMessage.id, - }); - onCancelReply && onCancelReply(); - } else { - sendMessage(messageValue); - } - } - setMessageValue(''); - }; - - // Sending attachment - const handleSendAttachment = async () => { - if (!client) return; - if (!attachment) return; - if (disabled) return; - if (newConvo) { - onNewConvo && onNewConvo(messageValue); - } else { - sendAttachment(attachment); - } - setMessageValue(''); - setAttachment(undefined); - setAttachmentPreview(undefined); - // setSelectingAttachment(false); - }; - - const handleCancelAttachment = () => { - setAttachment(undefined); - setAttachmentPreview(undefined); - }; - - const onButtonClick = (contentType: AttachmentType) => { - if (contentType === 'application') { - setAcceptedTypes('all'); - } else { - const acceptedFileTypeList = Object.keys(typeLookup).reduce( - (acc: string[], key: string) => { - if (typeLookup[key] === contentType) acc.push(`.${key}`); - return acc; - }, - [] - ); - setAcceptedTypes([...acceptedFileTypeList]); - } - }; - - // Reply message - const isSender = useMemo(() => { - return address === replyMessage?.senderAddress; - }, [replyMessage, address]); - const isReplyVoice = useMemo(() => { - return replyMessage?.content.mimeType === 'audio/wav'; - }, [replyMessage]); - - const isReplyText = useMemo(() => { - if (!replyMessage) return false; - return typeof replyMessage.content === 'string'; - }, [replyMessage]); - - const isReplyReply = useMemo(() => { - if (!replyMessage) return false; - return !!replyMessage.content.reference; - }, [replyMessage]); - - const replyAttachmentExtention = useMemo(() => { - if (!isReplyText && !!replyMessage && !isReplyReply) - return replyMessage.content.mimeType.split('/')?.[1] || ''; - }, [isReplyText, replyMessage, isReplyReply]); - - const navigateToRepliedMessage = () => { - if (!replyMessage) return; - const element = document.getElementById(replyMessage.id.toString()); - if (element) { - element.scrollIntoView({ - block: 'end', - behavior: 'smooth', - }); - } - }; - - useEffect(() => { - if (acceptedTypes) { - inputFile?.current?.click(); - } - }, [acceptedTypes]); - - const isReplyVideoOrImage = useMemo(() => { - return ( - typeLookup[replyAttachmentExtention] === 'image' || - typeLookup[replyAttachmentExtention] === 'video' - ); - }, [replyAttachmentExtention]); - - return ( - - {!replyMessage} - {!newConvo && ( - - onButtonClick('image')} - style={{ - cursor: 'pointer', - }} - /> - onButtonClick('video')} - style={{ - cursor: 'pointer', - }} - /> - onButtonClick('application')} - style={{ - cursor: 'pointer', - }} - /> - - - )} -
- {replyMessage && ( - - -

- {isSender - ? 'YOU' - : primaryName ?? formatAddress(replyMessage.senderAddress)} -

- {isReplyText || isReplyReply ? ( -

- {isReplyReply - ? replyMessage.content.content - : replyMessage.content} -

- ) : isReplyVoice ? ( - - ) : typeLookup[replyAttachmentExtention] === 'image' ? ( - {replyMessage.content.filename} - ) : typeLookup[replyAttachmentExtention] === 'video' ? ( - - ) : ( - - -

- {replyMessage.content.filename} -

-
- )} -
- -
- )} - {attachmentPreview ? ( - - {attachment?.mimeType !== 'audio/wav' && ( -
- )} - {attachment?.mimeType === 'audio/wav' ? ( - - ) : ( - - {typeLookup[attachmentExtention] === 'image' ? ( - {attachment?.filename} - ) : typeLookup[attachmentExtention] === 'video' ? ( - - ) : ( - - -

- {attachment?.filename ?? 'Cannot preview'} -

-
- )} - - - - -
- )} - { - if (disabled) return; - handleSendAttachment(); - }} - /> - - ) : recording ? ( - -

- {recordingValue} -

-

- RECORDING... -

- { - stopRecording(); - pause(); - reset(); - }} - /> -
- ) : isNewMessageLoading ? ( - - - - ) : ( - { - if (disabled) return; - startRecording(); - start(); - }} - /> - ) - } - right={ - { - if (disabled) return; - handleSendMessage(); - }} - /> - } - disabled={disabled} - onKeyDown={(e) => { - if (e.key === 'Enter') { - handleSendMessage(); - } - }} - onChange={(e) => setMessageValue(e.target.value)} - /> - )} -
-
- ); -}; - -export default MessageTextField; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/NewMessageSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/NewMessageSheet/index.tsx deleted file mode 100644 index 69a14e41..00000000 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/NewMessageSheet/index.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Sheet, SheetContent, SheetTitle } from '@justweb3/ui'; -import { CachedConversation } from '@xmtp/react-sdk'; -import NewConversation from '../NewConversation'; - -export interface MessageSheetProps { - openNewChat: boolean; - handleOpenNewChat: (open: boolean) => void; - onChatStarted: (conversation: CachedConversation) => void; - addressOrEns?: string; -} - -export const NewMessageSheet: React.FC = ({ - handleOpenNewChat, - openNewChat, - onChatStarted, - addressOrEns, -}) => { - return ( - !open && handleOpenNewChat(false)} - > - - New Conversation - handleOpenNewChat(false)} - selectedAddress={addressOrEns} - /> - - - ); -}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatWithProfileButton/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ProfileChatButton/index.tsx similarity index 96% rename from packages/@justweb3/xmtp-plugin/src/lib/components/ChatWithProfileButton/index.tsx rename to packages/@justweb3/xmtp-plugin/src/lib/components/ProfileChatButton/index.tsx index 0e839180..c0965bde 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatWithProfileButton/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ProfileChatButton/index.tsx @@ -8,13 +8,13 @@ import { useEthersSigner } from '../../hooks'; import { loadKeys, storeKeys, wipeKeys } from '../../utils/xmtp'; import { ChainId } from '@justaname.id/sdk'; -export interface ChatWithProfileButtonProps { +export interface ProfileChatButtonProps { ens: string; env: 'local' | 'production' | 'dev'; chainId: ChainId; } -export const ChatWithProfileButton: React.FC = ({ +export const ProfileChatButton: React.FC = ({ ens, env, chainId, diff --git a/packages/@justweb3/xmtp-plugin/src/lib/content-types/readReceipt.ts b/packages/@justweb3/xmtp-plugin/src/lib/content-types/readReceipt.ts new file mode 100644 index 00000000..12c0a2c2 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/content-types/readReceipt.ts @@ -0,0 +1,120 @@ +import { + ContentTypeReadReceipt, + ReadReceiptCodec, +} from '@xmtp/content-type-read-receipt'; +import { z } from 'zod'; +import { isAfter, parseISO } from 'date-fns'; +import { + CachedConversation, + ContentTypeConfiguration, + ContentTypeMessageProcessor, + ContentTypeMetadataValues, + getCachedConversationByTopic, +} from '@xmtp/react-sdk'; +import { Mutex } from 'async-mutex'; +import { ContentTypeId } from '@xmtp/content-type-primitives'; + +const NAMESPACE = 'readReceipt'; +export type CachedReadReceiptMetadata = { + incoming: string | undefined; + outgoing: string | undefined; +}; +/** + * Retrieve the read receipt from a cached conversation for the given type + * + * @param conversation Cached conversation + * @returns The read receipt date, or `undefined` if the conversation + * has no read receipt for the given type + */ +export const getReadReceipt = ( + conversation: CachedConversation, + type: keyof CachedReadReceiptMetadata +) => { + const metadata = conversation?.metadata?.[NAMESPACE] as + | CachedReadReceiptMetadata + | undefined; + const readReceiptType = metadata?.[type]; + return readReceiptType ? parseISO(readReceiptType) : undefined; +}; +/** + * Check if a cached conversation has a read receipt for the given type + * + * @param conversation Cached conversation + * @returns `true` if the conversation has a read receipt for the given type, + * `false` otherwise + */ +export const hasReadReceipt = ( + conversation: CachedConversation, + type: keyof CachedReadReceiptMetadata +) => getReadReceipt(conversation, type) !== undefined; +const ReadReceiptContentSchema = z.object({}).strict(); +/** + * Validate the content of a read receipt message + * + * @param content Message content + * @returns `true` if the content is valid, `false` otherwise + */ +const isValidReadReceiptContent = (content: unknown) => { + const { success } = ReadReceiptContentSchema.safeParse(content); + return success; +}; +const processReadReceiptMutex = new Mutex(); +/** + * Process a read receipt message + * + * Updates the metadata of its conversation with the timestamp of the + * read receipt. + */ +export const processReadReceipt: ContentTypeMessageProcessor = async ({ + client, + db, + message, + conversation, + updateConversationMetadata, +}) => { + // ensure that only 1 read receipt message is processed at a time to preserve order + await processReadReceiptMutex.runExclusive(async () => { + const contentType = ContentTypeId.fromString(message.contentType); + // always use the latest conversation from the cache + const updatedConversation = await getCachedConversationByTopic( + client.address, + conversation.topic, + db + ); + if (updatedConversation) { + const isIncoming = message.senderAddress !== client.address; + const readReceiptType = isIncoming ? 'incoming' : 'outgoing'; + const readReceiptDate = getReadReceipt( + updatedConversation, + readReceiptType + ); + if ( + ContentTypeReadReceipt.sameAs(contentType) && + conversation && + isValidReadReceiptContent(message.content) && + // ignore read receipts that are older than the current one + (!readReceiptDate || isAfter(message.sentAt, readReceiptDate)) + ) { + const metadata = updatedConversation.metadata?.[NAMESPACE] as + | CachedReadReceiptMetadata + | undefined; + // update conversation metadata with the appropriate read receipt + await updateConversationMetadata({ + ...(metadata ?? {}), + [readReceiptType]: message.sentAt.toISOString(), + } as ContentTypeMetadataValues); + } + } + }); +}; +export const readReceiptContentTypeConfig: ContentTypeConfiguration = { + codecs: [new ReadReceiptCodec()], + contentTypes: [ContentTypeReadReceipt.toString()], + namespace: NAMESPACE, + processors: { + [ContentTypeReadReceipt.toString()]: [processReadReceipt], + }, + validators: { + [ContentTypeReadReceipt.toString()]: isValidReadReceiptContent, + }, +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useGetAudioDuration/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useGetAudioDuration/index.tsx index ce7dc3c6..91b2af54 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useGetAudioDuration/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useGetAudioDuration/index.tsx @@ -1,41 +1,44 @@ import { useEffect, useState } from 'react'; -const useGetAudioDuration = (url: string) => { - const [duration, setDuration] = useState(null); - - useEffect(() => { - if (!url) { - setDuration(null); - return; +export const useGetAudioDuration = (url: string) => { + const [duration, setDuration] = useState(null); + + useEffect(() => { + if (!url) { + setDuration(null); + return; + } + + const getDuration = (url: string, next: (duration: number) => void) => { + const _player = new Audio(url); + const durationChangeHandler = function ( + this: HTMLAudioElement, + e: Event + ) { + if (this.duration !== Infinity) { + const duration = this.duration; + _player.remove(); // Cleanup + next(duration); } + }; + + _player.addEventListener('durationchange', durationChangeHandler, false); + _player.load(); + _player.currentTime = 24 * 60 * 60; + _player.volume = 0; + }; + + getDuration(url, (duration: number) => { + setDuration(duration); + }); + + return () => { + const _player = new Audio(url); + _player.remove(); + }; + }, [url]); - const getDuration = (url: string, next: (duration: number) => void) => { - const _player = new Audio(url); - const durationChangeHandler = function (this: HTMLAudioElement, e: Event) { - if (this.duration !== Infinity) { - const duration = this.duration; - _player.remove(); // Cleanup - next(duration); - } - }; - - _player.addEventListener('durationchange', durationChangeHandler, false); - _player.load(); - _player.currentTime = 24 * 60 * 60; - _player.volume = 0; - }; - - getDuration(url, (duration: number) => { - setDuration(duration); - }); - - return () => { - const _player = new Audio(url); - _player.remove(); - }; - }, [url]); - - return duration; + return duration; }; export default useGetAudioDuration; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useReadReceipt/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useReadReceipt/index.tsx new file mode 100644 index 00000000..eb1695f7 --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useReadReceipt/index.tsx @@ -0,0 +1,14 @@ +import { useMutation } from '@tanstack/react-query'; +import { CachedConversation, useSendMessage } from '@xmtp/react-sdk'; +import { ContentTypeReadReceipt } from '@xmtp/content-type-read-receipt'; + +export const useReadReceipt = (conversation?: CachedConversation) => { + const { sendMessage } = useSendMessage(); + + return useMutation({ + mutationFn: () => { + if (!conversation) throw new Error('Conversation not found'); + return sendMessage(conversation, {}, ContentTypeReadReceipt); + }, + }); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useSendMessage/index.ts b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useSendMessage/index.ts index 4a89f1d9..c7866345 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/hooks/useSendMessage/index.ts +++ b/packages/@justweb3/xmtp-plugin/src/lib/hooks/useSendMessage/index.ts @@ -1,33 +1,33 @@ -import { useMutation } from '@tanstack/react-query' -import { ContentTypeId } from '@xmtp/content-type-primitives' +import { useMutation } from '@tanstack/react-query'; +import { ContentTypeId } from '@xmtp/content-type-primitives'; import { - CachedConversation, - useSendMessage, - DecodedMessage, - SendOptions, -} from '@xmtp/react-sdk' + CachedConversation, + DecodedMessage, + SendOptions, + useSendMessage, +} from '@xmtp/react-sdk'; -export const sendMessages = async ( +export const _sendMessages = async ( + conversation: CachedConversation, + message: string, + sendMessage: ( conversation: CachedConversation, - message: string, - sendMessage: ( - conversation: CachedConversation, - content: T, - contentType?: ContentTypeId, - sendOptions?: Omit, - ) => Promise | undefined>, - contentType?: SendOptions, + content: T, + contentType?: ContentTypeId, + sendOptions?: Omit + ) => Promise | undefined>, + contentType?: SendOptions ) => { - await sendMessage(conversation, message, undefined, contentType) -} + await sendMessage(conversation, message, undefined, contentType); +}; export const useSendMessages = (conversation?: CachedConversation) => { - const { sendMessage } = useSendMessage() + const { sendMessage } = useSendMessage(); - return useMutation({ - mutationFn: (message: string, contentType?: SendOptions) => { - if (!conversation) throw new Error('Conversation not found') - return sendMessages(conversation, message, sendMessage, contentType) - }, - }) -} + return useMutation({ + mutationFn: (message: string, contentType?: SendOptions) => { + if (!conversation) throw new Error('Conversation not found'); + return _sendMessages(conversation, message, sendMessage, contentType); + }, + }); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx index 63c919a9..90d1a0a3 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx @@ -1,7 +1,7 @@ import { JustaPlugin } from '@justweb3/widget'; import { JustWeb3XMTPProvider } from '../providers/JustWeb3XMTPProvider'; -import { ChatButton } from '../components/ChatButton'; -import { ChatWithProfileButton } from '../components/ChatWithProfileButton'; +import { ChatMenuButton } from '../components/ChatMenuButton'; +import { ProfileChatButton } from '../components/ProfileChatButton'; export type XmtpEnvironment = 'local' | 'production' | 'dev'; @@ -21,11 +21,11 @@ export const XMTPPlugin = (env: XmtpEnvironment): JustaPlugin => { ); }, ProfileHeader: (pluginApi, ens, chainId, address) => { - return ; + return ; }, SignInMenu: (pluginApi) => { return ( - pluginApi.setState('xmtpOpen', open)} env={env} /> diff --git a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx index 05d06fc5..1ee5a0a8 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx @@ -1,29 +1,42 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { attachmentContentTypeConfig, CachedConversation, + CachedMessage, Client, ClientOptions, + ContentTypeConfiguration, ContentTypeMetadata, reactionContentTypeConfig, replyContentTypeConfig, useClient, + useMessages, + useStreamMessages, XMTPProvider, } from '@xmtp/react-sdk'; -import { ChatSheet } from '../../components/ChatSheet'; +import { InboxSheet } from '../../components/InboxSheet'; import { useEthersSigner } from '../../hooks'; import { useMountedAccount } from '@justaname.id/react'; import { loadKeys, storeKeys, wipeKeys } from '../../utils/xmtp'; -import { AllMessageSheet } from '../../components/AllMessageSheet'; +import { readReceiptContentTypeConfig } from '../../content-types/readReceipt'; +import { ContentTypeReadReceipt } from '@xmtp/content-type-read-receipt'; +import { ChatSheet } from '../../components/ChatSheet'; -const contentTypeConfigs = [ +const contentTypeConfigs: ContentTypeConfiguration[] = [ attachmentContentTypeConfig, reactionContentTypeConfig, replyContentTypeConfig, + readReceiptContentTypeConfig, ]; interface JustWeb3XMTPContextProps { handleOpenChat: (address: string) => void; + conversationsInfo: { + conversationId: string; + unreadCount: number; + consent: 'allowed' | 'blocked' | 'requested'; + lastMessage: CachedMessage; + }[]; } const JustWeb3XMTPContext = React.createContext< @@ -46,6 +59,25 @@ export const JustWeb3XMTPProvider: React.FC = ({ const [isXmtpEnabled, setIsXmtpEnabled] = React.useState(false); const [conversation, setConversation] = React.useState | null>(null); + const [conversations, setConversations] = React.useState<{ + allowed: CachedConversation[]; + blocked: CachedConversation[]; + requested: CachedConversation[]; + }>({ + allowed: [], + blocked: [], + requested: [], + }); + const [conversationsInfo, setConversationsInfo] = React.useState< + { + conversationId: string; + unreadCount: number; + consent: 'allowed' | 'blocked' | 'requested'; + lastMessage: CachedMessage; + }[] + >([]); + + console.log(conversations); const handleXmtpEnabled = (enabled: boolean) => { setIsXmtpEnabled(enabled); }; @@ -61,24 +93,142 @@ export const JustWeb3XMTPProvider: React.FC = ({ } }; + const handleConversationInfo = ( + conversationId: string, + unreadCount: number, + lastMessage: CachedMessage, + consent: 'allowed' | 'blocked' | 'requested' + ) => { + setConversationsInfo((prev) => { + const index = prev.findIndex( + (item) => item.conversationId === conversationId + ); + if (index === -1) { + return [ + ...prev, + { + conversationId, + unreadCount, + lastMessage, + consent, + }, + ]; + } + prev[index].unreadCount = unreadCount; + prev[index].lastMessage = lastMessage; + return [...prev]; + }); + }; + + console.log('Conversations Info:', conversationsInfo); + return ( {isXmtpEnabled && ( - handleOpenChat('')} + allConversations={conversations} + onConversationsUpdated={setConversations} + conversationsInfo={conversationsInfo} /> )} - ( + item.conversationId === conversation.topic + )?.unreadCount + } + lastMessage={ + conversationsInfo.find( + (item) => item.conversationId === conversation.topic + )?.lastMessage + } + handleConversationInfo={( + conversationId, + unreadCount, + lastMessage + ) => + handleConversationInfo( + conversationId, + unreadCount, + lastMessage, + 'allowed' + ) + } + /> + ))} + {conversations.blocked.map((conversation) => ( + item.conversationId === conversation.topic + )?.unreadCount + } + lastMessage={ + conversationsInfo.find( + (item) => item.conversationId === conversation.topic + )?.lastMessage + } + handleConversationInfo={( + conversationId, + unreadCount, + lastMessage + ) => + handleConversationInfo( + conversationId, + unreadCount, + lastMessage, + 'blocked' + ) + } + /> + ))} + {conversations.requested.map((conversation) => ( + item.conversationId === conversation.topic + )?.unreadCount + } + lastMessage={ + conversationsInfo.find( + (item) => item.conversationId === conversation.topic + )?.lastMessage + } + handleConversationInfo={( + conversationId, + unreadCount, + lastMessage + ) => + handleConversationInfo( + conversationId, + unreadCount, + lastMessage, + 'requested' + ) + } + /> + ))} + + { setPeerAddress(null); @@ -99,16 +249,122 @@ interface ChecksProps { env: 'local' | 'production' | 'dev'; } +interface GetConversationInfoProps { + conversation: CachedConversation; + handleConversationInfo: ( + conversationId: string, + unreadCount: number, + lastMessage: CachedMessage + ) => void; + unreadCount?: number; + lastMessage?: CachedMessage; +} + +export const GetConversationInfo: React.FC = ({ + conversation, + handleConversationInfo, + unreadCount, + lastMessage, +}) => { + const { messages } = useMessages(conversation); + + useStreamMessages(conversation); + const _unreadCount = useMemo(() => { + let count = 0; + const _messages = [...messages].reverse(); + for (const message of _messages) { + if (message.contentType === ContentTypeReadReceipt.toString()) { + break; + } + + count++; + } + + return count; + }, [messages]); + + const _lastMessage = useMemo(() => { + const _messages = [...messages]; + let lastMessage = _messages[_messages.length - 1]; + if (lastMessage?.contentType === ContentTypeReadReceipt.toString()) { + lastMessage = _messages[_messages.length - 2]; + } + + console.log('Last Message:', lastMessage); + return lastMessage; + }, [messages]); + + useEffect(() => { + if (unreadCount === _unreadCount && _lastMessage?.id === lastMessage?.id) { + return; + } + + console.log( + 'Updating Conversation Info:', + conversation.topic, + _unreadCount, + _lastMessage + ); + handleConversationInfo(conversation.topic, _unreadCount, _lastMessage); + }, [ + conversation.topic, + handleConversationInfo, + _unreadCount, + unreadCount, + _lastMessage, + lastMessage?.id, + ]); + + return null; +}; + export const Checks: React.FC = ({ open, handleXmtpEnabled, env, }) => { - const { client, initialize, isLoading } = useClient(); + const { client, initialize, isLoading, disconnect } = useClient(); const signer = useEthersSigner(); const { address } = useMountedAccount(); const [isInitializing, setIsInitializing] = React.useState(false); const [rejected, setRejected] = React.useState(false); + + useEffect(() => { + async function reinitializeXmtp() { + if (client && address) { + if (client?.address?.toLowerCase() !== address.toLowerCase()) { + await disconnect(); + + if (!signer) { + return; + } + setIsInitializing(true); + const clientOptions: Partial> = { + appVersion: 'JustWeb3/1.0.0/' + env + '/0', + env: env, + }; + let keys = loadKeys(address ?? '', env); + console.log('Keys:', keys); + if (!keys) { + keys = await Client.getKeys(signer, { + env: env, + skipContactPublishing: false, + // persistConversations: false, + }); + storeKeys(address ?? '', keys, env); + } + + await initialize({ + keys, + options: clientOptions, + signer: signer, + }); + } + } + } + reinitializeXmtp(); + }, [client, address, signer, env, initialize, disconnect]); + useEffect(() => { async function initializeXmtp() { if (isInitializing || isLoading || rejected) return; @@ -134,11 +390,14 @@ export const Checks: React.FC = ({ }); storeKeys(address ?? '', keys, env); } + await initialize({ keys, options: clientOptions, signer: signer, }); + + // _client?.registerCodec(new ReadReceiptCodec()); setIsInitializing(false); } catch (error) { console.error('Failed to initialize XMTP Client:', error); @@ -164,12 +423,6 @@ export const Checks: React.FC = ({ handleXmtpEnabled(!!client); }, [client, handleXmtpEnabled]); - // useEffect(() => { - // if (!address) { - // disconnect(); - // } - // }, [connectedEns?.ens, disconnect]); - return null; }; From 4a3af5ec741d4e6938b1311bd2fd8303c7e86875 Mon Sep 17 00:00:00 2001 From: HadiKhai Date: Mon, 9 Dec 2024 09:48:20 +0200 Subject: [PATCH 29/29] feat: chat optimization --- .gitignore | 4 +- apps/console/next.config.js | 5 +- package.json | 1 + .../lib/hooks/client/useEnsPublicClient.ts | 2 +- .../lib/hooks/primaryName/usePrimaryName.ts | 30 +- .../react/src/lib/hooks/records/useRecords.ts | 6 +- .../src/lib/providers/JustaNameProvider.tsx | 4 +- .../sdk/src/lib/api/axiosController.ts | 1 - .../src/lib/components/FollowButton/index.tsx | 3 + .../NotificationBadge.module.css | 3 +- .../ui/src/lib/ui/Tabs/Tabs.module.css | 3 + .../JustEnsCard/JustEnsCard.module.css | 5 + .../src/lib/components/JustEnsCard/index.tsx | 3 +- .../lib/components/JustWeb3Button/index.tsx | 29 + .../Profile/ContentSection/index.tsx | 5 +- .../src/lib/dialogs/SignInDialog/index.tsx | 1 + .../@justweb3/widget/src/lib/plugins/index.ts | 1 + .../lib/providers/JustWeb3Provider/index.tsx | 16 + .../@justweb3/xmtp-plugin/.storybook/main.ts | 11 +- .../xmtp-plugin/.storybook/preview.tsx | 14 +- .../ChatMessagesList/MessageCard/index.tsx | 1 - .../ChatSheet/Chat/ChatMessagesList/index.tsx | 31 +- .../Chat/ChatReactionOverlay/index.tsx | 2 +- .../Chat/ChatTextField/MessageInput/index.tsx | 1 + .../lib/components/ChatSheet/Chat/index.tsx | 46 +- .../InboxSheet/ChatList/MessageItem/index.tsx | 51 +- .../components/InboxSheet/ChatList/index.tsx | 66 +- .../src/lib/components/InboxSheet/index.tsx | 358 ++++--- .../components/JustWeb3ButtonRight/index.tsx | 84 ++ .../components/ProfileChatButton/index.tsx | 6 + .../src/lib/content-types/readReceipt.ts | 2 + .../src/lib/icons/ChatIcon/index.tsx | 17 + .../xmtp-plugin/src/lib/plugins/index.tsx | 18 +- .../providers/JustWeb3XMTPProvider/index.tsx | 86 +- .../xmtp-plugin/src/stories/xmtp.stories.tsx | 99 +- yarn.lock | 946 +++++++++++++++++- 36 files changed, 1597 insertions(+), 364 deletions(-) create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/components/JustWeb3ButtonRight/index.tsx create mode 100644 packages/@justweb3/xmtp-plugin/src/lib/icons/ChatIcon/index.tsx diff --git a/.gitignore b/.gitignore index 0c426e1a..1af11c4b 100644 --- a/.gitignore +++ b/.gitignore @@ -62,4 +62,6 @@ cache/ .yarn/install-state.gz -storybook-static \ No newline at end of file +storybook-static + +.million \ No newline at end of file diff --git a/apps/console/next.config.js b/apps/console/next.config.js index 55fe2990..a4720cf2 100644 --- a/apps/console/next.config.js +++ b/apps/console/next.config.js @@ -2,6 +2,7 @@ // eslint-disable-next-line @typescript-eslint/no-var-requires const { composePlugins, withNx } = require('@nx/next'); +const MillionLint = require('@million/lint'); /** * @type {import('@nx/next/plugins/with-nx').WithNxOptions} @@ -23,4 +24,6 @@ const plugins = [ withNx, ]; -module.exports = composePlugins(...plugins)(nextConfig); +module.exports = MillionLint.next({ rsc: true })( + composePlugins(...plugins)(nextConfig) +); diff --git a/package.json b/package.json index 8e77fd0f..e3ed50e1 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@hookform/resolvers": "^3.9.0", "@inquirer/prompts": "^4.3.0", "@justaname.id/address-resolution": "^1.1.0", + "@million/lint": "^1.0.13", "@privy-io/react-auth": "^1.82.0", "@privy-io/wagmi": "^0.2.12", "@radix-ui/react-accordion": "^1.2.1", diff --git a/packages/@justaname.id/react/src/lib/hooks/client/useEnsPublicClient.ts b/packages/@justaname.id/react/src/lib/hooks/client/useEnsPublicClient.ts index 039c6fb5..288087d2 100644 --- a/packages/@justaname.id/react/src/lib/hooks/client/useEnsPublicClient.ts +++ b/packages/@justaname.id/react/src/lib/hooks/client/useEnsPublicClient.ts @@ -22,7 +22,7 @@ export const getEnsPublicClient = ( }; export const buildEnsPublicClientKey = (chainId: ChainId | undefined) => [ - 'CLIENT', + 'ENS_PUBLIC_CLIENT', chainId, ]; diff --git a/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts b/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts index 594082b5..2c704966 100644 --- a/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts +++ b/packages/@justaname.id/react/src/lib/hooks/primaryName/usePrimaryName.ts @@ -6,6 +6,7 @@ import { useEnsPublicClient } from '../client/useEnsPublicClient'; import { defaultOptions } from '../../query'; import { getName } from '@ensdomains/ensjs/public'; import { PrimaryNameTaskQueue } from './primary-name-task-queue'; +import { buildPrimaryNameBatchKey } from './usePrimaryNameBatch'; export const buildPrimaryName = ( address: string, @@ -59,6 +60,16 @@ export const usePrimaryName = ( let name = ''; + const primaryNames = queryClient.getQueryData( + buildPrimaryNameBatchKey(_chainId) + ) as Record; + + if (primaryNames && _params?.address) { + if (primaryNames[_params?.address]) { + return primaryNames[_params.address]; + } + } + const primaryNameGetByAddressResponse = await justaname.subnames.getPrimaryNameByAddress({ address: params?.address, @@ -82,25 +93,6 @@ export const usePrimaryName = ( name = reverseResolution.name; } } - - // const reverseResolution = await getName(ensClient, { - // address: params?.address, - // }); - // - // if (reverseResolution && reverseResolution?.name) { - // name = reverseResolution.name; - // } else { - // const primaryNameGetByAddressResponse = - // await justaname.subnames.getPrimaryNameByAddress({ - // address: params?.address, - // chainId: _chainId, - // }); - // - // if (primaryNameGetByAddressResponse) { - // name = primaryNameGetByAddressResponse.name; - // } - // } - // return name; }; diff --git a/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts b/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts index 2feb6b87..51b421de 100644 --- a/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts +++ b/packages/@justaname.id/react/src/lib/hooks/records/useRecords.ts @@ -260,11 +260,7 @@ export const useRecords = (params?: UseRecordsParams): UseRecordsResult => { } return failureCount < 3; }, - queryKey: buildRecordsBySubnameKey( - _ens || '', - _chainId - // params?.standard - ), + queryKey: buildRecordsBySubnameKey(_ens || '', _chainId), queryFn: () => getRecordsInternal( { diff --git a/packages/@justaname.id/react/src/lib/providers/JustaNameProvider.tsx b/packages/@justaname.id/react/src/lib/providers/JustaNameProvider.tsx index 2b49b9cb..b3a690a3 100644 --- a/packages/@justaname.id/react/src/lib/providers/JustaNameProvider.tsx +++ b/packages/@justaname.id/react/src/lib/providers/JustaNameProvider.tsx @@ -68,8 +68,8 @@ export const JustaNameProvider: FC = ({ const { chainId } = useMountedAccount(); const defaultChain = useMemo(() => { - return !chainId - ? undefined + return !chainId === undefined + ? 1 : chainId !== 1 && chainId !== 11155111 ? 1 : chainId; diff --git a/packages/@justaname.id/sdk/src/lib/api/axiosController.ts b/packages/@justaname.id/sdk/src/lib/api/axiosController.ts index 9a2dad0b..4e84ddc5 100644 --- a/packages/@justaname.id/sdk/src/lib/api/axiosController.ts +++ b/packages/@justaname.id/sdk/src/lib/api/axiosController.ts @@ -42,7 +42,6 @@ export const controlledAxiosPromise = >( return res.data.result.data as T; }) .catch((err: AxiosError>) => { - console.error(err); if (err?.response) { if (err?.response?.data?.result) { if (err?.response?.data?.result?.error) { diff --git a/packages/@justweb3/efp-plugin/src/lib/components/FollowButton/index.tsx b/packages/@justweb3/efp-plugin/src/lib/components/FollowButton/index.tsx index e334e222..3206dd24 100644 --- a/packages/@justweb3/efp-plugin/src/lib/components/FollowButton/index.tsx +++ b/packages/@justweb3/efp-plugin/src/lib/components/FollowButton/index.tsx @@ -15,6 +15,9 @@ export const FollowButton: React.FC = ({ ens, address }) => { addressOrEns1: address, addressOrEns2: ownAddress, }); + if (ownAddress === address) { + return null; + } if (!ownAddress) { return ( diff --git a/packages/@justweb3/ui/src/lib/ui/NotificationBadge/NotificationBadge.module.css b/packages/@justweb3/ui/src/lib/ui/NotificationBadge/NotificationBadge.module.css index d5c0f5a4..f0b5f0f9 100644 --- a/packages/@justweb3/ui/src/lib/ui/NotificationBadge/NotificationBadge.module.css +++ b/packages/@justweb3/ui/src/lib/ui/NotificationBadge/NotificationBadge.module.css @@ -1,7 +1,6 @@ .notificationIcon { position: relative; - display: inline-block; - + display: flex; } .icon { diff --git a/packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css b/packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css index dac10440..5510c3f7 100644 --- a/packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css +++ b/packages/@justweb3/ui/src/lib/ui/Tabs/Tabs.module.css @@ -6,6 +6,8 @@ margin-bottom: 10px; gap: 10px; display: flex; + overflow-x: auto; + overflow-y: visible; } /* Underlined variant */ @@ -22,6 +24,7 @@ font-family: var(--justweb3-font-family); border-bottom: 2px solid transparent; + } .underlinedTabs .tabsTrigger[data-state='active'] { diff --git a/packages/@justweb3/widget/src/lib/components/JustEnsCard/JustEnsCard.module.css b/packages/@justweb3/widget/src/lib/components/JustEnsCard/JustEnsCard.module.css index 11751fc2..3b130351 100644 --- a/packages/@justweb3/widget/src/lib/components/JustEnsCard/JustEnsCard.module.css +++ b/packages/@justweb3/widget/src/lib/components/JustEnsCard/JustEnsCard.module.css @@ -70,3 +70,8 @@ display: flex; gap: 5px; } + +.socialIcon { + width: 12px; + height: 12px; +} diff --git a/packages/@justweb3/widget/src/lib/components/JustEnsCard/index.tsx b/packages/@justweb3/widget/src/lib/components/JustEnsCard/index.tsx index 515471f2..5b24a65d 100644 --- a/packages/@justweb3/widget/src/lib/components/JustEnsCard/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/JustEnsCard/index.tsx @@ -214,8 +214,7 @@ export const JustEnsCard: FC = ({ {records.sanitizedRecords.socials.map((social, index) => React.cloneElement(getTextRecordIcon(social.key), { key: `${ens}-${index}-${social.key}`, - width: 12, - height: 12, + className: styles.socialIcon, }) )} diff --git a/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx b/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx index 2c10fd20..2b53c6b3 100644 --- a/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/JustWeb3Button/index.tsx @@ -162,6 +162,24 @@ export const JustWeb3Button: FC = ({ } const connectedEnsBtn = (withDialog: boolean) => { + const right = plugins.map((plugin) => { + const component = plugin.components?.JustWeb3ButtonRight; + if (!component) { + return null; + } + + return ( +
{ + setMobileDialogOpen(false); + }} + > + {component(createPluginApi(plugin.name))} +
+ ); + }); + return ( = ({ color: 'var(--justweb3-primary-color)', ...style, }} + right={ +
+ {right} +
+ } contentStyle={{ alignItems: 'start', }} diff --git a/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx b/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx index de020496..97d576b5 100644 --- a/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx +++ b/packages/@justweb3/widget/src/lib/components/Profile/ContentSection/index.tsx @@ -51,6 +51,9 @@ export interface ContentProps { plugins: JustaPlugin[]; } +const ENS_MAINNET_RESOLVER = '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41'; +const ENS_SEPOLIA_RESOLVER = '0x8FADE66B79cC9f707aB26799354482EB93a5B7dD'; + const ContentSection: React.FC = ({ fullSubname = '', chainId = 1, @@ -65,7 +68,7 @@ const ContentSection: React.FC = ({ const { accountEnsNames } = useAccountEnsNames(); const [tab, setTab] = React.useState('Main'); const { openEnsProfile } = useJustWeb3(); - + // const { offchainResolvers } = useOffchainResolvers() const isProfileSelf = useMemo(() => { const tempEns = accountEnsNames ?.map((ens) => ens.ens) diff --git a/packages/@justweb3/widget/src/lib/dialogs/SignInDialog/index.tsx b/packages/@justweb3/widget/src/lib/dialogs/SignInDialog/index.tsx index eeb51db4..0bad3cb3 100644 --- a/packages/@justweb3/widget/src/lib/dialogs/SignInDialog/index.tsx +++ b/packages/@justweb3/widget/src/lib/dialogs/SignInDialog/index.tsx @@ -30,6 +30,7 @@ import styles from './SignInDialog.module.css'; import clsx from 'clsx'; const ENS_MAINNET_RESOLVER = '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41'; +// const BASE_MAINNET_RESOLVER = '0xde9049636F4a1dfE0a64d1bFe3155C0A14C54F31' const ENS_SEPOLIA_RESOLVER = '0x8FADE66B79cC9f707aB26799354482EB93a5B7dD'; interface TransitionElementProps extends React.HTMLAttributes { diff --git a/packages/@justweb3/widget/src/lib/plugins/index.ts b/packages/@justweb3/widget/src/lib/plugins/index.ts index 6337ffd3..5ba874b9 100644 --- a/packages/@justweb3/widget/src/lib/plugins/index.ts +++ b/packages/@justweb3/widget/src/lib/plugins/index.ts @@ -50,6 +50,7 @@ interface PluginComponents { Provider?: PluginProviderComponent; Global?: PluginComponent; SignInMenu?: PluginComponent; + JustWeb3ButtonRight?: PluginComponent; ProfileSection?: PluginRichComponent; ProfileHeader?: PluginRichComponent; ProfileTab?: ProfileTabPluginComponent; diff --git a/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx b/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx index 90058cf0..5e3bf1ad 100644 --- a/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx +++ b/packages/@justweb3/widget/src/lib/providers/JustWeb3Provider/index.tsx @@ -403,6 +403,22 @@ const CheckSession: FC<{ ); const isConnectedPrevious = usePreviousState(isConnected, [isConnected]); + useEffect(() => { + if (isConnecting || isReconnecting || isEnsAuthPending) { + return; + } + + const timeout = setTimeout(() => { + if (!isConnected) { + signOut(); + } + }, 1000); + + return () => { + clearTimeout(timeout); + }; + }, [isConnected, isConnecting, isEnsAuthPending, isReconnecting, signOut]); + useEffect(() => { if (connectedEns && chainId) { if ( diff --git a/packages/@justweb3/xmtp-plugin/.storybook/main.ts b/packages/@justweb3/xmtp-plugin/.storybook/main.ts index 3e575653..73c1c0cc 100644 --- a/packages/@justweb3/xmtp-plugin/.storybook/main.ts +++ b/packages/@justweb3/xmtp-plugin/.storybook/main.ts @@ -13,7 +13,16 @@ const config: StorybookConfig = { viteFinal: async (config) => mergeConfig(config, { - plugins: [react(), nxViteTsPaths()], + plugins: [ + react(), + nxViteTsPaths(), + // MillionLint.vite({ + // filter: { + // // I want a regex to exclude all the react tsx components with Icon at the end + // exclude: /Icon$/, + // }, + // }), + ], define: { 'process.env': process.env, }, diff --git a/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx b/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx index 0b60c255..297516f8 100644 --- a/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx +++ b/packages/@justweb3/xmtp-plugin/.storybook/preview.tsx @@ -1,11 +1,11 @@ import './polyfills'; -import { scan } from 'react-scan'; +// import { scan } from 'react-scan'; -if (typeof window !== 'undefined') { - scan({ - enabled: true, - log: true, // logs render info to console (default: false) - }); -} +// if (typeof window !== 'undefined') { +// scan({ +// enabled: true, +// log: true, // logs render info to console (default: false) +// }); +// } export const decorators = [(Story) => ]; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/MessageCard/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/MessageCard/index.tsx index 8ad5ce6c..ae0491c4 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/MessageCard/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/MessageCard/index.tsx @@ -243,7 +243,6 @@ export const MessageCard: React.FC = ({ overflowWrap: 'break-word', maxWidth: !isImage ? '240px' : 'none', fontSize: '14px', - lineHeight: '14px', padding: isReply ? '4px' : '5px', borderRadius: '14px', backgroundColor: isReceiver diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/index.tsx index ebbdee51..2aad68e1 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/ChatMessagesList/index.tsx @@ -4,6 +4,7 @@ import { DateDivider } from './DateDivider'; import { EmojiSelector } from './EmojiSelector'; import { MessageCard } from './MessageCard'; import { MessageWithReaction } from '../../../../utils/filterReactionsMessages'; +import { useEffect, useState } from 'react'; interface ChatMessagesListProps { canMessage: boolean; @@ -26,6 +27,19 @@ export const ChatMessagesList: React.FC = ({ handleEmojiSelect, computeHeight, }) => { + const [ref, setRef] = useState(null); + useEffect(() => { + if (ref) { + setTimeout(() => { + const lastGroupChild = ref.lastElementChild as HTMLElement; + + const lastMessage = lastGroupChild?.lastElementChild as HTMLElement; + + lastMessage?.scrollIntoView({ behavior: 'smooth' }); + }, 500); + } + }, [groupedMessages, ref]); + if (!canMessage) { return ( = ({ return ( setRef(el)} > {groupedMessages && Object.keys(groupedMessages).map((date, index) => ( - + {groupedMessages[date].map((message) => ( = ({ borderTopRightRadius: replyMessage ? 0 : '100px', borderTop: replyMessage ? '0px' : '', }} + autoFocus placeholder="Send message..." value={messageValue} left={ diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/index.tsx index de637057..688c55de 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ChatSheet/Chat/index.tsx @@ -11,7 +11,6 @@ import { useCanMessage, useConsent, useMessages, - useStreamMessages, } from '@xmtp/react-sdk'; import { useJustWeb3 } from '@justweb3/widget'; import { ChatTextField } from './ChatTextField'; @@ -46,7 +45,7 @@ export const Chat: React.FC = ({ conversation, onBack }) => { const [isRequestChangeLoading, setIsRequestChangeLoading] = useState(false); - const { entries, allow, refreshConsentList, deny } = useConsent(); + const { entries, allow, deny } = useConsent(); const { mutateAsync: sendReaction } = useSendReactionMessage(conversation); const { primaryName } = usePrimaryName({ address: conversation.peerAddress as `0x${string}`, @@ -59,7 +58,6 @@ export const Chat: React.FC = ({ conversation, onBack }) => { useCanMessage(); const { mutateAsync: readReceipt, isPending: isReadReceiptSending } = useReadReceipt(conversation); - useStreamMessages(conversation); useEffect(() => { const lastMessage = messages[messages.length - 1]; @@ -70,8 +68,16 @@ export const Chat: React.FC = ({ conversation, onBack }) => { return; } - readReceipt(); - }, [messages, readReceipt, isReadReceiptSending]); + if (entries[conversation.peerAddress]?.permissionType === 'allowed') { + readReceipt(); + } + }, [ + messages, + readReceipt, + isReadReceiptSending, + entries, + conversation.peerAddress, + ]); // Determine if user can message useEffect(() => { @@ -87,19 +93,6 @@ export const Chat: React.FC = ({ conversation, onBack }) => { ); }, [entries, conversation.peerAddress]); - // Scroll to last message when messages change - useEffect(() => { - if (messages.length === 0) return; - setTimeout(() => { - const lastMessageId = messages[messages.length - 1]?.id; - const element = document.getElementById(lastMessageId); - if (element) { - element.scrollIntoView({ behavior: 'smooth' }); - } - }, 500); - }, [messages, conversation]); - - // Filter out read receipts and group messages by date const filteredMessages = useMemo(() => { const withoutRead = messages.filter( (message) => message.contentType !== 'xmtp.org/readReceipt:1.0' @@ -125,10 +118,10 @@ export const Chat: React.FC = ({ conversation, onBack }) => { const type = mimeType ? typeLookup[mimeType.split('/')?.[1]] : null; const computeHeight = useMemo(() => { - const baseHeight = 'calc(100vh - 50px - 3rem - 1.5rem - 73px - 15px)'; + const baseHeight = '100vh - 50px - 3rem - 1.5rem - 73px - 15px'; const adjustments: string[] = []; - if (isRequest) adjustments.push('40px'); + if (isRequest) return 'calc(100vh - 50px - 3rem - 1.5rem - 15px - 34px)'; if (replyMessage) { if (isStringContent) { adjustments.push('46px'); @@ -142,8 +135,9 @@ export const Chat: React.FC = ({ conversation, onBack }) => { } if (isMessagesSenderOnly) adjustments.push('59px'); - if (adjustments.length === 0) return baseHeight; - return `${baseHeight}${adjustments.map((val) => ` - ${val}`).join('')}`; + return ` calc(${baseHeight}${adjustments + .map((val) => ` - ${val}`) + .join('')}) `; }, [ replyMessage, isMessagesSenderOnly, @@ -156,18 +150,18 @@ export const Chat: React.FC = ({ conversation, onBack }) => { // Handlers const blockAddressHandler = async (peerAddress: string) => { setIsRequestChangeLoading(true); - await refreshConsentList(); + // await refreshConsentList(); await deny([peerAddress]); - await refreshConsentList(); + // await refreshConsentList(); setIsRequestChangeLoading(false); onBack(); }; const handleAllowAddress = async () => { setIsRequestChangeLoading(true); - await refreshConsentList(); + // await refreshConsentList(); await allow([conversation.peerAddress]); - await refreshConsentList(); + // await refreshConsentList(); setIsRequest(false); setIsRequestChangeLoading(false); }; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/ChatList/MessageItem/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/ChatList/MessageItem/index.tsx index a994b787..f3640899 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/ChatList/MessageItem/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/ChatList/MessageItem/index.tsx @@ -6,7 +6,6 @@ import { reactionContentTypeConfig, replyContentTypeConfig, useConsent, - useStreamMessages, } from '@xmtp/react-sdk'; import { useEnsAvatar, useRecords } from '@justaname.id/react'; import { Avatar, Button, Flex, formatText, P, SPAN } from '@justweb3/ui'; @@ -33,8 +32,6 @@ const MessageItem: React.FC = ({ primaryName, conversationInfo, }) => { - useStreamMessages(conversation); - // const { messages } = useMessages(conversation); const { records } = useRecords({ ens: primaryName || undefined, }); @@ -45,15 +42,15 @@ const MessageItem: React.FC = ({ // return lastMessage.contentType !== ContentTypeReadReceipt.toString(); // }, [lastMessage]); - const { allow, refreshConsentList } = useConsent(); + const { allow, deny } = useConsent(); const allowUser = async () => { - await refreshConsentList(); await allow([conversation.peerAddress]); - await refreshConsentList(); }; - console.log('conversationInfo', conversationInfo); + const ignoreUser = async () => { + await deny([conversation.peerAddress]); + }; const lastContent = useMemo(() => { const lastMessage = conversationInfo?.lastMessage; @@ -80,14 +77,12 @@ const MessageItem: React.FC = ({ if ( replyContentTypeConfig.contentTypes.includes(lastMessage?.contentType) ) { - return lastMessage.contentFallback; + return 'replied "' + lastMessage.content.content + '"'; } return lastMessage.contentFallback; }, [conversationInfo, conversationInfo?.lastMessage]); - console.log(lastContent); - return ( = ({ direction={'column'} style={{ marginLeft: '10px', - maxWidth: blocked - ? 'calc(100% - 120px)' - : 'calc(100% - 50px - 32px - 10px)', + maxWidth: + conversationInfo?.consent === 'requested' + ? 'calc(100% - 132px - 44px)' + : conversationInfo?.consent === 'blocked' + ? 'calc(100% - 120px)' + : 'calc(100% - 50px - 32px - 10px)', justifyContent: 'space-between', }} > @@ -158,10 +156,29 @@ const MessageItem: React.FC = ({ textAlign: 'end', }} > - {blocked ? ( - + {conversationInfo?.consent !== 'allowed' ? ( + + + {conversationInfo?.consent === 'requested' && ( + + )} + ) : (
[]; @@ -14,6 +14,7 @@ export interface ChatListProps { conversation: CachedConversation ) => void; blockedList?: boolean; + primaryNames: PrimaryNameRecord | undefined; conversationsInfo?: { conversationId: string; unreadCount: number; @@ -27,37 +28,50 @@ export const ChatList: React.FC = ({ handleOpenChat, blockedList, conversationsInfo, + primaryNames, }) => { - const { allPrimaryNames } = usePrimaryNameBatch({ - addresses: conversations.map((conversation) => conversation.peerAddress), - }); - return ( - {conversations.map((conversation) => ( - item.conversationId === conversation.topic - // )?.unreadCount - // } - // - conversationInfo={conversationsInfo?.find( - (item) => item.conversationId === conversation.topic - )} - onClick={() => handleOpenChat(conversation)} - key={conversation.topic} - blocked={blockedList} - /> - ))} + {conversationsInfo + ?.sort((a, b) => { + if (a.lastMessage?.sentAt && b.lastMessage?.sentAt) { + // a.lastMessage.sentAt and b.lastMessage.sentA are Date objects + return ( + b.lastMessage.sentAt.getTime() - a.lastMessage.sentAt.getTime() + ); + } + return 0; + }) + .map((conv) => { + const conversation = conversations.find( + (item) => item.topic === conv.conversationId + ); + + if (!conversation) return null; + + return ( + item.conversationId === conversation.topic + // )?.unreadCount + // } + // + conversationInfo={conv} + onClick={() => handleOpenChat(conversation)} + key={conversation.topic} + blocked={blockedList} + /> + ); + })} ); }; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/index.tsx index c4496252..a8cdbf43 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/InboxSheet/index.tsx @@ -4,6 +4,7 @@ import { Sheet, SheetContent, SheetTitle, + SPAN, Tabs, TabsContent, TabsList, @@ -13,13 +14,18 @@ import { CachedConversation, CachedMessage, ContentTypeMetadata, + Conversation, + useClient, useConsent, useConversations, useStreamAllMessages, + useStreamConsentList, useStreamConversations, } from '@xmtp/react-sdk'; import React, { useEffect, useMemo } from 'react'; import { ChatList } from './ChatList'; +import { useMountedAccount, usePrimaryNameBatch } from '@justaname.id/react'; +import { isEqual } from 'lodash'; export interface InboxSheetProps { open?: boolean; @@ -60,10 +66,43 @@ export const InboxSheet: React.FC = ({ conversationsInfo, }) => { const [tab, setTab] = React.useState('Chats'); - const { conversations, isLoading } = useConversations(); - + const { conversations: cachedConversations, isLoading } = useConversations(); + const { address } = useMountedAccount(); + const conversations = useMemo(() => { + return cachedConversations.filter((convo) => convo.peerAddress !== address); + }, [cachedConversations, address]); const [isConsentListLoading, setIsConsentListLoading] = React.useState(true); - const { loadConsentList, entries } = useConsent(); + const { entries, loadConsentList } = useConsent(); + const { client } = useClient(); + + const [initialConversations, setInitialConversations] = React.useState< + Conversation[] | null + >(null); + useEffect(() => { + if (!client) return; + + const fetchConversations = async () => { + const _conversations = await client.conversations.list(); + setInitialConversations(_conversations); + }; + fetchConversations(); + }, [client]); + + const primaryNameConversations = useMemo(() => { + if (!initialConversations) return; + if (conversations?.length > initialConversations?.length) { + return conversations; + } + + return initialConversations; + }, [conversations, initialConversations]); + const { allPrimaryNames } = usePrimaryNameBatch({ + addresses: primaryNameConversations?.map( + (conversation) => conversation.peerAddress + ), + + enabled: initialConversations !== null, + }); const allowedConversations = useMemo(() => { return conversations.filter( @@ -91,56 +130,39 @@ export const InboxSheet: React.FC = ({ }, [conversations, entries]); useEffect(() => { - let _allowedConversations = [] as CachedConversation[]; - let _blockedConversations = [] as CachedConversation[]; - let _requestConversations = [] as CachedConversation[]; + const allowedConversationsTopic = allowedConversations.map( + (convo) => convo.topic + ); - if ( - allowedConversations.some( - (convo) => - !allConversations.allowed.some((c) => c.topic === convo.topic) - ) - ) { - _allowedConversations = allowedConversations.filter( - (convo) => - !allConversations.allowed.some((c) => c.topic === convo.topic) - ); - // onConversationsUpdated([...allConversations, ...newConversations]); - } + const blockedConversationsTopic = blockedConversations.map( + (convo) => convo.topic + ); - if ( - blockedConversations.some( - (convo) => - !allConversations.blocked.some((c) => c.topic === convo.topic) - ) - ) { - _blockedConversations = blockedConversations.filter( - (convo) => - !allConversations.blocked.some((c) => c.topic === convo.topic) - ); - } + const requestConversationsTopic = requestConversations.map( + (convo) => convo.topic + ); - if ( - requestConversations.some( - (convo) => - !allConversations.requested.some((c) => c.topic === convo.topic) - ) - ) { - _requestConversations = requestConversations.filter( - (convo) => - !allConversations.requested.some((c) => c.topic === convo.topic) - ); - } + const allConversationsAllowedTopic = allConversations.allowed.map( + (convo) => convo.topic + ); + + const allConversationsBlockedTopic = allConversations.blocked.map( + (convo) => convo.topic + ); + + const allConversationsRequestedTopic = allConversations.requested.map( + (convo) => convo.topic + ); if ( - _allowedConversations.length > 0 || - _blockedConversations.length > 0 || - _requestConversations.length > 0 + !isEqual(allowedConversationsTopic, allConversationsAllowedTopic) || + !isEqual(blockedConversationsTopic, allConversationsBlockedTopic) || + !isEqual(requestConversationsTopic, allConversationsRequestedTopic) ) { onConversationsUpdated({ - allowed: [...allConversations.allowed, ..._allowedConversations], - blocked: [...allConversations.blocked, ..._blockedConversations], - requested: [...allConversations.requested, ..._requestConversations], + allowed: allowedConversations, + blocked: blockedConversations, + requested: requestConversations, }); } }, [ @@ -152,13 +174,15 @@ export const InboxSheet: React.FC = ({ ]); useEffect(() => { + if (!isConsentListLoading) return; loadConsentList().then(() => { setIsConsentListLoading(false); }); - }, [loadConsentList]); + }, [loadConsentList, isConsentListLoading]); useStreamConversations(); useStreamAllMessages(); + useStreamConsentList(); return ( @@ -171,7 +195,7 @@ export const InboxSheet: React.FC = ({ width: 45, height: 45, borderRadius: '50%', - backgroundColor: 'var(--justweb3-primary-color', + backgroundColor: 'var(--justweb3-primary-color)', cursor: 'pointer', position: 'absolute', bottom: '2rem', @@ -186,88 +210,172 @@ export const InboxSheet: React.FC = ({ height={35} /> - setTab(value)} - style={{ - display: 'flex', - flexDirection: 'column', - marginBottom: '0px', - overflow: 'hidden', - marginTop: '10px', - flex: '1', - }} - > - - - Chats - - + setTab(value)} + style={{ + display: 'flex', + flexDirection: 'column', + marginBottom: '0px', + // overflow: 'hidden', + maxHeight: 'calc(100vh - 72px - 10px - 28px - 10px)', + minHeight: 'calc(100vh - 72px - 10px - 28px - 10px)', + marginTop: '10px', + flex: '1', + }} + > + + + Chats + + + Requests + {requestConversations.length > 0 && ( +
+ + {requestConversations.length} + +
+ )} +
+ + Blocked + +
+ {isLoading || isConsentListLoading ? ( + // {true ? ( +
+ + Loading... + +
+ ) : ( + <> + + + + + + + + + + + )} +
+ + + - Requests - {requestConversations.length > 0 && ( - - {requestConversations.length} - - )} -
- + - Blocked - -
- {isLoading || isConsentListLoading ? ( -
Loading...
- ) : ( - <> - - + + - - - - - - - - - )} -
+ + + + + + + + + +
); diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/JustWeb3ButtonRight/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/JustWeb3ButtonRight/index.tsx new file mode 100644 index 00000000..5358282e --- /dev/null +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/JustWeb3ButtonRight/index.tsx @@ -0,0 +1,84 @@ +import { XmtpEnvironment } from '../../plugins'; +import { NotificationBadge } from '@justweb3/ui'; +import { ChatIcon } from '../../icons/ChatIcon'; +import { useJustWeb3XMTP } from '../../providers/JustWeb3XMTPProvider'; +import { useMemo } from 'react'; +import { Client, ClientOptions, useClient } from '@xmtp/react-sdk'; +import { useEthersSigner } from '../../hooks'; +import { useMountedAccount } from '@justaname.id/react'; +import { loadKeys, storeKeys, wipeKeys } from '../../utils/xmtp'; + +export interface ChatMenuButtonProps { + handleOpen: (open: boolean) => void; + env: XmtpEnvironment; +} + +export const JustWeb3ButtonRight: React.FC = ({ + handleOpen, + env, +}) => { + const { conversationsInfo } = useJustWeb3XMTP(); + const totalUnreadCount = useMemo(() => { + return conversationsInfo + .filter((conversation) => conversation.consent === 'allowed') + .reduce((acc, curr) => acc + curr.unreadCount, 0); + }, [conversationsInfo]); + const { initialize } = useClient(); + const { client } = useClient(); + const walletClient = useEthersSigner(); + const { address } = useMountedAccount(); + + const handleChat = async () => { + if (!client) { + const signer = walletClient; + try { + if (!signer) { + return; + } + const clientOptions: Partial> = { + appVersion: 'JustWeb3/1.0.0', + env: env, + }; + let keys = loadKeys(address ?? '', env); + if (!keys) { + keys = await Client.getKeys(signer, { + env: env, + skipContactPublishing: false, + // persistConversations: false, + }); + storeKeys(address ?? '', keys, env); + } + await initialize({ + keys, + options: clientOptions, + signer: signer, + }).then(() => { + handleOpen(true); + }); + + // handleClient(client) + } catch (error) { + console.error('Failed to initialize XMTP Client:', error); + wipeKeys(address ?? '', env); + } + } else { + handleOpen(true); + } + }; + + return ( + { + e.stopPropagation(); + handleChat(); + }} + /> + } + /> + ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/components/ProfileChatButton/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/components/ProfileChatButton/index.tsx index c0965bde..902cb71f 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/components/ProfileChatButton/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/components/ProfileChatButton/index.tsx @@ -12,12 +12,14 @@ export interface ProfileChatButtonProps { ens: string; env: 'local' | 'production' | 'dev'; chainId: ChainId; + address: string; } export const ProfileChatButton: React.FC = ({ ens, env, chainId, + address: profileAddress, }) => { const { closeEnsProfile } = useJustWeb3(); const { handleOpenChat } = useJustWeb3XMTP(); @@ -92,6 +94,10 @@ export const ProfileChatButton: React.FC = ({ } }, [canMessage, canMessageAddress, env, records]); + if (profileAddress === address) { + return null; + } + return (
) => { + return ( + + + + ); +}; diff --git a/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx index 90d1a0a3..22758fb3 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/plugins/index.tsx @@ -2,6 +2,7 @@ import { JustaPlugin } from '@justweb3/widget'; import { JustWeb3XMTPProvider } from '../providers/JustWeb3XMTPProvider'; import { ChatMenuButton } from '../components/ChatMenuButton'; import { ProfileChatButton } from '../components/ProfileChatButton'; +import { JustWeb3ButtonRight } from '../components/JustWeb3ButtonRight'; export type XmtpEnvironment = 'local' | 'production' | 'dev'; @@ -9,6 +10,14 @@ export const XMTPPlugin = (env: XmtpEnvironment): JustaPlugin => { return { name: 'XMTPPlugin', components: { + JustWeb3ButtonRight: (pluginApi) => { + return ( + pluginApi.setState('xmtpOpen', open)} + env={env} + /> + ); + }, Provider: (pluginApi, children) => { return ( { ); }, ProfileHeader: (pluginApi, ens, chainId, address) => { - return ; + return ( + + ); }, SignInMenu: (pluginApi) => { return ( diff --git a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx index 1ee5a0a8..7092f8d0 100644 --- a/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx +++ b/packages/@justweb3/xmtp-plugin/src/lib/providers/JustWeb3XMTPProvider/index.tsx @@ -11,7 +11,6 @@ import { replyContentTypeConfig, useClient, useMessages, - useStreamMessages, XMTPProvider, } from '@xmtp/react-sdk'; import { InboxSheet } from '../../components/InboxSheet'; @@ -56,6 +55,7 @@ export const JustWeb3XMTPProvider: React.FC = ({ handleOpen, env, }) => { + // const { isConnected } = useMountedAccount() const [isXmtpEnabled, setIsXmtpEnabled] = React.useState(false); const [conversation, setConversation] = React.useState | null>(null); @@ -77,7 +77,6 @@ export const JustWeb3XMTPProvider: React.FC = ({ }[] >([]); - console.log(conversations); const handleXmtpEnabled = (enabled: boolean) => { setIsXmtpEnabled(enabled); }; @@ -116,12 +115,11 @@ export const JustWeb3XMTPProvider: React.FC = ({ } prev[index].unreadCount = unreadCount; prev[index].lastMessage = lastMessage; + prev[index].consent = consent; return [...prev]; }); }; - console.log('Conversations Info:', conversationsInfo); - return ( = ({ }) => { const { messages } = useMessages(conversation); - useStreamMessages(conversation); const _unreadCount = useMemo(() => { let count = 0; const _messages = [...messages].reverse(); @@ -285,12 +282,17 @@ export const GetConversationInfo: React.FC = ({ const _lastMessage = useMemo(() => { const _messages = [...messages]; - let lastMessage = _messages[_messages.length - 1]; - if (lastMessage?.contentType === ContentTypeReadReceipt.toString()) { - lastMessage = _messages[_messages.length - 2]; + // let lastMessage = _messages[_messages.length - 1]; + let lastMessageIndex = _messages.length - 1; + let lastMessage = _messages[lastMessageIndex]; + while ( + lastMessage?.contentType === ContentTypeReadReceipt.toString() && + lastMessageIndex > 0 + ) { + lastMessageIndex--; + lastMessage = _messages[lastMessageIndex]; } - console.log('Last Message:', lastMessage); return lastMessage; }, [messages]); @@ -299,12 +301,6 @@ export const GetConversationInfo: React.FC = ({ return; } - console.log( - 'Updating Conversation Info:', - conversation.topic, - _unreadCount, - _lastMessage - ); handleConversationInfo(conversation.topic, _unreadCount, _lastMessage); }, [ conversation.topic, @@ -330,44 +326,42 @@ export const Checks: React.FC = ({ const [rejected, setRejected] = React.useState(false); useEffect(() => { + if (!client || !address || isInitializing) return; + if (client.address.toLowerCase() === address.toLowerCase()) return; + async function reinitializeXmtp() { - if (client && address) { - if (client?.address?.toLowerCase() !== address.toLowerCase()) { - await disconnect(); - - if (!signer) { - return; - } - setIsInitializing(true); - const clientOptions: Partial> = { - appVersion: 'JustWeb3/1.0.0/' + env + '/0', - env: env, - }; - let keys = loadKeys(address ?? '', env); - console.log('Keys:', keys); - if (!keys) { - keys = await Client.getKeys(signer, { - env: env, - skipContactPublishing: false, - // persistConversations: false, - }); - storeKeys(address ?? '', keys, env); - } - - await initialize({ - keys, - options: clientOptions, - signer: signer, - }); - } + await disconnect(); + + if (!signer) { + return; } + setIsInitializing(true); + const clientOptions: Partial> = { + appVersion: 'JustWeb3/1.0.0/' + env + '/0', + env: env, + }; + let keys = loadKeys(address ?? '', env); + if (!keys) { + keys = await Client.getKeys(signer, { + env: env, + skipContactPublishing: false, + // persistConversations: false, + }); + storeKeys(address ?? '', keys, env); + } + + await initialize({ + keys, + options: clientOptions, + signer: signer, + }); } reinitializeXmtp(); - }, [client, address, signer, env, initialize, disconnect]); + }, [client, address, signer, env, initialize, disconnect, isInitializing]); useEffect(() => { + if (isInitializing || isLoading || rejected) return; async function initializeXmtp() { - if (isInitializing || isLoading || rejected) return; try { if (client) { return; diff --git a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx index 03c180ca..6dd6e287 100644 --- a/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx +++ b/packages/@justweb3/xmtp-plugin/src/stories/xmtp.stories.tsx @@ -1,5 +1,4 @@ import { - JustEnsCard, JustWeb3Button, JustWeb3Provider, JustWeb3ProviderConfig, @@ -93,55 +92,55 @@ export const Example = () => {
-
- {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - {/**/} - - - -
-
- - - - - - -
+ {/*
*/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/*
*/} + {/**/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/*
*/}
diff --git a/yarn.lock b/yarn.lock index 902a2f9e..7630baab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -62,6 +62,31 @@ __metadata: languageName: node linkType: hard +"@antfu/ni@npm:^0.21.12": + version: 0.21.12 + resolution: "@antfu/ni@npm:0.21.12" + bin: + na: bin/na.mjs + nci: bin/nci.mjs + ni: bin/ni.mjs + nlx: bin/nlx.mjs + nr: bin/nr.mjs + nu: bin/nu.mjs + nun: bin/nun.mjs + checksum: 10c0/729e03cdde75087bd1e959357fa69caf5c8ecf80087f19ac07ecceeb0def3eabbe87a8bd88a78444bea321cce8e385a1c90dca4b5146c351e32c2a516c2d9ea2 + languageName: node + linkType: hard + +"@axiomhq/js@npm:1.0.0-rc.3": + version: 1.0.0-rc.3 + resolution: "@axiomhq/js@npm:1.0.0-rc.3" + dependencies: + fetch-retry: "npm:^6.0.0" + uuid: "npm:^8.3.2" + checksum: 10c0/bcd02c844c19dcfa49e7e75fffbafffea6caa46756e8f194e41b281c807fde26ccdb2198844672ad078c54ba9609949585ffd2c2d0ed9b5db1d74a77dae5f883 + languageName: node + linkType: hard + "@babel/code-frame@npm:7.10.4, @babel/code-frame@npm:~7.10.4": version: 7.10.4 resolution: "@babel/code-frame@npm:7.10.4" @@ -89,7 +114,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.13.16, @babel/core@npm:^7.14.5, @babel/core@npm:^7.18.9, @babel/core@npm:^7.20.0, @babel/core@npm:^7.21.3, @babel/core@npm:^7.22.5, @babel/core@npm:^7.23.0, @babel/core@npm:^7.23.2, @babel/core@npm:^7.23.9, @babel/core@npm:^7.24.4, @babel/core@npm:^7.25.2, @babel/core@npm:^7.7.5": +"@babel/core@npm:7.26.0, @babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.13.16, @babel/core@npm:^7.14.5, @babel/core@npm:^7.18.9, @babel/core@npm:^7.20.0, @babel/core@npm:^7.21.3, @babel/core@npm:^7.22.5, @babel/core@npm:^7.23.0, @babel/core@npm:^7.23.2, @babel/core@npm:^7.23.9, @babel/core@npm:^7.24.4, @babel/core@npm:^7.25.2, @babel/core@npm:^7.7.5": version: 7.26.0 resolution: "@babel/core@npm:7.26.0" dependencies: @@ -1707,7 +1732,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.0, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.4, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": +"@babel/types@npm:7.26.0, @babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.0, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.4, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": version: 7.26.0 resolution: "@babel/types@npm:7.26.0" dependencies: @@ -1798,7 +1823,7 @@ __metadata: languageName: node linkType: hard -"@clack/core@npm:0.3.5, @clack/core@npm:^0.3.5": +"@clack/core@npm:0.3.5, @clack/core@npm:^0.3.3, @clack/core@npm:^0.3.5": version: 0.3.5 resolution: "@clack/core@npm:0.3.5" dependencies: @@ -1808,6 +1833,18 @@ __metadata: languageName: node linkType: hard +"@clack/prompts@npm:^0.7.0": + version: 0.7.0 + resolution: "@clack/prompts@npm:0.7.0" + dependencies: + "@clack/core": "npm:^0.3.3" + is-unicode-supported: "npm:*" + picocolors: "npm:^1.0.0" + sisteransi: "npm:^1.0.5" + checksum: 10c0/fecb3b34308c5cb75807211b28d50caa4b0c5d150d16e733e59bfba3187ac856f050ed44baeca90eb99e047671096ff54402dd2790e9c0e77845a75b04003e2e + languageName: node + linkType: hard + "@clack/prompts@npm:^0.8.2": version: 0.8.2 resolution: "@clack/prompts@npm:0.8.2" @@ -2111,6 +2148,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/aix-ppc64@npm:0.20.2" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/aix-ppc64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/aix-ppc64@npm:0.21.5" @@ -2132,6 +2176,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm64@npm:0.20.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-arm64@npm:0.21.5" @@ -2153,6 +2204,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm@npm:0.20.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-arm@npm:0.21.5" @@ -2174,6 +2232,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-x64@npm:0.20.2" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-x64@npm:0.21.5" @@ -2195,6 +2260,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-arm64@npm:0.20.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/darwin-arm64@npm:0.21.5" @@ -2216,6 +2288,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-x64@npm:0.20.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/darwin-x64@npm:0.21.5" @@ -2237,6 +2316,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-arm64@npm:0.20.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/freebsd-arm64@npm:0.21.5" @@ -2258,6 +2344,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-x64@npm:0.20.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/freebsd-x64@npm:0.21.5" @@ -2279,6 +2372,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm64@npm:0.20.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-arm64@npm:0.21.5" @@ -2300,6 +2400,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm@npm:0.20.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-arm@npm:0.21.5" @@ -2321,6 +2428,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ia32@npm:0.20.2" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-ia32@npm:0.21.5" @@ -2342,6 +2456,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-loong64@npm:0.20.2" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-loong64@npm:0.21.5" @@ -2363,6 +2484,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-mips64el@npm:0.20.2" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-mips64el@npm:0.21.5" @@ -2384,6 +2512,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ppc64@npm:0.20.2" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-ppc64@npm:0.21.5" @@ -2405,6 +2540,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-riscv64@npm:0.20.2" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-riscv64@npm:0.21.5" @@ -2426,6 +2568,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-s390x@npm:0.20.2" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-s390x@npm:0.21.5" @@ -2447,6 +2596,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-x64@npm:0.20.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-x64@npm:0.21.5" @@ -2468,6 +2624,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/netbsd-x64@npm:0.20.2" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/netbsd-x64@npm:0.21.5" @@ -2489,6 +2652,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/openbsd-x64@npm:0.20.2" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/openbsd-x64@npm:0.21.5" @@ -2510,6 +2680,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/sunos-x64@npm:0.20.2" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/sunos-x64@npm:0.21.5" @@ -2531,6 +2708,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-arm64@npm:0.20.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-arm64@npm:0.21.5" @@ -2552,6 +2736,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-ia32@npm:0.20.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-ia32@npm:0.21.5" @@ -2573,6 +2764,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-x64@npm:0.20.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-x64@npm:0.21.5" @@ -3652,6 +3850,15 @@ __metadata: languageName: node linkType: hard +"@hono/node-server@npm:^1.11.1": + version: 1.13.7 + resolution: "@hono/node-server@npm:1.13.7" + peerDependencies: + hono: ^4 + checksum: 10c0/a50da48fd0b5c647db20a4cefdbec10af957753427bb6b66388f2716a9d3910f192f2f51d0a3ddb9e5e0d6f9057451daabbd84fe8f6190e5ab15c35f86ebaafa + languageName: node + linkType: hard + "@hookform/error-message@npm:^2.0.1": version: 2.0.1 resolution: "@hookform/error-message@npm:2.0.1" @@ -5074,6 +5281,66 @@ __metadata: languageName: node linkType: hard +"@million/install@npm:latest": + version: 1.0.13 + resolution: "@million/install@npm:1.0.13" + dependencies: + "@antfu/ni": "npm:^0.21.12" + "@axiomhq/js": "npm:1.0.0-rc.3" + "@babel/parser": "npm:^7.25.3" + "@babel/types": "npm:7.26.0" + "@clack/prompts": "npm:^0.7.0" + ast-types: "npm:^0.14.2" + cli-high: "npm:^0.4.2" + diff: "npm:^5.1.0" + effect: "npm:^3.8.4" + nanoid: "npm:^5.0.7" + recast: "npm:^0.23.9" + xycolors: "npm:^0.1.2" + bin: + install: bin/index.js + checksum: 10c0/496617a85663b95b196c698cb6b768aef18954d932eaf01760a5f1299fbe91f4010720bc835596a05a2124bf580cb13eb0b04bc6f12d0b4158d3096290b55307 + languageName: node + linkType: hard + +"@million/lint@npm:^1.0.13": + version: 1.0.13 + resolution: "@million/lint@npm:1.0.13" + dependencies: + "@axiomhq/js": "npm:1.0.0-rc.3" + "@babel/core": "npm:7.26.0" + "@babel/types": "npm:7.26.0" + "@hono/node-server": "npm:^1.11.1" + "@million/install": "npm:latest" + "@rollup/pluginutils": "npm:^5.1.0" + "@rrweb/types": "npm:2.0.0-alpha.16" + babel-plugin-syntax-hermes-parser: "npm:^0.21.1" + ci-info: "npm:^4.0.0" + esbuild: "npm:^0.20.1" + faster-babel-types: "npm:^0.1.0" + hono: "npm:^4.5.9" + isomorphic-fetch: "npm:^3.0.0" + nanoid: "npm:^5.0.7" + ohash: "npm:^1.1.4" + pako: "npm:^2.1.0" + pathe: "npm:^1.1.2" + piscina: "npm:^4.4.0" + pretty-ms: "npm:8.0.0" + react-scan: "npm:^0.0.31" + rrweb: "npm:2.0.0-alpha.4" + rrweb-player: "npm:1.0.0-alpha.4" + semver: "npm:^7.6.2" + socket.io: "npm:^4.8.1" + socket.io-client: "npm:^4.7.5" + tmp: "npm:^0.2.3" + unplugin: "npm:^1.6.0" + update-notifier-cjs: "npm:^5.1.6" + bin: + lint: cli.js + checksum: 10c0/bd5d28ed49137edf20fa9c0bf1ecc429d2ef0f5fda63ff4f020861bce9049d9dd3b6d52f9daa5a5816b312486c7919a802e567e3bac7fa2491d582d3a27cdce5 + languageName: node + linkType: hard + "@module-federation/bridge-react-webpack-plugin@npm:0.6.14": version: 0.6.14 resolution: "@module-federation/bridge-react-webpack-plugin@npm:0.6.14" @@ -8725,6 +8992,29 @@ __metadata: languageName: node linkType: hard +"@rrweb/types@npm:2.0.0-alpha.16": + version: 2.0.0-alpha.16 + resolution: "@rrweb/types@npm:2.0.0-alpha.16" + dependencies: + rrweb-snapshot: "npm:^2.0.0-alpha.16" + checksum: 10c0/d2eb1e755c3bed7fda19ebdaca92df5ec83979326d2597c95fcdd1a59e4f0fbd17b6f3f5bc48e6faaf098a4521f13cf1aeaf9247e026d8c02e0843ea313498d0 + languageName: node + linkType: hard + +"@rrweb/types@npm:^2.0.0-alpha.18, @rrweb/types@npm:^2.0.0-alpha.4": + version: 2.0.0-alpha.18 + resolution: "@rrweb/types@npm:2.0.0-alpha.18" + checksum: 10c0/a1adb842f59b782e04576a7e88ffc2e43b8b29460555922e6a15f8ffd4840e554e96c1331653b0a322a3a8f25e73a9ae38ff37d3e60f1da71b6f6c0d001a20e7 + languageName: node + linkType: hard + +"@rrweb/utils@npm:^2.0.0-alpha.18": + version: 2.0.0-alpha.18 + resolution: "@rrweb/utils@npm:2.0.0-alpha.18" + checksum: 10c0/04a24b838de7294254ead08fbdc39daa9e04a86ed519eba3d6a85d485da56da02aa19cd61d82606c538d324060d6a0fc80fc41813d474e2b57ad9b61e74a137c + languageName: node + linkType: hard + "@rtsao/scc@npm:^1.1.0": version: 1.1.0 resolution: "@rtsao/scc@npm:1.1.0" @@ -11304,6 +11594,13 @@ __metadata: languageName: node linkType: hard +"@tsconfig/svelte@npm:^1.0.0": + version: 1.0.13 + resolution: "@tsconfig/svelte@npm:1.0.13" + checksum: 10c0/701da672b70300a023754eca604788fe96542178cbf362122bb1083a81f3ff4f8922213960abb99aaf194977e0582eb76a51695a9dd9b5fd6a458e17fb0c3074 + languageName: node + linkType: hard + "@tufjs/canonical-json@npm:2.0.0": version: 2.0.0 resolution: "@tufjs/canonical-json@npm:2.0.0" @@ -11454,7 +11751,14 @@ __metadata: languageName: node linkType: hard -"@types/cors@npm:^2.8.17": +"@types/cookie@npm:^0.4.1": + version: 0.4.1 + resolution: "@types/cookie@npm:0.4.1" + checksum: 10c0/f96afe12bd51be1ec61410b0641243d93fa3a494702407c787a4c872b5c8bcd39b224471452055e44a9ce42af1a636e87d161994226eaf4c2be9c30f60418409 + languageName: node + linkType: hard + +"@types/cors@npm:^2.8.12, @types/cors@npm:^2.8.17": version: 2.8.17 resolution: "@types/cors@npm:2.8.17" dependencies: @@ -11472,6 +11776,13 @@ __metadata: languageName: node linkType: hard +"@types/css-font-loading-module@npm:0.0.7": + version: 0.0.7 + resolution: "@types/css-font-loading-module@npm:0.0.7" + checksum: 10c0/a74759a14bcc7d60a1a1d863b53b7638d4aa7f88f1d97347426262cc6fe8f9335d8fa80c7e0608cd67e33ff0067608e9b5475a1227a684e1dfad3cac87df1405 + languageName: node + linkType: hard + "@types/debug@npm:^4.1.7": version: 4.1.12 resolution: "@types/debug@npm:4.1.12" @@ -11844,6 +12155,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:>=10.0.0": + version: 22.10.1 + resolution: "@types/node@npm:22.10.1" + dependencies: + undici-types: "npm:~6.20.0" + checksum: 10c0/0fbb6d29fa35d807f0223a4db709c598ac08d66820240a2cd6a8a69b8f0bc921d65b339d850a666b43b4e779f967e6ed6cf6f0fca3575e08241e6b900364c234 + languageName: node + linkType: hard + "@types/node@npm:>=13.7.0": version: 22.9.1 resolution: "@types/node@npm:22.9.1" @@ -14397,6 +14717,13 @@ __metadata: languageName: node linkType: hard +"@xstate/fsm@npm:^1.4.0": + version: 1.6.5 + resolution: "@xstate/fsm@npm:1.6.5" + checksum: 10c0/472fe625b84b9e7102b8774e80c441b8b7dbc9585e700223d9c7a39c583d38ba50636909a5d749d44b361555daa841862f932a29c52b81c8829a74884e715bf4 + languageName: node + linkType: hard + "@xtuc/ieee754@npm:^1.2.0": version: 1.2.0 resolution: "@xtuc/ieee754@npm:1.2.0" @@ -14741,6 +15068,15 @@ __metadata: languageName: node linkType: hard +"ansi-align@npm:^3.0.0": + version: 3.0.1 + resolution: "ansi-align@npm:3.0.1" + dependencies: + string-width: "npm:^4.1.0" + checksum: 10c0/ad8b755a253a1bc8234eb341e0cec68a857ab18bf97ba2bda529e86f6e30460416523e0ec58c32e5c21f0ca470d779503244892873a5895dbd0c39c788e82467 + languageName: node + linkType: hard + "ansi-colors@npm:^4.1.1, ansi-colors@npm:^4.1.3": version: 4.1.3 resolution: "ansi-colors@npm:4.1.3" @@ -15209,6 +15545,15 @@ __metadata: languageName: node linkType: hard +"ast-types@npm:^0.14.2": + version: 0.14.2 + resolution: "ast-types@npm:0.14.2" + dependencies: + tslib: "npm:^2.0.1" + checksum: 10c0/5d66d89b6c07fe092087454b6042dbaf81f2882b176db93861e2b986aafe0bce49e1f1ff59aac775d451c1426ad1e967d250e9e3548f5166ea8a3475e66c169d + languageName: node + linkType: hard + "ast-types@npm:^0.16.1": version: 0.16.1 resolution: "ast-types@npm:0.16.1" @@ -15567,6 +15912,15 @@ __metadata: languageName: node linkType: hard +"babel-plugin-syntax-hermes-parser@npm:^0.21.1": + version: 0.21.1 + resolution: "babel-plugin-syntax-hermes-parser@npm:0.21.1" + dependencies: + hermes-parser: "npm:0.21.1" + checksum: 10c0/0134b435e194654f5ba96b6f48ea8ac37c31e9f52e29261bddeefb0cb98852a13cf58a569dd1f39479098dbaf54a0152bff995faf58b8206eb64c2ffaa800b8d + languageName: node + linkType: hard + "babel-plugin-syntax-trailing-function-commas@npm:^7.0.0-beta.0": version: 7.0.0-beta.0 resolution: "babel-plugin-syntax-trailing-function-commas@npm:7.0.0-beta.0" @@ -15768,6 +16122,13 @@ __metadata: languageName: node linkType: hard +"base64-arraybuffer@npm:^1.0.1": + version: 1.0.2 + resolution: "base64-arraybuffer@npm:1.0.2" + checksum: 10c0/3acac95c70f9406e87a41073558ba85b6be9dbffb013a3d2a710e3f2d534d506c911847d5d9be4de458af6362c676de0a5c4c2d7bdf4def502d00b313368e72f + languageName: node + linkType: hard + "base64-js@npm:^1.2.3, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1, base64-js@npm:^1.5.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -15775,6 +16136,13 @@ __metadata: languageName: node linkType: hard +"base64id@npm:2.0.0, base64id@npm:~2.0.0": + version: 2.0.0 + resolution: "base64id@npm:2.0.0" + checksum: 10c0/6919efd237ed44b9988cbfc33eca6f173a10e810ce50292b271a1a421aac7748ef232a64d1e6032b08f19aae48dce6ee8f66c5ae2c9e5066c82b884861d4d453 + languageName: node + linkType: hard + "base64url@npm:3.0.1, base64url@npm:^3.0.1": version: 3.0.1 resolution: "base64url@npm:3.0.1" @@ -16013,6 +16381,22 @@ __metadata: languageName: node linkType: hard +"boxen@npm:^5.0.0": + version: 5.1.2 + resolution: "boxen@npm:5.1.2" + dependencies: + ansi-align: "npm:^3.0.0" + camelcase: "npm:^6.2.0" + chalk: "npm:^4.1.0" + cli-boxes: "npm:^2.2.1" + string-width: "npm:^4.2.2" + type-fest: "npm:^0.20.2" + widest-line: "npm:^3.1.0" + wrap-ansi: "npm:^7.0.0" + checksum: 10c0/71f31c2eb3dcacd5fce524ae509e0cc90421752e0bfbd0281fd3352871d106c462a0f810c85f2fdb02f3a9fab2d7a84e9718b4999384d651b76104ebe5d2c024 + languageName: node + linkType: hard + "bplist-creator@npm:0.1.1": version: 0.1.1 resolution: "bplist-creator@npm:0.1.1" @@ -16975,6 +17359,13 @@ __metadata: languageName: node linkType: hard +"cli-boxes@npm:^2.2.1": + version: 2.2.1 + resolution: "cli-boxes@npm:2.2.1" + checksum: 10c0/6111352edbb2f62dbc7bfd58f2d534de507afed7f189f13fa894ce5a48badd94b2aa502fda28f1d7dd5f1eb456e7d4033d09a76660013ef50c7f66e7a034f050 + languageName: node + linkType: hard + "cli-columns@npm:^4.0.0": version: 4.0.0 resolution: "cli-columns@npm:4.0.0" @@ -17012,6 +17403,20 @@ __metadata: languageName: node linkType: hard +"cli-high@npm:^0.4.2": + version: 0.4.3 + resolution: "cli-high@npm:0.4.3" + dependencies: + "@clack/prompts": "npm:^0.7.0" + sugar-high: "npm:^0.7.1" + xycolors: "npm:^0.1.2" + yargs: "npm:^17.7.2" + bin: + cli-high: bin/index.js + checksum: 10c0/0f93a06436d20d7224fd21a815c46dcad10952724ba7dc3d3ac67ff60fa818676238115fac4620547322e92b450cc88f642efb449ad05c71b648e0fe10a7ec17 + languageName: node + linkType: hard + "cli-spinners@npm:2.6.1": version: 2.6.1 resolution: "cli-spinners@npm:2.6.1" @@ -17469,6 +17874,20 @@ __metadata: languageName: node linkType: hard +"configstore@npm:^5.0.1": + version: 5.0.1 + resolution: "configstore@npm:5.0.1" + dependencies: + dot-prop: "npm:^5.2.0" + graceful-fs: "npm:^4.1.2" + make-dir: "npm:^3.0.0" + unique-string: "npm:^2.0.0" + write-file-atomic: "npm:^3.0.0" + xdg-basedir: "npm:^4.0.0" + checksum: 10c0/5af23830e78bdc56cbe92a2f81e87f1d3a39e96e51a0ab2a8bc79bbbc5d4440a48d92833b3fd9c6d34b4a9c4c5853c8487b8e6e68593e7ecbc7434822f7aced3 + languageName: node + linkType: hard + "confusing-browser-globals@npm:^1.0.9": version: 1.0.11 resolution: "confusing-browser-globals@npm:1.0.11" @@ -17627,7 +18046,7 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.7.2": +"cookie@npm:0.7.2, cookie@npm:~0.7.2": version: 0.7.2 resolution: "cookie@npm:0.7.2" checksum: 10c0/9596e8ccdbf1a3a88ae02cf5ee80c1c50959423e1022e4e60b91dd87c622af1da309253d8abdb258fb5e3eacb4f08e579dc58b4897b8087574eee0fd35dfa5d2 @@ -17706,7 +18125,7 @@ __metadata: languageName: node linkType: hard -"cors@npm:2.8.5, cors@npm:^2.8.5": +"cors@npm:2.8.5, cors@npm:^2.8.5, cors@npm:~2.8.5": version: 2.8.5 resolution: "cors@npm:2.8.5" dependencies: @@ -18560,7 +18979,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:4.3.7, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.6, debug@npm:~4.3.1, debug@npm:~4.3.2": +"debug@npm:4, debug@npm:4.3.7, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.6, debug@npm:~4.3.1, debug@npm:~4.3.2, debug@npm:~4.3.4": version: 4.3.7 resolution: "debug@npm:4.3.7" dependencies: @@ -19241,7 +19660,7 @@ __metadata: languageName: node linkType: hard -"dot-prop@npm:^5.1.0": +"dot-prop@npm:^5.1.0, dot-prop@npm:^5.2.0": version: 5.3.0 resolution: "dot-prop@npm:5.3.0" dependencies: @@ -19349,6 +19768,15 @@ __metadata: languageName: node linkType: hard +"effect@npm:^3.8.4": + version: 3.11.3 + resolution: "effect@npm:3.11.3" + dependencies: + fast-check: "npm:^3.21.0" + checksum: 10c0/a343a20d833112e21b27f17f404e97a33240fafe09d638428381d8bb96b4f0d2eccdaebe43453dce4982242134e1c8cfbab1d63e364fea79de02faeb92940c04 + languageName: node + linkType: hard + "ejs@npm:^3.1.10, ejs@npm:^3.1.7": version: 3.1.10 resolution: "ejs@npm:3.1.10" @@ -19541,6 +19969,24 @@ __metadata: languageName: node linkType: hard +"engine.io@npm:~6.6.0": + version: 6.6.2 + resolution: "engine.io@npm:6.6.2" + dependencies: + "@types/cookie": "npm:^0.4.1" + "@types/cors": "npm:^2.8.12" + "@types/node": "npm:>=10.0.0" + accepts: "npm:~1.3.4" + base64id: "npm:2.0.0" + cookie: "npm:~0.7.2" + cors: "npm:~2.8.5" + debug: "npm:~4.3.1" + engine.io-parser: "npm:~5.2.1" + ws: "npm:~8.17.1" + checksum: 10c0/e9ac3cba49badb6905259df3b019fbcbe53e2a389c930fb9fbc10eebc8839554b189706206bba2509a4a3a7d78a32f7e027f73230f31662c7efd215276432dad + languageName: node + linkType: hard + "enhanced-resolve@npm:^5.0.0, enhanced-resolve@npm:^5.15.0, enhanced-resolve@npm:^5.17.1, enhanced-resolve@npm:^5.7.0": version: 5.17.1 resolution: "enhanced-resolve@npm:5.17.1" @@ -20136,6 +20582,86 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.20.1": + version: 0.20.2 + resolution: "esbuild@npm:0.20.2" + dependencies: + "@esbuild/aix-ppc64": "npm:0.20.2" + "@esbuild/android-arm": "npm:0.20.2" + "@esbuild/android-arm64": "npm:0.20.2" + "@esbuild/android-x64": "npm:0.20.2" + "@esbuild/darwin-arm64": "npm:0.20.2" + "@esbuild/darwin-x64": "npm:0.20.2" + "@esbuild/freebsd-arm64": "npm:0.20.2" + "@esbuild/freebsd-x64": "npm:0.20.2" + "@esbuild/linux-arm": "npm:0.20.2" + "@esbuild/linux-arm64": "npm:0.20.2" + "@esbuild/linux-ia32": "npm:0.20.2" + "@esbuild/linux-loong64": "npm:0.20.2" + "@esbuild/linux-mips64el": "npm:0.20.2" + "@esbuild/linux-ppc64": "npm:0.20.2" + "@esbuild/linux-riscv64": "npm:0.20.2" + "@esbuild/linux-s390x": "npm:0.20.2" + "@esbuild/linux-x64": "npm:0.20.2" + "@esbuild/netbsd-x64": "npm:0.20.2" + "@esbuild/openbsd-x64": "npm:0.20.2" + "@esbuild/sunos-x64": "npm:0.20.2" + "@esbuild/win32-arm64": "npm:0.20.2" + "@esbuild/win32-ia32": "npm:0.20.2" + "@esbuild/win32-x64": "npm:0.20.2" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/66398f9fb2c65e456a3e649747b39af8a001e47963b25e86d9c09d2a48d61aa641b27da0ce5cad63df95ad246105e1d83e7fee0e1e22a0663def73b1c5101112 + languageName: node + linkType: hard + "escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" @@ -20143,6 +20669,13 @@ __metadata: languageName: node linkType: hard +"escape-goat@npm:^2.0.0": + version: 2.1.1 + resolution: "escape-goat@npm:2.1.1" + checksum: 10c0/fc0ad656f89c05e86a9641a21bdc5ea37b258714c057430b68a834854fa3e5770cda7d41756108863fc68b1e36a0946463017b7553ac39eaaf64815be07816fc + languageName: node + linkType: hard + "escape-html@npm:^1.0.3, escape-html@npm:~1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" @@ -21463,6 +21996,15 @@ __metadata: languageName: node linkType: hard +"fast-check@npm:^3.21.0": + version: 3.23.1 + resolution: "fast-check@npm:3.23.1" + dependencies: + pure-rand: "npm:^6.1.0" + checksum: 10c0/d61ee4a7a2e1abc5126bf2f1894413f532f686b3d1fc15c67fefb60dcca66024934b69a6454d3eba92e6568ac1abbb9882080e212d255865c3b3bbe52c5bf702 + languageName: node + linkType: hard + "fast-copy@npm:^3.0.0, fast-copy@npm:^3.0.2": version: 3.0.2 resolution: "fast-copy@npm:3.0.2" @@ -21587,6 +22129,15 @@ __metadata: languageName: node linkType: hard +"faster-babel-types@npm:^0.1.0": + version: 0.1.0 + resolution: "faster-babel-types@npm:0.1.0" + peerDependencies: + "@babel/types": ^7 + checksum: 10c0/e73f27146458d8af39582231e2b65643f1d74a3cc184ed68a684c3c74cb8b8d054773c174fb6a0bb7a85523af91f10a11ae6f542766d5be6d7b570680c2bb256 + languageName: node + linkType: hard + "fastest-levenshtein@npm:^1.0.12, fastest-levenshtein@npm:^1.0.16": version: 1.0.16 resolution: "fastest-levenshtein@npm:1.0.16" @@ -21693,6 +22244,20 @@ __metadata: languageName: node linkType: hard +"fetch-retry@npm:^6.0.0": + version: 6.0.0 + resolution: "fetch-retry@npm:6.0.0" + checksum: 10c0/8e275b042ff98041236d30b71966f24c34ff19f957bb0f00e664754bd63d0dfb5122d091e7d5bca21f6370d88a1713d22421b33471305d7b86d6799427278802 + languageName: node + linkType: hard + +"fflate@npm:^0.4.4": + version: 0.4.8 + resolution: "fflate@npm:0.4.8" + checksum: 10c0/29d1eddaaa5deab61b1c6b0d21282adacadbc4d2c01e94d8b1ee784398151673b9c563e53f97a801bc410a1ae55e8de5378114a743430e643e7a0644ba8e5a42 + languageName: node + linkType: hard + "fflate@npm:^0.8.1": version: 0.8.2 resolution: "fflate@npm:0.8.2" @@ -23100,6 +23665,13 @@ __metadata: languageName: node linkType: hard +"has-yarn@npm:^2.1.0": + version: 2.1.0 + resolution: "has-yarn@npm:2.1.0" + checksum: 10c0/b5cab61b4129c2fc0474045b59705371b7f5ddf2aab8ba8725011e52269f017e06f75059a2c8a1d8011e9779c2885ad987263cfc6d1280f611c396b45fd5d74a + languageName: node + linkType: hard + "has@npm:^1.0.3": version: 1.0.4 resolution: "has@npm:1.0.4" @@ -23255,6 +23827,13 @@ __metadata: languageName: node linkType: hard +"hermes-estree@npm:0.21.1": + version: 0.21.1 + resolution: "hermes-estree@npm:0.21.1" + checksum: 10c0/b9bacf41ced8346e4e1d91519530a5facf8cde8662a4ed732b85bb989b11d596832d3fe743e6ccd212eb08ca160ad504d191895cc13b62932f5ba14edb27516f + languageName: node + linkType: hard + "hermes-estree@npm:0.23.1": version: 0.23.1 resolution: "hermes-estree@npm:0.23.1" @@ -23271,6 +23850,15 @@ __metadata: languageName: node linkType: hard +"hermes-parser@npm:0.21.1": + version: 0.21.1 + resolution: "hermes-parser@npm:0.21.1" + dependencies: + hermes-estree: "npm:0.21.1" + checksum: 10c0/a3df443bfef835a982865da16a0b0bda5d86efa699791d5007e14b1b2731cb62cb9b1ac9157581602d35ff0ae437a345e701e03dd6330d9c552e8dafa9776436 + languageName: node + linkType: hard + "hermes-parser@npm:0.23.1": version: 0.23.1 resolution: "hermes-parser@npm:0.23.1" @@ -23330,6 +23918,13 @@ __metadata: languageName: node linkType: hard +"hono@npm:^4.5.9": + version: 4.6.13 + resolution: "hono@npm:4.6.13" + checksum: 10c0/8bf6ed856e3204d8dadc74cddc0f5a8e99e78a12df00e5b57f4d6c416ad7f808e6140688a30606c7d4b2a585b0ad085b7ed8be419f13a4b58e29dfdd54cfdac8 + languageName: node + linkType: hard + "hosted-git-info@npm:^2.1.4": version: 2.8.9 resolution: "hosted-git-info@npm:2.8.9" @@ -23896,6 +24491,13 @@ __metadata: languageName: node linkType: hard +"import-lazy@npm:^2.1.0": + version: 2.1.0 + resolution: "import-lazy@npm:2.1.0" + checksum: 10c0/c5e5f507d26ee23c5b2ed64577155810361ac37863b322cae0c17f16b6a8cdd15adf370288384ddd95ef9de05602fb8d87bf76ff835190eb037333c84db8062c + languageName: node + linkType: hard + "import-lazy@npm:~4.0.0": version: 4.0.0 resolution: "import-lazy@npm:4.0.0" @@ -24304,6 +24906,17 @@ __metadata: languageName: node linkType: hard +"is-ci@npm:^2.0.0": + version: 2.0.0 + resolution: "is-ci@npm:2.0.0" + dependencies: + ci-info: "npm:^2.0.0" + bin: + is-ci: bin.js + checksum: 10c0/17de4e2cd8f993c56c86472dd53dd9e2c7f126d0ee55afe610557046cdd64de0e8feadbad476edc9eeff63b060523b8673d9094ed2ab294b59efb5a66dd05a9a + languageName: node + linkType: hard + "is-ci@npm:^3.0.1": version: 3.0.1 resolution: "is-ci@npm:3.0.1" @@ -24493,7 +25106,7 @@ __metadata: languageName: node linkType: hard -"is-installed-globally@npm:~0.4.0": +"is-installed-globally@npm:^0.4.0, is-installed-globally@npm:~0.4.0": version: 0.4.0 resolution: "is-installed-globally@npm:0.4.0" dependencies: @@ -24571,6 +25184,13 @@ __metadata: languageName: node linkType: hard +"is-npm@npm:^5.0.0": + version: 5.0.0 + resolution: "is-npm@npm:5.0.0" + checksum: 10c0/8ded3ae1119bbbda22395fe1c64d2d79d3b3baeb2635c90f9a9dca4b8ce19a67b55fda178269b63421b257b361892fd545807fb5ac212f06776f544d9fcc3ab0 + languageName: node + linkType: hard + "is-number-object@npm:^1.0.4": version: 1.0.7 resolution: "is-number-object@npm:1.0.7" @@ -24772,6 +25392,13 @@ __metadata: languageName: node linkType: hard +"is-unicode-supported@npm:*, is-unicode-supported@npm:^2.0.0": + version: 2.1.0 + resolution: "is-unicode-supported@npm:2.1.0" + checksum: 10c0/a0f53e9a7c1fdbcf2d2ef6e40d4736fdffff1c9f8944c75e15425118ff3610172c87bf7bc6c34d3903b04be59790bb2212ddbe21ee65b5a97030fc50370545a5 + languageName: node + linkType: hard + "is-unicode-supported@npm:^0.1.0": version: 0.1.0 resolution: "is-unicode-supported@npm:0.1.0" @@ -24786,13 +25413,6 @@ __metadata: languageName: node linkType: hard -"is-unicode-supported@npm:^2.0.0": - version: 2.1.0 - resolution: "is-unicode-supported@npm:2.1.0" - checksum: 10c0/a0f53e9a7c1fdbcf2d2ef6e40d4736fdffff1c9f8944c75e15425118ff3610172c87bf7bc6c34d3903b04be59790bb2212ddbe21ee65b5a97030fc50370545a5 - languageName: node - linkType: hard - "is-valid-path@npm:^0.1.1": version: 0.1.1 resolution: "is-valid-path@npm:0.1.1" @@ -24874,6 +25494,13 @@ __metadata: languageName: node linkType: hard +"is-yarn-global@npm:^0.3.0": + version: 0.3.0 + resolution: "is-yarn-global@npm:0.3.0" + checksum: 10c0/9f1ab6f28e6e7961c4b97e564791d1decf2886a0dbe9b92b2176d76156adbb42b4c06c0f33d7107b270c207cbcfe0b2293b7cc4a0ec6774ac6d37af9503d51e1 + languageName: node + linkType: hard + "is64bit@npm:^2.0.0": version: 2.0.0 resolution: "is64bit@npm:2.0.0" @@ -24918,6 +25545,16 @@ __metadata: languageName: node linkType: hard +"isomorphic-fetch@npm:^3.0.0": + version: 3.0.0 + resolution: "isomorphic-fetch@npm:3.0.0" + dependencies: + node-fetch: "npm:^2.6.1" + whatwg-fetch: "npm:^3.4.1" + checksum: 10c0/511b1135c6d18125a07de661091f5e7403b7640060355d2d704ce081e019bc1862da849482d079ce5e2559b8976d3de7709566063aec1b908369c0b98a2b075b + languageName: node + linkType: hard + "isomorphic-rslog@npm:0.0.4": version: 0.0.4 resolution: "isomorphic-rslog@npm:0.0.4" @@ -26712,6 +27349,7 @@ __metadata: "@hookform/resolvers": "npm:^3.9.0" "@inquirer/prompts": "npm:^4.3.0" "@justaname.id/address-resolution": "npm:^1.1.0" + "@million/lint": "npm:^1.0.13" "@nx/cypress": "npm:19.7.3" "@nx/eslint": "npm:19.7.3" "@nx/eslint-plugin": "npm:19.7.3" @@ -29029,6 +29667,13 @@ __metadata: languageName: node linkType: hard +"mitt@npm:^3.0.0": + version: 3.0.1 + resolution: "mitt@npm:3.0.1" + checksum: 10c0/3ab4fdecf3be8c5255536faa07064d05caa3dd332bd318ff02e04621f7b3069ca1de9106cfe8e7ced675abfc2bec2ce4c4ef321c4a1bb1fb29df8ae090741913 + languageName: node + linkType: hard + "mkdirp@npm:1.0.4, mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" @@ -29228,6 +29873,15 @@ __metadata: languageName: node linkType: hard +"nanoid@npm:^5.0.7": + version: 5.0.9 + resolution: "nanoid@npm:5.0.9" + bin: + nanoid: bin/nanoid.js + checksum: 10c0/a2d9710525d4998a8a1610bbe6eb9a92c254ebab7c567c1ab429046fe7eed9c4df3508b59fb44c58ffdc98edb28dd6f953715c14b64ea0a3a2ce37420cdfeefd + languageName: node + linkType: hard + "napi-wasm@npm:^1.1.0": version: 1.1.3 resolution: "napi-wasm@npm:1.1.3" @@ -30941,6 +31595,13 @@ __metadata: languageName: node linkType: hard +"parse-ms@npm:^3.0.0": + version: 3.0.0 + resolution: "parse-ms@npm:3.0.0" + checksum: 10c0/056b4a32a9d3749f3f4cfffefb45c45540491deaa8e1d8ad43c2ddde7ba04edd076bd1b298f521238bb5fb084a9b2c4a2ebb78aefa651afbc4c2b0af4232fc54 + languageName: node + linkType: hard + "parse-ms@npm:^4.0.0": version: 4.0.0 resolution: "parse-ms@npm:4.0.0" @@ -31405,6 +32066,18 @@ __metadata: languageName: node linkType: hard +"piscina@npm:^4.4.0": + version: 4.8.0 + resolution: "piscina@npm:4.8.0" + dependencies: + "@napi-rs/nice": "npm:^1.0.1" + dependenciesMeta: + "@napi-rs/nice": + optional: true + checksum: 10c0/963ee0dc0862e936c88357b21b0b4fa32407ab21e9600756504411f368dcfae7478c8a19e13d0dd8afed56a8252a8e5967ee4413aa33dd436751b7ee2804531e + languageName: node + linkType: hard + "pkg-dir@npm:^3.0.0": version: 3.0.0 resolution: "pkg-dir@npm:3.0.0" @@ -32528,6 +33201,15 @@ __metadata: languageName: node linkType: hard +"pretty-ms@npm:8.0.0": + version: 8.0.0 + resolution: "pretty-ms@npm:8.0.0" + dependencies: + parse-ms: "npm:^3.0.0" + checksum: 10c0/e960d633ecca45445cf5c6dffc0f5e4bef6744c92449ab0e8c6c704800675ab71e181c5e02ece5265e02137a33e313d3f3e355fbf8ea30b4b5b23de423329f8d + languageName: node + linkType: hard + "pretty-ms@npm:^9.0.0": version: 9.1.0 resolution: "pretty-ms@npm:9.1.0" @@ -32889,7 +33571,16 @@ __metadata: languageName: node linkType: hard -"pure-rand@npm:^6.0.0": +"pupa@npm:^2.1.1": + version: 2.1.1 + resolution: "pupa@npm:2.1.1" + dependencies: + escape-goat: "npm:^2.0.0" + checksum: 10c0/d2346324780ebae4be847cad052b830e004d816851dd4750fc73faa6cd360f443e358f6b1c83641fd4c904c6055dcb545807f55259a20a52ad86d9477746c724 + languageName: node + linkType: hard + +"pure-rand@npm:^6.0.0, pure-rand@npm:^6.1.0": version: 6.1.0 resolution: "pure-rand@npm:6.1.0" checksum: 10c0/1abe217897bf74dcb3a0c9aba3555fe975023147b48db540aa2faf507aee91c03bf54f6aef0eb2bf59cc259a16d06b28eca37f0dc426d94f4692aeff02fb0e65 @@ -33507,6 +34198,21 @@ __metadata: languageName: node linkType: hard +"react-scan@npm:^0.0.31": + version: 0.0.31 + resolution: "react-scan@npm:0.0.31" + dependencies: + "@clack/core": "npm:^0.3.5" + "@clack/prompts": "npm:^0.8.2" + kleur: "npm:^4.1.5" + mri: "npm:^1.2.0" + playwright: "npm:^1.49.0" + bin: + react-scan: bin/cli.js + checksum: 10c0/4235909e20a3f096382c96e108c293dfd9369e4311a02661adeab366a9964a8cf238ff7bfab5a4ec59cc022e5ecd157acb8e445a4d7120f30ee06421dd82613f + languageName: node + linkType: hard + "react-scan@npm:^0.0.35": version: 0.0.35 resolution: "react-scan@npm:0.0.35" @@ -33806,7 +34512,7 @@ __metadata: languageName: node linkType: hard -"recast@npm:^0.23.1, recast@npm:^0.23.3, recast@npm:^0.23.5": +"recast@npm:^0.23.1, recast@npm:^0.23.3, recast@npm:^0.23.5, recast@npm:^0.23.9": version: 0.23.9 resolution: "recast@npm:0.23.9" dependencies: @@ -33971,6 +34677,24 @@ __metadata: languageName: node linkType: hard +"registry-auth-token@npm:^5.0.1": + version: 5.0.3 + resolution: "registry-auth-token@npm:5.0.3" + dependencies: + "@pnpm/npm-conf": "npm:^2.1.0" + checksum: 10c0/f92313032fae7dca787aa878cc7fa8499ee5da960802777f6b9f168a5d8f24a97fcfa0cf30a604bcf38b050a5db5f034b1e2fec18a3326f41822a6aff9514c85 + languageName: node + linkType: hard + +"registry-url@npm:^5.1.0": + version: 5.1.0 + resolution: "registry-url@npm:5.1.0" + dependencies: + rc: "npm:^1.2.8" + checksum: 10c0/c2c455342b5836cbed5162092eba075c7a02c087d9ce0fde8aeb4dc87a8f4a34a542e58bf4d8ec2d4cb73f04408cb3148ceb1f76647f76b978cfec22047dc6d6 + languageName: node + linkType: hard + "regjsgen@npm:^0.8.0": version: 0.8.0 resolution: "regjsgen@npm:0.8.0" @@ -34572,6 +35296,24 @@ __metadata: languageName: node linkType: hard +"rrdom@npm:^0.1.7": + version: 0.1.7 + resolution: "rrdom@npm:0.1.7" + dependencies: + rrweb-snapshot: "npm:^2.0.0-alpha.4" + checksum: 10c0/2e06c90f1e3d8a329edb9526ceaf25f2ca09b4a8dffd171577751a94fdc0ec0e56ab899be1f8f775fd6bf76a1268507767a2aa336a6c1d8a189022909cde7726 + languageName: node + linkType: hard + +"rrdom@npm:^2.0.0-alpha.18": + version: 2.0.0-alpha.18 + resolution: "rrdom@npm:2.0.0-alpha.18" + dependencies: + rrweb-snapshot: "npm:^2.0.0-alpha.18" + checksum: 10c0/13770f81a475eff96d50bb74d313965a4e3d5b904b9a27dc43cb33fb92dac040fa5acd602db3a20de5366997a4cf3f55c635a5359e58bd26187ef074c0704fe5 + languageName: node + linkType: hard + "rrweb-cssom@npm:^0.6.0": version: 0.6.0 resolution: "rrweb-cssom@npm:0.6.0" @@ -34579,6 +35321,57 @@ __metadata: languageName: node linkType: hard +"rrweb-player@npm:1.0.0-alpha.4": + version: 1.0.0-alpha.4 + resolution: "rrweb-player@npm:1.0.0-alpha.4" + dependencies: + "@tsconfig/svelte": "npm:^1.0.0" + rrweb: "npm:^2.0.0-alpha.4" + checksum: 10c0/cde3a7e0505c97312bc8015bba91f7814770d1d08cff2c2cb3e7a9eaf6a8a2bcc40f5fe5a22a46a351f6992df49a4a1c8be2c85ef461c96d5dd2af69f4fbad75 + languageName: node + linkType: hard + +"rrweb-snapshot@npm:^2.0.0-alpha.16, rrweb-snapshot@npm:^2.0.0-alpha.18, rrweb-snapshot@npm:^2.0.0-alpha.4": + version: 2.0.0-alpha.18 + resolution: "rrweb-snapshot@npm:2.0.0-alpha.18" + dependencies: + postcss: "npm:^8.4.38" + checksum: 10c0/296996f50f8a9c5f5dad2f92cea8fcc670bf364e094db48592919cab8987cdc19ce2e7b9b20653c63160f924e733a213329e87ff092353d4a5364c0a3a66405c + languageName: node + linkType: hard + +"rrweb@npm:2.0.0-alpha.4": + version: 2.0.0-alpha.4 + resolution: "rrweb@npm:2.0.0-alpha.4" + dependencies: + "@rrweb/types": "npm:^2.0.0-alpha.4" + "@types/css-font-loading-module": "npm:0.0.7" + "@xstate/fsm": "npm:^1.4.0" + base64-arraybuffer: "npm:^1.0.1" + fflate: "npm:^0.4.4" + mitt: "npm:^3.0.0" + rrdom: "npm:^0.1.7" + rrweb-snapshot: "npm:^2.0.0-alpha.4" + checksum: 10c0/124de86bc4db3d3254309950a5fef1c0ed2ad283a4db5840c43eba8d4157738f1fd833e15c3201e6754aa0bec2e3f7ed7fdf7a5335262626e15691afc2cf4f24 + languageName: node + linkType: hard + +"rrweb@npm:^2.0.0-alpha.4": + version: 2.0.0-alpha.18 + resolution: "rrweb@npm:2.0.0-alpha.18" + dependencies: + "@rrweb/types": "npm:^2.0.0-alpha.18" + "@rrweb/utils": "npm:^2.0.0-alpha.18" + "@types/css-font-loading-module": "npm:0.0.7" + "@xstate/fsm": "npm:^1.4.0" + base64-arraybuffer: "npm:^1.0.1" + mitt: "npm:^3.0.0" + rrdom: "npm:^2.0.0-alpha.18" + rrweb-snapshot: "npm:^2.0.0-alpha.18" + checksum: 10c0/8f33a64f4648fbba1621ec4ec383ee909435a0621259cf1b38c88074b8e23c875a7837f7e403d176f8399ad25312f6632c16c0879618a327d4b1797f8c4b37b1 + languageName: node + linkType: hard + "run-applescript@npm:^7.0.0": version: 7.0.0 resolution: "run-applescript@npm:7.0.0" @@ -34852,6 +35645,15 @@ __metadata: languageName: node linkType: hard +"semver-diff@npm:^3.1.1": + version: 3.1.1 + resolution: "semver-diff@npm:3.1.1" + dependencies: + semver: "npm:^6.3.0" + checksum: 10c0/7d350f1450b9577d538ef866a9bc4cd97bfbf1f1d92070291495a31d0ec3aa808e826c223e5454ea9877cc06eaa886ffd71bb3a1f331b44bc210f9ff525c68d2 + languageName: node + linkType: hard + "semver-regex@npm:^4.0.5": version: 4.0.5 resolution: "semver-regex@npm:4.0.5" @@ -34897,7 +35699,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.6.3, semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3": +"semver@npm:7.6.3, semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.6.3": version: 7.6.3 resolution: "semver@npm:7.6.3" bin: @@ -35335,7 +36137,17 @@ __metadata: languageName: node linkType: hard -"socket.io-client@npm:^4.5.1": +"socket.io-adapter@npm:~2.5.2": + version: 2.5.5 + resolution: "socket.io-adapter@npm:2.5.5" + dependencies: + debug: "npm:~4.3.4" + ws: "npm:~8.17.1" + checksum: 10c0/04a5a2a9c4399d1b6597c2afc4492ab1e73430cc124ab02b09e948eabf341180b3866e2b61b5084cb899beb68a4db7c328c29bda5efb9207671b5cb0bc6de44e + languageName: node + linkType: hard + +"socket.io-client@npm:^4.5.1, socket.io-client@npm:^4.7.5": version: 4.8.1 resolution: "socket.io-client@npm:4.8.1" dependencies: @@ -35357,6 +36169,21 @@ __metadata: languageName: node linkType: hard +"socket.io@npm:^4.8.1": + version: 4.8.1 + resolution: "socket.io@npm:4.8.1" + dependencies: + accepts: "npm:~1.3.4" + base64id: "npm:~2.0.0" + cors: "npm:~2.8.5" + debug: "npm:~4.3.2" + engine.io: "npm:~6.6.0" + socket.io-adapter: "npm:~2.5.2" + socket.io-parser: "npm:~4.2.4" + checksum: 10c0/acf931a2bb235be96433b71da3d8addc63eeeaa8acabd33dc8d64e12287390a45f1e9f389a73cf7dc336961cd491679741b7a016048325c596835abbcc017ca9 + languageName: node + linkType: hard + "sockjs@npm:^0.3.24": version: 0.3.24 resolution: "sockjs@npm:0.3.24" @@ -36057,7 +36884,7 @@ __metadata: languageName: node linkType: hard -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: @@ -36549,6 +37376,13 @@ __metadata: languageName: node linkType: hard +"sugar-high@npm:^0.7.1": + version: 0.7.5 + resolution: "sugar-high@npm:0.7.5" + checksum: 10c0/0d898ce842bc4c7362bed5b302186a39bed320c251e193e185be6b6ba10b183321748fa9d30d2a89b242b7d3cbcdb8abc26c02d3279851a649c0532cbeddd582 + languageName: node + linkType: hard + "superstruct@npm:^1.0.3": version: 1.0.4 resolution: "superstruct@npm:1.0.4" @@ -37151,7 +37985,7 @@ __metadata: languageName: node linkType: hard -"tmp@npm:~0.2.1, tmp@npm:~0.2.3": +"tmp@npm:^0.2.3, tmp@npm:~0.2.1, tmp@npm:~0.2.3": version: 0.2.3 resolution: "tmp@npm:0.2.3" checksum: 10c0/3e809d9c2f46817475b452725c2aaa5d11985cf18d32a7a970ff25b568438e2c076c2e8609224feef3b7923fa9749b74428e3e634f6b8e520c534eef2fd24125 @@ -37963,6 +38797,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~6.20.0": + version: 6.20.0 + resolution: "undici-types@npm:6.20.0" + checksum: 10c0/68e659a98898d6a836a9a59e6adf14a5d799707f5ea629433e025ac90d239f75e408e2e5ff086afc3cace26f8b26ee52155293564593fbb4a2f666af57fc59bf + languageName: node + linkType: hard + "undici@npm:^5.8.1": version: 5.28.4 resolution: "undici@npm:5.28.4" @@ -38225,6 +39066,16 @@ __metadata: languageName: node linkType: hard +"unplugin@npm:^1.6.0": + version: 1.16.0 + resolution: "unplugin@npm:1.16.0" + dependencies: + acorn: "npm:^8.14.0" + webpack-virtual-modules: "npm:^0.6.2" + checksum: 10c0/547f6bd5ec1dd7411533e68e73c60d5e9527e68d52aa326442650d084866ed3307ac68719068abae23ceab09db197cad43b382a7e69c2d8ca338b27802392fed + languageName: node + linkType: hard + "unstorage@npm:^1.9.0": version: 1.12.0 resolution: "unstorage@npm:1.12.0" @@ -38325,6 +39176,30 @@ __metadata: languageName: node linkType: hard +"update-notifier-cjs@npm:^5.1.6": + version: 5.1.6 + resolution: "update-notifier-cjs@npm:5.1.6" + dependencies: + boxen: "npm:^5.0.0" + chalk: "npm:^4.1.0" + configstore: "npm:^5.0.1" + has-yarn: "npm:^2.1.0" + import-lazy: "npm:^2.1.0" + is-ci: "npm:^2.0.0" + is-installed-globally: "npm:^0.4.0" + is-npm: "npm:^5.0.0" + is-yarn-global: "npm:^0.3.0" + isomorphic-fetch: "npm:^3.0.0" + pupa: "npm:^2.1.1" + registry-auth-token: "npm:^5.0.1" + registry-url: "npm:^5.1.0" + semver: "npm:^7.3.7" + semver-diff: "npm:^3.1.1" + xdg-basedir: "npm:^4.0.0" + checksum: 10c0/339d9d8c049c2dc45979159b393e6037b9a935e1da3a0b772e1f42437a2fd372e9b5db12c98c2eef4c9a578922b214432085944935816dab06804ca29ab61d99 + languageName: node + linkType: hard + "uqr@npm:^0.1.2": version: 0.1.2 resolution: "uqr@npm:0.1.2" @@ -39520,7 +40395,7 @@ __metadata: languageName: node linkType: hard -"whatwg-fetch@npm:^3.0.0": +"whatwg-fetch@npm:^3.0.0, whatwg-fetch@npm:^3.4.1": version: 3.6.20 resolution: "whatwg-fetch@npm:3.6.20" checksum: 10c0/fa972dd14091321d38f36a4d062298df58c2248393ef9e8b154493c347c62e2756e25be29c16277396046d6eaa4b11bd174f34e6403fff6aaca9fb30fa1ff46d @@ -39696,6 +40571,15 @@ __metadata: languageName: node linkType: hard +"widest-line@npm:^3.1.0": + version: 3.1.0 + resolution: "widest-line@npm:3.1.0" + dependencies: + string-width: "npm:^4.0.0" + checksum: 10c0/b1e623adcfb9df35350dd7fc61295d6d4a1eaa65a406ba39c4b8360045b614af95ad10e05abf704936ed022569be438c4bfa02d6d031863c4166a238c301119f + languageName: node + linkType: hard + "wildcard@npm:^2.0.0": version: 2.0.1 resolution: "wildcard@npm:2.0.1" @@ -39919,6 +40803,13 @@ __metadata: languageName: node linkType: hard +"xdg-basedir@npm:^4.0.0": + version: 4.0.0 + resolution: "xdg-basedir@npm:4.0.0" + checksum: 10c0/1b5d70d58355af90363a4e0a51c992e77fc5a1d8de5822699c7d6e96a6afea9a1e048cb93312be6870f338ca45ebe97f000425028fa149c1e87d1b5b8b212a06 + languageName: node + linkType: hard + "xml-name-validator@npm:^4.0.0": version: 4.0.0 resolution: "xml-name-validator@npm:4.0.0" @@ -39985,6 +40876,13 @@ __metadata: languageName: node linkType: hard +"xycolors@npm:^0.1.2": + version: 0.1.2 + resolution: "xycolors@npm:0.1.2" + checksum: 10c0/a7dd439022f72e7d9c9ec335ccee5583dca63c2bdcc9aa64cd6b1f7de6d6e319fe01aa3c584241fd2f187be3ca30a5527682310493975357333afb6311c7cac1 + languageName: node + linkType: hard + "y18n@npm:^4.0.0": version: 4.0.3 resolution: "y18n@npm:4.0.3" @@ -40093,7 +40991,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.3.1, yargs@npm:^17.6.2": +"yargs@npm:^17.3.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: