├── embeddable ├── .gitignore └── embed.jsx ├── .gitignore ├── src ├── index.js ├── ReplyButton.jsx ├── RelayList.jsx ├── util.js ├── Thread.jsx ├── components.jsx ├── NoComment.jsx └── Editor.jsx ├── screenshot.png ├── .prettierrc.yaml ├── .github └── workflows │ ├── npm-publish.yml │ └── publish-embeddable.yml ├── package.json ├── README.md ├── .eslintrc.json └── yarn.lock /embeddable/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | *.css 3 | *.map 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | yarn-error.log 4 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export {NoComment} from './NoComment' 2 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fiatjaf/nocomment/HEAD/screenshot.png -------------------------------------------------------------------------------- /.prettierrc.yaml: -------------------------------------------------------------------------------- 1 | arrowParens: avoid 2 | bracketSpacing: false 3 | jsxBracketSameLine: false 4 | printWidth: 80 5 | proseWrap: preserve 6 | semi: false 7 | singleQuote: true 8 | trailingComma: none 9 | useTabs: false 10 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: publish npm package 2 | 3 | on: 4 | push: 5 | tags: [v*] 6 | 7 | jobs: 8 | publish-npm: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - uses: actions/setup-node@v3 13 | with: 14 | node-version: 18 15 | - run: yarn --ignore-engines 16 | - run: node build.js 17 | - uses: JS-DevTools/npm-publish@v1 18 | with: 19 | token: ${{ secrets.NPM_TOKEN }} 20 | greater-version-only: true 21 | -------------------------------------------------------------------------------- /.github/workflows/publish-embeddable.yml: -------------------------------------------------------------------------------- 1 | name: build and deploy to cloudflare pages 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | - run: yarn && yarn build && yarn embeddable-debug 12 | - uses: cloudflare/pages-action@v1 13 | with: 14 | apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} 15 | accountId: 444a281da7983eac7a37b9896aad917c 16 | projectName: nocomment 17 | directory: embeddable 18 | -------------------------------------------------------------------------------- /src/ReplyButton.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {GhostButton} from './components' 3 | 4 | const ChatBubbleIcon = () => ( 5 | 13 | 18 | 19 | ) 20 | 21 | const ReplyButton = ({onClick}) => { 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | export default ReplyButton 30 | -------------------------------------------------------------------------------- /embeddable/embed.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {createRoot} from 'react-dom/client' 3 | import {NoComment} from '../src/NoComment.jsx' 4 | 5 | const script = document.getElementById('nocomment') 6 | 7 | const relays = script.dataset.relays 8 | ? JSON.parse(script.dataset.relays) 9 | : ['wss://nostr.wine', 'wss://nostr.mom', 'wss://nostr-pub.wellorder.net'] 10 | const skip = script.dataset.skip || '/' 11 | const owner = script.dataset.owner || '' 12 | const customBase = script.dataset.customBase 13 | const placeholder = script.dataset.placeholder || '' 14 | const readonly = script.dataset.readonly === 'true' 15 | 16 | const container = document.createElement('div') 17 | container.style.width = '100%' 18 | script.parentNode.insertBefore(container, script) 19 | 20 | const root = createRoot(container) 21 | root.render( 22 | 30 | ) 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-nocomment", 3 | "version": "0.3.0", 4 | "description": "This is an embeddable Nostr comments widget that just works", 5 | "main": "lib/index.js", 6 | "module": "lib/index.js", 7 | "scripts": { 8 | "build": "node build.js", 9 | "embeddable-debug": "esbuild --bundle embeddable/embed.jsx --outfile=embeddable/embed.js --sourcemap", 10 | "embeddable": "esbuild --bundle embeddable/embed.jsx --outfile=embeddable/embed.js --minify" 11 | }, 12 | "author": [ 13 | "fiatjaf", 14 | "saiy2k" 15 | ], 16 | "license": "MIT", 17 | "repository": "https://github.com/fiatjaf/nocomment", 18 | "dependencies": { 19 | "@noble/hashes": "^1.5.0", 20 | "dayjs": "^1.11.6", 21 | "esbuild": "^0.17.0", 22 | "nostr-tools": "^2.10.1", 23 | "react": "^18.2.0", 24 | "react-dom": "^18.1.0", 25 | "styled-components": "^5.3.6", 26 | "use-debounce": "^8.0.4" 27 | }, 28 | "devDependencies": { 29 | "eslint": "^8.6.0", 30 | "eslint-plugin-babel": "^5.3.1", 31 | "eslint-plugin-react": "^7.28.0", 32 | "prettier": "^2.5.1" 33 | }, 34 | "peerDependencies": { 35 | "react": "^18.2.0" 36 | }, 37 | "files": [ 38 | "lib" 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /src/RelayList.jsx: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react' 2 | import {Info, GhostButton, DangerText} from './components' 3 | 4 | export const RelayList = ({setRelays, relays, selfName}) => { 5 | const [r, setR] = useState('') 6 | return ( 7 | 8 | Commenting{' '} 9 | {selfName !== '_' && ( 10 | <> 11 | as {selfName} 12 | 13 | )}{' '} 14 | using relays{' '} 15 | 50 |

51 | Powered by{' '} 52 | 61 | NoComment 62 | 63 | . 64 |

65 |
66 | ) 67 | } 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nocomment 2 | 3 | A Nostr-powered embeddable website comments widget that _just works_. 4 | 5 | [![](screenshot.png)](https://fiatjaf.com/nostr.html) 6 | 7 | ## Usage as an embeddable script 8 | 9 | Anywhere in your website you want to see the comment box, include 10 | 11 | ``` 12 | 13 | ``` 14 | 15 | You can pass special attributes to that `