Improve editor

This commit is contained in:
tezlm 2023-12-13 01:32:43 -08:00
parent 1ae824fa4b
commit 24e1a1a4c0
Signed by: tezlm
GPG key ID: 649733FCD94AFBBA
8 changed files with 250 additions and 761 deletions

View file

@ -13,25 +13,17 @@
"@solid-primitives/scheduled": "^1.4.1",
"@tanstack/solid-virtual": "^3.0.1",
"@tanstack/virtual-core": "^3.0.1",
"@tiptap/core": "^2.1.13",
"@tiptap/extension-document": "^2.1.13",
"@tiptap/extension-dropcursor": "^2.1.13",
"@tiptap/extension-gapcursor": "^2.1.13",
"@tiptap/extension-hard-break": "^2.1.13",
"@tiptap/extension-history": "^2.1.13",
"@tiptap/extension-mention": "^2.1.13",
"@tiptap/extension-paragraph": "^2.1.13",
"@tiptap/extension-placeholder": "^2.1.13",
"@tiptap/extension-text": "^2.1.13",
"@tiptap/pm": "^2.1.13",
"@tiptap/starter-kit": "^2.1.13",
"@tiptap/suggestion": "^2.1.13",
"i18next": "^23.7.8",
"marked": "^11.0.1",
"nanoid": "^5.0.4",
"prosemirror-autocomplete": "^0.4.3",
"prosemirror-history": "^1.3.2",
"prosemirror-keymap": "^1.2.2",
"prosemirror-model": "^1.19.4",
"prosemirror-state": "^1.4.3",
"prosemirror-view": "^1.32.6",
"sdk": "link:../sdk-ts",
"solid-js": "^1.8.7",
"tiptap-solid": "^0.1.8"
"solid-js": "^1.8.7"
},
"devDependencies": {
"sass": "^1.69.5",

View file

@ -20,45 +20,6 @@ dependencies:
'@tanstack/virtual-core':
specifier: ^3.0.1
version: 3.0.1
'@tiptap/core':
specifier: ^2.1.13
version: 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/extension-document':
specifier: ^2.1.13
version: 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-dropcursor':
specifier: ^2.1.13
version: 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
'@tiptap/extension-gapcursor':
specifier: ^2.1.13
version: 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
'@tiptap/extension-hard-break':
specifier: ^2.1.13
version: 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-history':
specifier: ^2.1.13
version: 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
'@tiptap/extension-mention':
specifier: ^2.1.13
version: 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)(@tiptap/suggestion@2.1.13)
'@tiptap/extension-paragraph':
specifier: ^2.1.13
version: 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-placeholder':
specifier: ^2.1.13
version: 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
'@tiptap/extension-text':
specifier: ^2.1.13
version: 2.1.13(@tiptap/core@2.1.13)
'@tiptap/pm':
specifier: ^2.1.13
version: 2.1.13
'@tiptap/starter-kit':
specifier: ^2.1.13
version: 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/suggestion':
specifier: ^2.1.13
version: 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
i18next:
specifier: ^23.7.8
version: 23.7.8
@ -68,15 +29,30 @@ dependencies:
nanoid:
specifier: ^5.0.4
version: 5.0.4
prosemirror-autocomplete:
specifier: ^0.4.3
version: 0.4.3
prosemirror-history:
specifier: ^1.3.2
version: 1.3.2
prosemirror-keymap:
specifier: ^1.2.2
version: 1.2.2
prosemirror-model:
specifier: ^1.19.4
version: 1.19.4
prosemirror-state:
specifier: ^1.4.3
version: 1.4.3
prosemirror-view:
specifier: ^1.32.6
version: 1.32.6
sdk:
specifier: link:../sdk-ts
version: link:../sdk-ts
solid-js:
specifier: ^1.8.7
version: 1.8.7
tiptap-solid:
specifier: ^0.1.8
version: 0.1.8(@tiptap/core@2.1.13)(@tiptap/extension-bubble-menu@2.1.13)(@tiptap/extension-floating-menu@2.1.13)(solid-js@1.8.7)
devDependencies:
sass:
@ -678,34 +654,6 @@ packages:
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
dev: false
/@remirror/core-constants@2.0.2:
resolution: {integrity: sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==}
dev: false
/@remirror/core-helpers@3.0.0:
resolution: {integrity: sha512-tusEgQJIqg4qKj6HSBUFcyRnWnziw3neh4T9wOmsPGHFC3w9kl5KSrDb9UAgE8uX6y32FnS7vJ955mWOl3n50A==}
dependencies:
'@remirror/core-constants': 2.0.2
'@remirror/types': 1.0.1
'@types/object.omit': 3.0.3
'@types/object.pick': 1.3.4
'@types/throttle-debounce': 2.1.0
case-anything: 2.1.13
dash-get: 1.0.2
deepmerge: 4.3.1
fast-deep-equal: 3.1.3
make-error: 1.3.6
object.omit: 3.0.0
object.pick: 1.3.0
throttle-debounce: 3.0.1
dev: false
/@remirror/types@1.0.1:
resolution: {integrity: sha512-VlZQxwGnt1jtQ18D6JqdIF+uFZo525WEqrfp9BOc3COPpK4+AWCgdnAWL+ho6imWcoINlGjR/+3b6y5C1vBVEA==}
dependencies:
type-fest: 2.19.0
dev: false
/@rollup/rollup-android-arm-eabi@4.7.0:
resolution: {integrity: sha512-rGku10pL1StFlFvXX5pEv88KdGW6DHUghsxyP/aRYb9eH+74jTGJ3U0S/rtlsQ4yYq1Hcc7AMkoJOb1xu29Fxw==}
cpu: [arm]
@ -835,271 +783,6 @@ packages:
resolution: {integrity: sha512-By6TTR3u6rmAWRD7STXqI8WP9q1jYrqVCz88lNTgOf/cUm5cNF6Uj7dej/1+LUj42KMwFusyxGS908HlGBhE2Q==}
dev: false
/@tiptap/core@2.1.13(@tiptap/pm@2.1.13):
resolution: {integrity: sha512-cMC8bgTN63dj1Mv82iDeeLl6sa9kY0Pug8LSalxVEptRmyFVsVxGgu2/6Y3T+9aCYScxfS06EkA8SdzFMAwYTQ==}
peerDependencies:
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/pm': 2.1.13
dev: false
/@tiptap/extension-blockquote@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-oe6wSQACmODugoP9XH3Ouffjy4BsOBWfTC+dETHNCG6ZED6ShHN3CB9Vr7EwwRgmm2WLaKAjMO1sVumwH+Z1rg==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-bold@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-6cHsQTh/rUiG4jkbJer3vk7g60I5tBwEBSGpdxmEHh83RsvevD8+n92PjA24hYYte5RNlATB011E1wu8PVhSvw==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-bubble-menu@2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13):
resolution: {integrity: sha512-Hm7e1GX3AI6lfaUmr6WqsS9MMyXIzCkhh+VQi6K8jj4Q4s8kY4KPoAyD/c3v9pZ/dieUtm2TfqrOCkbHzsJQBg==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/pm': 2.1.13
tippy.js: 6.3.7
dev: false
/@tiptap/extension-bullet-list@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-NkWlQ5bLPUlcROj6G/d4oqAxMf3j3wfndGOPp0z8OoXJtVbVoXl/aMSlLbVgE6n8r6CS8MYxKhXNxrb7Ll2foA==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-code-block@2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13):
resolution: {integrity: sha512-E3tweNExPOV+t1ODKX0MDVsS0aeHGWc1ECt+uyp6XwzsN0bdF2A5+pttQqM7sTcMnQkVACGFbn9wDeLRRcfyQg==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/pm': 2.1.13
dev: false
/@tiptap/extension-code@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-f5fLYlSgliVVa44vd7lQGvo49+peC+Z2H0Fn84TKNCH7tkNZzouoJsHYn0/enLaQ9Sq+24YPfqulfiwlxyiT8w==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-document@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-wLwiTWsVmZTGIE5duTcHRmW4ulVxNW4nmgfpk95+mPn1iKyNGtrVhGWleLhBlTj+DWXDtcfNWZgqZkZNzhkqYQ==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-dropcursor@2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13):
resolution: {integrity: sha512-NAyJi4BJxH7vl/2LNS1X0ndwFKjEtX+cRgshXCnMyh7qNpIRW6Plczapc/W1OiMncOEhZJfpZfkRSfwG01FWFg==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/pm': 2.1.13
dev: false
/@tiptap/extension-floating-menu@2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13):
resolution: {integrity: sha512-9Oz7pk1Nts2+EyY+rYfnREGbLzQ5UFazAvRhF6zAJdvyuDmAYm0Jp6s0GoTrpV0/dJEISoFaNpPdMJOb9EBNRw==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/pm': 2.1.13
tippy.js: 6.3.7
dev: false
/@tiptap/extension-gapcursor@2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13):
resolution: {integrity: sha512-Cl5apsoTcyPPCgE3ThufxQxZ1wyqqh+9uxUN9VF9AbeTkid6oPZvKXwaILf6AFnkSy+SuKrb9kZD2iaezxpzXw==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/pm': 2.1.13
dev: false
/@tiptap/extension-hard-break@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-TGkMzMQayuKg+vN4du0x1ahEItBLcCT1jdWeRsjdM8gHfzbPLdo4PQhVsvm1I0xaZmbJZelhnVsUwRZcIu1WNA==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-heading@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-PEmc19QLmlVUTiHWoF0hpgNTNPNU0nlaFmMKskzO+cx5Df4xvHmv/UqoIwp7/UFbPMkfVJT1ozQU7oD1IWn9Hg==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-history@2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13):
resolution: {integrity: sha512-1ouitThGTBUObqw250aDwGLMNESBH5PRXIGybsCFO1bktdmWtEw7m72WY41EuX2BH8iKJpcYPerl3HfY1vmCNw==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/pm': 2.1.13
dev: false
/@tiptap/extension-horizontal-rule@2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13):
resolution: {integrity: sha512-7OgjgNqZXvBejgULNdMSma2M1nzv4bbZG+FT5XMFZmEOxR9IB1x/RzChjPdeicff2ZK2sfhMBc4Y9femF5XkUg==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/pm': 2.1.13
dev: false
/@tiptap/extension-italic@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-HyDJfuDn5hzwGKZiANcvgz6wcum6bEgb4wmJnfej8XanTMJatNVv63TVxCJ10dSc9KGpPVcIkg6W8/joNXIEbw==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-list-item@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-6e8iiCWXOiJTl1XOwVW2tc0YG18h70HUtEHFCx2m5HspOGFKsFEaSS3qYxOheM9HxlmQeDt8mTtqftRjEFRxPQ==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-mention@2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)(@tiptap/suggestion@2.1.13):
resolution: {integrity: sha512-OYqaucyBiCN/CmDYjpOVX74RJcIEKmAqiZxUi8Gfaq7ryEO5a8Gk93nK+8uZ0onaqHE+mHpoLFFbcAFbOPgkUQ==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
'@tiptap/suggestion': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/pm': 2.1.13
'@tiptap/suggestion': 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-ordered-list@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-UO4ZAL5Vrr1WwER5VjgmeNIWHpqy9cnIRo1En07gZ0OWTjs1eITPcu+4TCn1ZG6DhoFvAQzE5DTxxdhIotg+qw==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-paragraph@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-cEoZBJrsQn69FPpUMePXG/ltGXtqKISgypj70PEHXt5meKDjpmMVSY4/8cXvFYEYsI9GvIwyAK0OrfAHiSoROA==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-placeholder@2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13):
resolution: {integrity: sha512-vIY7y7UbqsrAW/y8bDE9eRenbQEU16kNHB5Wri8RU1YiUZpkPgdXP/pLqyjIIq95SwP/vdTIHjHoQ77VLRl1hA==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/pm': 2.1.13
dev: false
/@tiptap/extension-strike@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-VN6zlaCNCbyJUCDyBFxavw19XmQ4LkCh8n20M8huNqW77lDGXA2A7UcWLHaNBpqAijBRu9mWI8l4Bftyf2fcAw==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/extension-text@2.1.13(@tiptap/core@2.1.13):
resolution: {integrity: sha512-zzsTTvu5U67a8WjImi6DrmpX2Q/onLSaj+LRWPh36A1Pz2WaxW5asZgaS+xWCnR+UrozlCALWa01r7uv69jq0w==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
dev: false
/@tiptap/pm@2.1.13:
resolution: {integrity: sha512-zNbA7muWsHuVg12GrTgN/j119rLePPq5M8dZgkKxUwdw8VmU3eUyBp1SihPEXJ2U0MGdZhNhFX7Y74g11u66sg==}
dependencies:
prosemirror-changeset: 2.2.1
prosemirror-collab: 1.3.1
prosemirror-commands: 1.5.2
prosemirror-dropcursor: 1.8.1
prosemirror-gapcursor: 1.3.2
prosemirror-history: 1.3.2
prosemirror-inputrules: 1.3.0
prosemirror-keymap: 1.2.2
prosemirror-markdown: 1.11.2
prosemirror-menu: 1.2.4
prosemirror-model: 1.19.3
prosemirror-schema-basic: 1.2.2
prosemirror-schema-list: 1.3.0
prosemirror-state: 1.4.3
prosemirror-tables: 1.3.5
prosemirror-trailing-node: 2.0.7(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.6)
prosemirror-transform: 1.8.0
prosemirror-view: 1.32.6
dev: false
/@tiptap/starter-kit@2.1.13(@tiptap/pm@2.1.13):
resolution: {integrity: sha512-ph/mUR/OwPtPkZ5rNHINxubpABn8fHnvJSdhXFrY/q6SKoaO11NZXgegRaiG4aL7O6Sz4LsZVw6Sm0Ae+GJmrg==}
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/extension-blockquote': 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-bold': 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-bullet-list': 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-code': 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-code-block': 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
'@tiptap/extension-document': 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-dropcursor': 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
'@tiptap/extension-gapcursor': 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
'@tiptap/extension-hard-break': 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-heading': 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-history': 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
'@tiptap/extension-horizontal-rule': 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
'@tiptap/extension-italic': 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-list-item': 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-ordered-list': 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-paragraph': 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-strike': 2.1.13(@tiptap/core@2.1.13)
'@tiptap/extension-text': 2.1.13(@tiptap/core@2.1.13)
transitivePeerDependencies:
- '@tiptap/pm'
dev: false
/@tiptap/suggestion@2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13):
resolution: {integrity: sha512-Y05TsiXTFAJ5SrfoV+21MAxig5UNbY0AVa03lQlh/yicTRPpIc6hgZzblB0uxDSYoj6+kaHE4MIZvPvhUD8BJQ==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/pm': 2.1.13
dev: false
/@types/babel__core@7.20.5:
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
dependencies:
@ -1129,18 +812,6 @@ packages:
'@babel/types': 7.23.5
dev: true
/@types/object.omit@3.0.3:
resolution: {integrity: sha512-xrq4bQTBGYY2cw+gV4PzoG2Lv3L0pjZ1uXStRRDQoATOYW1lCsFQHhQ+OkPhIcQoqLjAq7gYif7D14Qaa6Zbew==}
dev: false
/@types/object.pick@1.3.4:
resolution: {integrity: sha512-5PjwB0uP2XDp3nt5u5NJAG2DORHIRClPzWT/TTZhJ2Ekwe8M5bA9tvPdi9NO/n2uvu2/ictat8kgqvLfcIE1SA==}
dev: false
/@types/throttle-debounce@2.1.0:
resolution: {integrity: sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ==}
dev: false
/ansi-styles@3.2.1:
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
engines: {node: '>=4'}
@ -1156,10 +827,6 @@ packages:
picomatch: 2.3.1
dev: true
/argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: false
/babel-plugin-jsx-dom-expressions@0.37.9(@babel/core@7.23.5):
resolution: {integrity: sha512-6w+zs2i14fVanj4e1hXCU5cp+x0U0LJ5jScknpMZZUteHhwFRGJflHMVJ+xAcW7ku41FYjr7DgtK9mnc2SXlJg==}
peerDependencies:
@ -1209,11 +876,6 @@ packages:
resolution: {integrity: sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==}
dev: true
/case-anything@2.1.13:
resolution: {integrity: sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==}
engines: {node: '>=12.13'}
dev: false
/chalk@2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
engines: {node: '>=4'}
@ -1252,17 +914,9 @@ packages:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
dev: true
/crelt@1.0.6:
resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==}
dev: false
/csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
/dash-get@1.0.2:
resolution: {integrity: sha512-4FbVrHDwfOASx7uQVxeiCTo7ggSdYZbqs8lH+WU6ViypPlDbe9y6IP5VVUDQBv9DcnyaiPT5XT0UWHgJ64zLeQ==}
dev: false
/debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
@ -1275,20 +929,10 @@ packages:
ms: 2.1.2
dev: true
/deepmerge@4.3.1:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
dev: false
/electron-to-chromium@1.4.609:
resolution: {integrity: sha512-ihiCP7PJmjoGNuLpl7TjNA8pCQWu09vGyjlPYw1Rqww4gvNuCcmvl+44G+2QyJ6S2K4o+wbTS++Xz0YN8Q9ERw==}
dev: true
/entities@3.0.1:
resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==}
engines: {node: '>=0.12'}
dev: false
/esbuild@0.19.8:
resolution: {integrity: sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w==}
engines: {node: '>=12'}
@ -1329,15 +973,6 @@ packages:
engines: {node: '>=0.8.0'}
dev: true
/escape-string-regexp@4.0.0:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
dev: false
/fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
dev: false
/fill-range@7.0.1:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
@ -1396,13 +1031,6 @@ packages:
binary-extensions: 2.2.0
dev: true
/is-extendable@1.0.1:
resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==}
engines: {node: '>=0.10.0'}
dependencies:
is-plain-object: 2.0.4
dev: false
/is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@ -1420,23 +1048,11 @@ packages:
engines: {node: '>=0.12.0'}
dev: true
/is-plain-object@2.0.4:
resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
engines: {node: '>=0.10.0'}
dependencies:
isobject: 3.0.1
dev: false
/is-what@4.1.16:
resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
engines: {node: '>=12.13'}
dev: true
/isobject@3.0.1:
resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
engines: {node: '>=0.10.0'}
dev: false
/js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
dev: true
@ -1453,43 +1069,18 @@ packages:
hasBin: true
dev: true
/linkify-it@4.0.1:
resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==}
dependencies:
uc.micro: 1.0.6
dev: false
/lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
dependencies:
yallist: 3.1.1
dev: true
/make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
dev: false
/markdown-it@13.0.2:
resolution: {integrity: sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==}
hasBin: true
dependencies:
argparse: 2.0.1
entities: 3.0.1
linkify-it: 4.0.1
mdurl: 1.0.1
uc.micro: 1.0.6
dev: false
/marked@11.0.1:
resolution: {integrity: sha512-P4kDhFEMlvLePBPRwOcMOv6+lYUbhfbSxJFs3Jb4Qx7v6K7l+k8Dxh9CEGfRvK71tL+qIFz5y7Pe4uzt4+/A3A==}
engines: {node: '>= 18'}
hasBin: true
dev: false
/mdurl@1.0.1:
resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
dev: false
/merge-anything@5.1.7:
resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==}
engines: {node: '>=12.13'}
@ -1522,20 +1113,6 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/object.omit@3.0.0:
resolution: {integrity: sha512-EO+BCv6LJfu+gBIF3ggLicFebFLN5zqzz/WWJlMFfkMyGth+oBkhxzDl0wx2W4GkLzuQs/FsSkXZb2IMWQqmBQ==}
engines: {node: '>=0.10.0'}
dependencies:
is-extendable: 1.0.1
dev: false
/object.pick@1.3.0:
resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==}
engines: {node: '>=0.10.0'}
dependencies:
isobject: 3.0.1
dev: false
/orderedmap@2.1.1:
resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==}
dev: false
@ -1558,39 +1135,10 @@ packages:
source-map-js: 1.0.2
dev: true
/prosemirror-changeset@2.2.1:
resolution: {integrity: sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==}
/prosemirror-autocomplete@0.4.3:
resolution: {integrity: sha512-a4w/SOzgrTjXaWpSYMrai6H3KHSUBuADZC/DBm4VApiD9LGHpv98zQbHzsHgInrEoWcBGzYVT0HUD3tLgrsEVQ==}
dependencies:
prosemirror-transform: 1.8.0
dev: false
/prosemirror-collab@1.3.1:
resolution: {integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==}
dependencies:
prosemirror-state: 1.4.3
dev: false
/prosemirror-commands@1.5.2:
resolution: {integrity: sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==}
dependencies:
prosemirror-model: 1.19.3
prosemirror-state: 1.4.3
prosemirror-transform: 1.8.0
dev: false
/prosemirror-dropcursor@1.8.1:
resolution: {integrity: sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==}
dependencies:
prosemirror-state: 1.4.3
prosemirror-transform: 1.8.0
prosemirror-view: 1.32.6
dev: false
/prosemirror-gapcursor@1.3.2:
resolution: {integrity: sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==}
dependencies:
prosemirror-keymap: 1.2.2
prosemirror-model: 1.19.3
prosemirror-inputrules: 1.3.0
prosemirror-state: 1.4.3
prosemirror-view: 1.32.6
dev: false
@ -1618,85 +1166,30 @@ packages:
w3c-keyname: 2.2.8
dev: false
/prosemirror-markdown@1.11.2:
resolution: {integrity: sha512-Eu5g4WPiCdqDTGhdSsG9N6ZjACQRYrsAkrF9KYfdMaCmjIApH75aVncsWYOJvEk2i1B3i8jZppv3J/tnuHGiUQ==}
dependencies:
markdown-it: 13.0.2
prosemirror-model: 1.19.3
dev: false
/prosemirror-menu@1.2.4:
resolution: {integrity: sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==}
dependencies:
crelt: 1.0.6
prosemirror-commands: 1.5.2
prosemirror-history: 1.3.2
prosemirror-state: 1.4.3
dev: false
/prosemirror-model@1.19.3:
resolution: {integrity: sha512-tgSnwN7BS7/UM0sSARcW+IQryx2vODKX4MI7xpqY2X+iaepJdKBPc7I4aACIsDV/LTaTjt12Z56MhDr9LsyuZQ==}
/prosemirror-model@1.19.4:
resolution: {integrity: sha512-RPmVXxUfOhyFdayHawjuZCxiROsm9L4FCUA6pWI+l7n2yCBsWy9VpdE1hpDHUS8Vad661YLY9AzqfjLhAKQ4iQ==}
dependencies:
orderedmap: 2.1.1
dev: false
/prosemirror-schema-basic@1.2.2:
resolution: {integrity: sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw==}
dependencies:
prosemirror-model: 1.19.3
dev: false
/prosemirror-schema-list@1.3.0:
resolution: {integrity: sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A==}
dependencies:
prosemirror-model: 1.19.3
prosemirror-state: 1.4.3
prosemirror-transform: 1.8.0
dev: false
/prosemirror-state@1.4.3:
resolution: {integrity: sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==}
dependencies:
prosemirror-model: 1.19.3
prosemirror-model: 1.19.4
prosemirror-transform: 1.8.0
prosemirror-view: 1.32.6
dev: false
/prosemirror-tables@1.3.5:
resolution: {integrity: sha512-JSZ2cCNlApu/ObAhdPyotrjBe2cimniniTpz60YXzbL0kZ+47nEYk2LWbfKU2lKpBkUNquta2PjteoNi4YCluQ==}
dependencies:
prosemirror-keymap: 1.2.2
prosemirror-model: 1.19.3
prosemirror-state: 1.4.3
prosemirror-transform: 1.8.0
prosemirror-view: 1.32.6
dev: false
/prosemirror-trailing-node@2.0.7(prosemirror-model@1.19.3)(prosemirror-state@1.4.3)(prosemirror-view@1.32.6):
resolution: {integrity: sha512-8zcZORYj/8WEwsGo6yVCRXFMOfBo0Ub3hCUvmoWIZYfMP26WqENU0mpEP27w7mt8buZWuGrydBewr0tOArPb1Q==}
peerDependencies:
prosemirror-model: ^1.19.0
prosemirror-state: ^1.4.2
prosemirror-view: ^1.31.2
dependencies:
'@remirror/core-constants': 2.0.2
'@remirror/core-helpers': 3.0.0
escape-string-regexp: 4.0.0
prosemirror-model: 1.19.3
prosemirror-state: 1.4.3
prosemirror-view: 1.32.6
dev: false
/prosemirror-transform@1.8.0:
resolution: {integrity: sha512-BaSBsIMv52F1BVVMvOmp1yzD3u65uC3HTzCBQV1WDPqJRQ2LuHKcyfn0jwqodo8sR9vVzMzZyI+Dal5W9E6a9A==}
dependencies:
prosemirror-model: 1.19.3
prosemirror-model: 1.19.4
dev: false
/prosemirror-view@1.32.6:
resolution: {integrity: sha512-26r5LvyDlPgUNVf7ZdNdGrMJnylwjJtUJTfDuYOANIVx9lqWD1WCBlGg283weYQGKUC64DXR25LeAmliB9CrFQ==}
dependencies:
prosemirror-model: 1.19.3
prosemirror-model: 1.19.4
prosemirror-state: 1.4.3
prosemirror-transform: 1.8.0
dev: false
@ -1785,31 +1278,6 @@ packages:
has-flag: 3.0.0
dev: true
/throttle-debounce@3.0.1:
resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==}
engines: {node: '>=10'}
dev: false
/tippy.js@6.3.7:
resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==}
dependencies:
'@popperjs/core': 2.11.8
dev: false
/tiptap-solid@0.1.8(@tiptap/core@2.1.13)(@tiptap/extension-bubble-menu@2.1.13)(@tiptap/extension-floating-menu@2.1.13)(solid-js@1.8.7):
resolution: {integrity: sha512-gUFkp9CxNVqrUkXkra3PN2NQhJoQ+wch2aJSUHE0vDW/1FloPB8Rz+P4K7RUxS0D++R3dhn0cY2dpzcZN+VXTw==}
peerDependencies:
'@tiptap/core': ^2.0.0-beta.125
'@tiptap/extension-bubble-menu': ^2.0.0-beta.42
'@tiptap/extension-floating-menu': ^2.0.0-beta.36
solid-js: ^1.1.6
dependencies:
'@tiptap/core': 2.1.13(@tiptap/pm@2.1.13)
'@tiptap/extension-bubble-menu': 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
'@tiptap/extension-floating-menu': 2.1.13(@tiptap/core@2.1.13)(@tiptap/pm@2.1.13)
solid-js: 1.8.7
dev: false
/to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
@ -1822,21 +1290,12 @@ packages:
is-number: 7.0.0
dev: true
/type-fest@2.19.0:
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
engines: {node: '>=12.20'}
dev: false
/typescript@5.3.3:
resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==}
engines: {node: '>=14.17'}
hasBin: true
dev: true
/uc.micro@1.0.6:
resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==}
dev: false
/update-browserslist-db@1.0.13(browserslist@4.22.2):
resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
hasBin: true

View file

@ -314,13 +314,15 @@
bottom: 0;
left: 0;
width: 100%;
height: 72px;
min-height: 72px;
height: fit-content;
background: var(--background-2);
display: flex;
align-items: center;
padding: 0 8px;
padding: 8px;
gap: 8px;
border-top: solid var(--background-4) 1px;
box-shadow: 0 0 4px var(--background-4);
& > textarea {
background: var(--background-1);
@ -361,7 +363,8 @@
}
& > .spacer-bottom {
margin-top: 72px;
// margin-top: 72px; // same height as footer
margin-top: 80px;
}
& > .thread-title {

View file

@ -2,8 +2,11 @@
border: solid var(--background-3) 1px;
background: var(--background-1);
width: 100%;
min-height: calc(72px - 16px);
padding: 4px;
white-space: pre-wrap;
& .tiptap:focus {
&:focus {
outline: solid #4af 1px;
}
@ -11,22 +14,18 @@
background: #9ad5;
padding: 0 2px;
border-radius: 2px;
// user-select: none;
}
& p.is-editor-empty:first-child::before {
color: var(--foreground-1);
content: attr(data-placeholder);
float: left;
height: 0;
opacity: .3;
pointer-events: none;
}
& .syn {
& .syn, .placeholder {
color: #777;
}
& code {
& .placeholder {
position: absolute;
}
& code, pre {
font-family: "Iosevka Zesty", 'Courier New', Courier, monospace;
background: var(--background-3);
padding: 0 2px;

View file

@ -1,3 +1,185 @@
export function Editor() {
return <textarea />;
import { EditorState } from "prosemirror-state";
import { EditorView, Decoration, DecorationSet } from "prosemirror-view";
import { Schema, Slice } from "prosemirror-model";
import { history, undo, redo } from "prosemirror-history";
import { keymap } from "prosemirror-keymap";
import { autocomplete } from "prosemirror-autocomplete";
import "./Editor.scss";
import { VoidProps, createSignal, onCleanup, onMount } from "solid-js";
import { Token, marked } from "marked";
import { UserId } from "sdk/dist/src/api";
const schema = new Schema({
nodes: {
doc: {
content: "paragraph",
},
paragraph: {
content: "inline*",
whitespace: "pre",
toDOM: () => ["p", 0],
},
mention: {
group: "inline",
atom: true,
inline: true,
selectable: false,
attrs: {
user: {},
},
toDOM: (n) => ["span", { "data-mention": n.attrs.user }, n.attrs.user],
},
text: {
group: "inline",
inline: true,
},
},
});
function Autocomplete(props: VoidProps<{ options: Array<UserId> }>) {
return (
<ul>
{props.options.map(i => <li>{i}</li>)}
</ul>
)
}
export function Editor(props: VoidProps<{ onSubmit: (text: string) => void }>) {
let editorEl: HTMLDivElement;
const [autocompleteOptions, setAutocompleteOptions] = createSignal<null | Array<string>>(null);
const items = [
"@foobar:celery.eu.org",
"@foobaz:celery.eu.org",
"@foobarbaz:celery.eu.org",
];
onMount(() => {
const view = new EditorView({ mount: editorEl }, {
state: EditorState.create({
schema,
plugins: [
history(),
...autocomplete({
triggers: [
// { name: "mention", trigger: "@" },
// { name: "room", trigger: "##" },
// { name: "thread", trigger: "#" },
// { name: "emoji", trigger: ":" },
// { name: "command", trigger: "/" },
],
onOpen(action) {
setAutocompleteOptions(items);
return true;
},
onFilter(action) {
setAutocompleteOptions(action.filter ? items.filter(name => name.includes(action.filter!)) : items);
return true;
},
onClose() {
setAutocompleteOptions(null);
return true;
},
onArrow(action) {
// console.log(action);
return true;
},
onEnter(action) {
setAutocompleteOptions(null);
const { state } = action.view;
const tr = state.tr.replaceRangeWith(action.range.from, action.range.to, state.schema.node("mention", { user: "@user:server.tld" }));
const newState = action.view.state.apply(tr);
action.view.updateState(newState);
return true;
}
}),
keymap({
"Ctrl-z": undo,
"Ctrl-Shift-z": redo,
"Ctrl-y": redo,
"Shift-Enter": (state, dispatch) => {
dispatch?.(state.tr.insertText("\n"));
return true;
},
"Enter": (state, dispatch) => {
if (state.doc.textContent.startsWith("---")) {
dispatch?.(state.tr.insertText("\n"));
} else {
// TODO: render properly?
props.onSubmit(state.doc.textContent);
// state.selection.content().content.firstChild?.type.name === "code";
// console.log("send", state.toJSON());
dispatch?.(state.tr.deleteRange(0, state.doc.nodeSize - 2));
}
return true;
},
}),
],
}),
decorations(state) {
if (state.doc.firstChild!.firstChild === null) {
const placeholder = <div class="placeholder">write something nice...</div> as HTMLDivElement;
return DecorationSet.create(state.doc, [Decoration.widget(0, placeholder)]);
}
const decorations: Array<Decoration> = [];
let pos = 0;
const walk = (ast: Token) => {
switch (ast.type) {
case "em": {
const end = pos + ast.raw.length + 1;
decorations.push(Decoration.inline(pos, pos + 2, { class: "syn" }));
decorations.push(Decoration.inline(pos + 2, end - 1, { nodeName: "em" }));
decorations.push(Decoration.inline(end - 1, end, { class: "syn" }));
break;
}
case "strong": {
const end = pos + ast.raw.length + 1;
decorations.push(Decoration.inline(pos, pos + 3, { class: "syn" }));
decorations.push(Decoration.inline(pos + 3, end - 2, { nodeName: "bold" }));
decorations.push(Decoration.inline(end - 2, end, { class: "syn" }));
break;
}
case "codespan": {
const end = pos + ast.raw.length + 1;
decorations.push(Decoration.inline(pos, pos + 2, { class: "syn" }));
decorations.push(Decoration.inline(pos + 2, end - 1, { nodeName: "code" }));
decorations.push(Decoration.inline(end - 1, end, { class: "syn" }));
break;
}
case "code": {
// const headIdx = ast.raw.indexOf("\n");
// const tailIdx = ast.raw.lastIndexOf("\n");
// const hasTail = ast.raw.endsWith("```");
// decorations.push(Decoration.inline(pos, headIdx === -1 ? ast.raw.length + pos + 1 : headIdx + pos + 1, { class: "syn" }));
// if (hasTail) {
// decorations.push(Decoration.inline(headIdx + pos + 2, tailIdx + pos + 1, { nodeName: "code" }));
// decorations.push(Decoration.inline(tailIdx + pos + 1, pos + ast.raw.length + 1, { class: "syn" }));
// } else if (headIdx !== -1) {
// decorations.push(Decoration.inline(headIdx + pos + 2, ast.raw.length + pos + 1, { nodeName: "code" }));
// }
// decorations.push(Decoration.node(pos, ast.raw.length + pos + 1, { nodeName: "pre" }));
break;
}
case "paragraph": ast.tokens?.forEach(walk); return;
// default: console.log(ast);
}
pos += ast.raw.length;
};
marked.lexer(state.doc.textContent).forEach(walk);
return DecorationSet.create(state.doc, decorations);
},
});
onCleanup(() => view.destroy());
});
return (
<>
<div class="editor" ref={editorEl!}></div>
{false && autocompleteOptions() && <Autocomplete options={autocompleteOptions()!} />}
</>
)
}

View file

@ -1,10 +1,11 @@
import { ParentProps, Show, VoidProps, createEffect, createResource, createSignal, onCleanup, onMount } from "solid-js";
import "./App.scss";
import { Client, Room, Thread, Timeline } from "sdk";
import { Client, Room, Thread } from "sdk";
import { Message, TextBlock, ThreadsItem } from "./Room";
import { computePosition, shift, offset, autoUpdate } from "@floating-ui/dom";
import { Portal } from "solid-js/web";
import { Time } from "./Atoms";
import { Editor } from "./Editor";
export function RoomView(props: VoidProps<{ room: Room }>) {
return (

View file

@ -1,6 +1,6 @@
import { For, ParentProps, Show, VoidProps, createEffect, createResource, createSignal, onCleanup, onMount } from "solid-js";
import "./App.scss";
import { Client, Room, Thread } from "sdk";
import { Client, Event, Room, Thread } from "sdk";
import { Message, TextBlock, ThreadsItem } from "./Room";
// import { computePosition, shift, offset, autoUpdate } from "@floating-ui/dom";
// import { Portal } from "solid-js/web";
@ -12,18 +12,11 @@ import { useGlobals } from "./Context";
// import { createVirtualizer } from "@tanstack/solid-virtual";
export function ThreadView(props: VoidProps<{ thread: Thread }>) {
let textareaEl: HTMLTextAreaElement;
function handleKeyDown(e: KeyboardEvent) {
if (e.key === "Enter" && !e.shiftKey) {
e.stopPropagation();
e.preventDefault();
props.thread.room.sendEvent("m.message", {
text: [{ body: textareaEl.value }],
"m.relations": [{ rel_type: "m.thread", event_id: props.thread.id }],
});
textareaEl.value = "";
}
function handleSubmit(text: string) {
props.thread.room.sendEvent("m.message", {
text: [{ body: text }],
"m.relations": [{ rel_type: "m.thread", event_id: props.thread.id }],
});
}
// updates when the thread changes
@ -100,6 +93,12 @@ export function ThreadView(props: VoidProps<{ thread: Thread }>) {
// </div>;
// })}
// </Show>
function shouldSplit(ev: Event, prev: Event) {
if (ev.sender !== prev.sender) return true;
if (ev.originTs - prev.originTs > 1000 * 60 * 5) return true;
return false;
}
return (
<div class="thread-view">
@ -109,14 +108,12 @@ export function ThreadView(props: VoidProps<{ thread: Thread }>) {
{false && (timeline.loading || isPaginating()) && new Array(5).fill(0).map(() => <div style="min-height:1rem;margin:8px;background:var(--background-3)"></div>)}
{!isAtBeginning() && <div style={`min-height:${PAGINATE_MARGIN}px`}></div>}
<For each={events()}>
{(ev, idx) => <Message event={ev} title={idx() === 0 && false} />}
{(ev, idx) => <Message event={ev} title={idx() === 0 || shouldSplit(ev, events()![idx() - 1])} />}
</For>
<div class="spacer-bottom"></div>
</div>
<div class="input">
<button onClick={handleScroll}>more</button>
<Editor />
<textarea placeholder="write something nice..." ref={textareaEl!} onKeyDown={handleKeyDown}></textarea>
<Editor onSubmit={handleSubmit} />
</div>
</div>
);

View file

@ -1,144 +0,0 @@
import { createEditor, EditorContent } from "tiptap-solid";
import Document from "@tiptap/extension-document";
import Paragraph from "@tiptap/extension-paragraph";
import Text from "@tiptap/extension-text";
import History from "@tiptap/extension-history";
// import Mention from "@tiptap/extension-mention";
import Placeholder from "@tiptap/extension-placeholder";
import "./Editor.scss";
// import { Accessor, createEffect, createSignal, VoidProps } from "solid-js";
import { Extension, Mark, markInputRule, wrappingInputRule } from "@tiptap/core";
import * as tiptap from "@tiptap/core";
import { Plugin, PluginKey } from "@tiptap/pm/state";
import { Decoration, DecorationSet } from "@tiptap/pm/view";
import { Node } from "@tiptap/pm/model";
import { Marked, marked, Token } from "marked";
import { Dropcursor } from "@tiptap/extension-dropcursor";
import { Gapcursor } from "@tiptap/extension-gapcursor";
import { HardBreak } from "@tiptap/extension-hard-break";
// function Suggestions(props: VoidProps<{ suggestions: Accessor<Array<string>> }>) {
// createEffect(() => console.log(props.suggestions()));
// return (
// <ul>
// {props.suggestions().map(i => <li>{i}</li>)}
// </ul>
// )
// }
const Markdown = Extension.create({
addKeyboardShortcuts() {
return {
"Mod-b": () => {
const { state } = this.editor.view;
const { selection } = state;
const { from, to } = selection;
this.editor.chain()
.insertContentAt({ from: to, to }, "**", { updateSelection: true })
.insertContentAt({ from, to: from }, "**", { updateSelection: true })
.setTextSelection({ from: from + 2, to: to + 2 })
.focus()
.run();
return true;
},
"Shift-Enter": () => {
const { state } = this.editor.view;
const { selection } = state;
const { from, to } = selection;
const { paragraph } = state.schema.nodes;
console.log(paragraph)
// this.editor.chain().deleteSelection().unsetCode(from, paragraph.create())
this.editor.chain().setNode("paragraph").run();
console.log("s+enter");
return false;
},
"Enter": () => {
console.log("enter");
return true;
},
}
},
addProseMirrorPlugins() {
return [new Plugin({
key: new PluginKey("markdown"),
props: {
decorations(state) {
const decorations: Array<Decoration> = [];
console.log(state.doc, state.doc.textContent)
state.doc.descendants((node, nodePos) => {
if (!node.isText) return;
let pos = nodePos - 1;
const walk = (ast: Token) => {
switch (ast.type) {
case "em": {
const end = pos + ast.raw.length + 1;
decorations.push(Decoration.inline(pos, pos + 2, { class: "syn" }));
decorations.push(Decoration.inline(pos + 2, end - 1, { style: "font-style: italic" }));
decorations.push(Decoration.inline(end - 1, end, { class: "syn" }));
break;
}
case "strong": {
const end = pos + ast.raw.length + 1;
decorations.push(Decoration.inline(pos, pos + 3, { class: "syn" }));
decorations.push(Decoration.inline(pos + 3, end - 2, { style: "font-weight: bold" }));
decorations.push(Decoration.inline(end - 2, end, { class: "syn" }));
break;
}
case "codespan": {
const end = pos + ast.raw.length + 1;
decorations.push(Decoration.inline(pos, pos + 2, { class: "syn" }));
decorations.push(Decoration.inline(pos + 2, end - 1, { style: "font-style: italic" }));
decorations.push(Decoration.inline(end - 1, end, { class: "syn" }));
break;
}
case "code": {
// console.log(ast)
// const end = pos + ast.raw.length + 1;
// decorations.push(Decoration.inline(pos, pos + 2, { class: "syn" }));
// decorations.push(Decoration.inline(pos + 2, end - 1, { style: "font-style: italic" }));
// decorations.push(Decoration.inline(end - 1, end, { class: "syn" }));
break;
}
case "paragraph": ast.tokens?.forEach(walk); return;
// default: console.log(ast);
}
pos += ast.raw.length;
};
// console.log(node, marked.lexer(node.text!))
marked.lexer(node.text!).forEach(walk);
});
return DecorationSet.create(state.doc, decorations);
}
}
})]
}
});
export function Editor() {
let editorEl;
const editor = createEditor({
content: "hello world *asdf*",
autofocus: true,
extensions: [
Document,
Paragraph,
Text,
History,
Gapcursor,
Dropcursor,
HardBreak,
Placeholder.configure({
placeholder: "write something nice...",
}),
Markdown,
]
});
return (
<div class="editor" ref={editorEl}>
<EditorContent editor={editor()} />
</div>
);
}