feat: upgrade tiptap and handle clipboard uploads
This commit is contained in:
parent
fa9efdb5af
commit
281ecd5f6f
5 changed files with 487 additions and 219 deletions
12
package.json
12
package.json
|
|
@ -44,11 +44,13 @@
|
||||||
"@react-three/fiber": "^9.3.0",
|
"@react-three/fiber": "^9.3.0",
|
||||||
"@tabler/icons-react": "^3.35.0",
|
"@tabler/icons-react": "^3.35.0",
|
||||||
"@tanstack/react-table": "^8.21.3",
|
"@tanstack/react-table": "^8.21.3",
|
||||||
"@tiptap/extension-link": "^3.6.5",
|
"@tiptap/extension-link": "^3.10.0",
|
||||||
"@tiptap/extension-mention": "^3.6.5",
|
"@tiptap/extension-mention": "^3.10.0",
|
||||||
"@tiptap/extension-placeholder": "^3.6.5",
|
"@tiptap/extension-placeholder": "^3.10.0",
|
||||||
"@tiptap/react": "^3.6.5",
|
"@tiptap/react": "^3.10.0",
|
||||||
"@tiptap/starter-kit": "^3.6.5",
|
"@tiptap/starter-kit": "^3.10.0",
|
||||||
|
"@tiptap/suggestion": "^3.10.0",
|
||||||
|
"@tiptap/markdown": "^3.10.0",
|
||||||
"better-auth": "^1.3.26",
|
"better-auth": "^1.3.26",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
|
|
||||||
445
pnpm-lock.yaml
generated
445
pnpm-lock.yaml
generated
|
|
@ -87,20 +87,26 @@ importers:
|
||||||
specifier: ^8.21.3
|
specifier: ^8.21.3
|
||||||
version: 8.21.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
version: 8.21.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
'@tiptap/extension-link':
|
'@tiptap/extension-link':
|
||||||
specifier: ^3.6.5
|
specifier: ^3.10.0
|
||||||
version: 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
version: 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/extension-mention':
|
'@tiptap/extension-mention':
|
||||||
specifier: ^3.6.5
|
specifier: ^3.10.0
|
||||||
version: 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)(@tiptap/suggestion@3.7.2(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))
|
version: 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)(@tiptap/suggestion@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-placeholder':
|
'@tiptap/extension-placeholder':
|
||||||
specifier: ^3.6.5
|
specifier: ^3.10.0
|
||||||
version: 3.6.5(@tiptap/extensions@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))
|
version: 3.10.1(@tiptap/extensions@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))
|
||||||
|
'@tiptap/markdown':
|
||||||
|
specifier: ^3.10.0
|
||||||
|
version: 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/react':
|
'@tiptap/react':
|
||||||
specifier: ^3.6.5
|
specifier: ^3.10.0
|
||||||
version: 3.6.5(@floating-ui/dom@1.7.4)(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
version: 3.10.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
'@tiptap/starter-kit':
|
'@tiptap/starter-kit':
|
||||||
specifier: ^3.6.5
|
specifier: ^3.10.0
|
||||||
version: 3.6.5
|
version: 3.10.1
|
||||||
|
'@tiptap/suggestion':
|
||||||
|
specifier: ^3.10.0
|
||||||
|
version: 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
better-auth:
|
better-auth:
|
||||||
specifier: ^1.3.26
|
specifier: ^1.3.26
|
||||||
version: 1.3.26(next@16.0.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
version: 1.3.26(next@16.0.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
|
|
@ -2163,172 +2169,178 @@ packages:
|
||||||
'@tauri-apps/plugin-updater@2.9.0':
|
'@tauri-apps/plugin-updater@2.9.0':
|
||||||
resolution: {integrity: sha512-j++sgY8XpeDvzImTrzWA08OqqGqgkNyxczLD7FjNJJx/uXxMZFz5nDcfkyoI/rCjYuj2101Tci/r/HFmOmoxCg==}
|
resolution: {integrity: sha512-j++sgY8XpeDvzImTrzWA08OqqGqgkNyxczLD7FjNJJx/uXxMZFz5nDcfkyoI/rCjYuj2101Tci/r/HFmOmoxCg==}
|
||||||
|
|
||||||
'@tiptap/core@3.6.5':
|
'@tiptap/core@3.10.1':
|
||||||
resolution: {integrity: sha512-CgXuhevQbBcPfxaXzGZgIY9+aVMSAd68Q21g3EONz1iZBw026QgiaLhGK6jgGTErZL4GoNL/P+gC5nFCvN7+cA==}
|
resolution: {integrity: sha512-YY/u+RsjLVhcUaIn+wv6vjMx8kldO7SzFFnRu0iuC+QW57VrlqUzqz5PR6CenphwJHuqGM5b3SCr4K2ZPjN8jQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/pm': ^3.6.5
|
'@tiptap/pm': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-blockquote@3.6.5':
|
'@tiptap/extension-blockquote@3.10.1':
|
||||||
resolution: {integrity: sha512-FOOgkLHXQ3zTiL2V1js5+PfaOHXuyr/GjeFZe+W1AUk58X/qJNOVGvKT1xlMOy9gy2ySgWmco7PhNXRRTimkWg==}
|
resolution: {integrity: sha512-swBtOW1g6LMwA1LTZN2GBpdgwOD6pL/SX1GrfZJ46uQF8uBuErsUc+Iop7SX3pVPGLmQg40k0qW5k9QjEC8dGw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-bold@3.6.5':
|
'@tiptap/extension-bold@3.10.1':
|
||||||
resolution: {integrity: sha512-8JXC+K4DXtPDbClHxgRAZnXYO2an2I86PbpqUw+S7m17XCr4t39Sw9CeNBohOHS6Cl8uxOKAjSyCZzqdnYkn3g==}
|
resolution: {integrity: sha512-8TE9oFEonoAs0k3Vd1RGW1FiDBayJiBWyd+1eoH6EEmk1DD7quHcP1mBNZwPpjhONMITaSmizs2FjweWYibFwA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-bubble-menu@3.6.5':
|
'@tiptap/extension-bubble-menu@3.10.1':
|
||||||
resolution: {integrity: sha512-RyCJghtkYZAljZQUfjk3B5tvVVCILsIYMR9XnC152uBiIuWsnz25qfdyBP+cOl6ONrQUvdscs0WmKvzN+nXZYw==}
|
resolution: {integrity: sha512-oNRXAupEeDCeI4nkIhCYSUuT9eZeHDWXcC5fQeWDzCPv3hOcm7W4jqUGJhWWD6qhcbmUSKmsGDTLkBfNk4NT4Q==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
'@tiptap/pm': ^3.6.5
|
'@tiptap/pm': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-bullet-list@3.6.5':
|
'@tiptap/extension-bullet-list@3.10.1':
|
||||||
resolution: {integrity: sha512-AP81hyN7oTyv5zbNVRK35cQA7zuLnI5ItFFyqMQKWh90vfftXi/zhC9C7FWvKtEH7Kk68B338G2mi4tlXDgBFQ==}
|
resolution: {integrity: sha512-SzE8u9QrpzculNmtxKJZAvNG2hGLwishk4oUocK8aAYGUhesKd4pLHE1emA54TgWP0t1aXstg49QIhmHcUND0A==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/extension-list': ^3.6.5
|
'@tiptap/extension-list': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-code-block@3.6.5':
|
'@tiptap/extension-code-block@3.10.1':
|
||||||
resolution: {integrity: sha512-VPPke3LqZYKPlbDBp8IcTJQwvYb1PP0L+2Qi2n3ebN4+gKn+KGhrjnkO+xNHCySWlqywQmMTIfWX1sxA0eVVdQ==}
|
resolution: {integrity: sha512-Yy7XREi27aUE3S1NMihq0j4vM9rNLa3AQVHWFx1Ze2Jec2MUK7ef8WUkMs28cX76M+yB4P63Q2z8meH6HUAzyA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
'@tiptap/pm': ^3.6.5
|
'@tiptap/pm': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-code@3.6.5':
|
'@tiptap/extension-code@3.10.1':
|
||||||
resolution: {integrity: sha512-U/cJFjE0hqBTbMb5J74e7ni5YReuJgS9NyJgTy94+Xt6vxR1vU4+qOl+3E0fOZtwDrxbLrsCQy3P3LvNb3HXdw==}
|
resolution: {integrity: sha512-jeStJuFR5jpwHw/jdnqc1sVNe73dJcqDhcjmNV8cxy86BBadSGynUL1O1/vIyGbF1BFkU69UDBAOLptPH/M2Xg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-document@3.6.5':
|
'@tiptap/extension-document@3.10.1':
|
||||||
resolution: {integrity: sha512-0c7kxWBIEIcoHUG89vpHOF2h4CMa0q6VWXhZ+6iqcI5uyqaKwgcW/TbHZR0nAwEsZLdRCKaryn2kO7jXiCjfnA==}
|
resolution: {integrity: sha512-HM9lmPGKX1s9NJYQh1BD6oLqwh0gWylNmgkT6hEI7lm7DANxaYyMZue9anCDae+K6tln22BauXGAfbRb6Bs0Lw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-dropcursor@3.6.5':
|
'@tiptap/extension-dropcursor@3.10.1':
|
||||||
resolution: {integrity: sha512-BsO3ufLHsdeV1ddChwQfi2Q4UkeqOF4LeUYPYBKfSg59aRKTSoxj3gZrAsaAm/0O3DmAiKNBiCtNRTJSApPEBQ==}
|
resolution: {integrity: sha512-fF3h2Oac8vr21uJh+tiUEz/XUoEzXqx5JpoyWj6BmrTulaMY5uw+SUbh1MxN2EeZ+dUvoc8wPATvn0TTq/3GpA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/extensions': ^3.6.5
|
'@tiptap/extensions': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-floating-menu@3.6.5':
|
'@tiptap/extension-floating-menu@3.10.1':
|
||||||
resolution: {integrity: sha512-ASKb5vHkYyB9g3vOAr2E2U+b6MbHk4Ff4PqngafGlWRAmOAmFxTcw9fLa3HKnj4pokSsYAEvYGOso99/W3GzhA==}
|
resolution: {integrity: sha512-D5ociNnOI3OP4NxS8eKiiqjUdO7geOguK4ZhJo1CFiIXXoLyV20wqqu4fe8Hq9+4gbEyyJ55Tz/AzLiaXw/GPQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@floating-ui/dom': ^1.0.0
|
'@floating-ui/dom': ^1.0.0
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
'@tiptap/pm': ^3.6.5
|
'@tiptap/pm': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-gapcursor@3.6.5':
|
'@tiptap/extension-gapcursor@3.10.1':
|
||||||
resolution: {integrity: sha512-SHtp71zhV2bAQS8kaJ/otb2podGusDREZ9/SQ1rZi6yPcDFLS2KvIvsLssDwbjTuH6KefnsN6Vx01tzmXRAQig==}
|
resolution: {integrity: sha512-Tg43PHL21ZgVXiQZrXmMWCx8jZGEfxB7xxamEkl0CdRFGkcXRmARXuNKT72NtCI3t7/QSlKbpyD/2/9RFGvyeA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/extensions': ^3.6.5
|
'@tiptap/extensions': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-hard-break@3.6.5':
|
'@tiptap/extension-hard-break@3.10.1':
|
||||||
resolution: {integrity: sha512-6iMS6SzIn7+X95okRX8y3l/4f1G3lTrq24sbcAX4MHITncDC6g3TrdAxdA67Tqn5NI/OQx0LwF3kFJDO8QTAUg==}
|
resolution: {integrity: sha512-kCz/ILEVr3jd4/adOfl9d62dEe9PQrHXAB5rBy1ZFoNC+C7Trq8cgpyqUYFAK7Z500nKmUgQh1GtqGN2vy338Q==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-heading@3.6.5':
|
'@tiptap/extension-heading@3.10.1':
|
||||||
resolution: {integrity: sha512-jFS5saqTtfG6MM0sW4X6mZlLycT2ud0Oo1GOZkCyBClwSOpZI/EBLNRIgoXgNtWrY917vB7xTQgCpTVHbvVRsQ==}
|
resolution: {integrity: sha512-udG4cG1pmumECEb6WDW/qYtuHcHscTMPCR6mG8hz0WpYk1S+LQWGPaQPdvHK6qYrMo/3YwQcYZv5vuQiB3dpjg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-horizontal-rule@3.6.5':
|
'@tiptap/extension-horizontal-rule@3.10.1':
|
||||||
resolution: {integrity: sha512-yNxcejI25j6NQMQuKQMTVmNYLnrHFCpzGAz1Ndzyar+gItYZXI9BLmMlwpLkIaJMpIKChj+2qHz25fPS5FlNFw==}
|
resolution: {integrity: sha512-P9dJrVnVlYTESmXWMDmAMHw1TLHZwKQV8Yfz1f8mCuuIHTR++hoWVgjZ70MYZzdAMCug3FWsmDjo+sxGCWOTpg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
'@tiptap/pm': ^3.6.5
|
'@tiptap/pm': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-italic@3.6.5':
|
'@tiptap/extension-italic@3.10.1':
|
||||||
resolution: {integrity: sha512-2EtO2uffw5YnTQ1cieLPv9t7OKCfJFbgHRJPXf7Nnfh8XFh5AEyzw0qBNXZyLtlB28+HHSWLc/OHS6xMfwUy0A==}
|
resolution: {integrity: sha512-/VbABhC20z/KWhKjcFUk7jJuOgD8Hp2V5lr6fOLFJaRpptoJhmbCRrPJzEZhs/Z55nv6aF7ZxVxtjzO0FpKneQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-link@3.6.5':
|
'@tiptap/extension-link@3.10.1':
|
||||||
resolution: {integrity: sha512-VLCDNwxLC1IPnWT3HLLJUg1Hflf8A2jfs7aNF4vyMTWmKnrk1zmN+VyXQTAkrqr27qE5FnmLhHOYF3SNolNucw==}
|
resolution: {integrity: sha512-87OBwlU/ylPCDNhNyKPQaM0KiT0FscyAqh8/oErmI7gKVdrUNfO4zcqIOKHql32lEu9KsmpSum/jSeeUJMR4pA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
'@tiptap/pm': ^3.6.5
|
'@tiptap/pm': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-list-item@3.6.5':
|
'@tiptap/extension-list-item@3.10.1':
|
||||||
resolution: {integrity: sha512-A5JKf2dNG6IRrHmkaqroq/VcD5SnXYXgpQpsF7HrPGIzUSIjvjQu088980NQPHyMuTanDMml+nZgd8RzHhRISA==}
|
resolution: {integrity: sha512-YCK2N2RJGnvMTolwMD3kutnN4x1duBhUH14SdigJuPQLhDi02ck6jjTCNTjQRgDfpL9qfSLpPdn0ou7+NbFu3g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/extension-list': ^3.6.5
|
'@tiptap/extension-list': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-list-keymap@3.6.5':
|
'@tiptap/extension-list-keymap@3.10.1':
|
||||||
resolution: {integrity: sha512-OHGGTJMdUOBincMgYGEN4WzHrTB/GFeCxLDJraDknPx4VJVa3UVZS8F8xd5cb2WnACEF33Ud/0yK3aN6kHrbtQ==}
|
resolution: {integrity: sha512-EPFZtv4yzuCRXqyIQ6v7xvDFGb9L4O+r6NpQ/Aim6fgQmElxHKs75iDet0dFWGQ/Re/o1Q7zgW3mhBcl1MLszw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/extension-list': ^3.6.5
|
'@tiptap/extension-list': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-list@3.6.5':
|
'@tiptap/extension-list@3.10.1':
|
||||||
resolution: {integrity: sha512-2S6wNeaGvvYzJygBhHRLP0YubJAzY00WxQSO3NvHFeLFRFvilCnmh0JGMAqsNU+Owpz0iVrWY0YZskN5gPeR9w==}
|
resolution: {integrity: sha512-v1TqDqNq3RXwKXyCoObv+42qrxAEtpac3BRZKWwwUcxM55oP5HxeaiEo2usheLs3+fEFkKtWKof2I9gUW0HLvA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
'@tiptap/pm': ^3.6.5
|
'@tiptap/pm': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-mention@3.6.5':
|
'@tiptap/extension-mention@3.10.1':
|
||||||
resolution: {integrity: sha512-ACElkBvemEJGm8gVYI4QKjf6tfNj3m5dC9MkZL4rwZo4CAwjiNQ8oFhj1x7sPO1OVlnjt+FhnItBix5ztTF8Ng==}
|
resolution: {integrity: sha512-s7zC3gBQQL99vH37/WdagfLFIDmSJz1uV6fsouckIag0nHBxKTPsZy4LR8CRZZ6RECIyj2WGm71GoVqKUUSEBw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
'@tiptap/pm': ^3.6.5
|
'@tiptap/pm': ^3.10.1
|
||||||
'@tiptap/suggestion': ^3.6.5
|
'@tiptap/suggestion': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-ordered-list@3.6.5':
|
'@tiptap/extension-ordered-list@3.10.1':
|
||||||
resolution: {integrity: sha512-RiBl0Dkw8QtzS7OqUGm84BOyemw/N+hf8DYWsIqVysMRQAGBGhuklbw+DGpCL0nMHW4lh7WtvfKcb0yxLmhbbA==}
|
resolution: {integrity: sha512-dpKNFFF8QqfwSuXYoTktb3Woeqqjc3pZ4Vx4F4JSyzIlgBPLim0Wkn18ClJFIC2But/FcLm6NQrlpnimExfFlQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/extension-list': ^3.6.5
|
'@tiptap/extension-list': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-paragraph@3.6.5':
|
'@tiptap/extension-paragraph@3.10.1':
|
||||||
resolution: {integrity: sha512-AfuaBu+DKrRPspaLsXgo17dhuneISS6QsZTIzPeX21jFJcq3TjtD8wSzS4yRgzAQCEbupkI7t4JbtgxAIBNQHA==}
|
resolution: {integrity: sha512-ocxyg947q5yOSyripEingN7SnsJ/4cYuxOg8BdNlSao8HzUTw5298/81Almf2pT0FNAJHMp8R4Xsii2oMlJ/yQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-placeholder@3.6.5':
|
'@tiptap/extension-placeholder@3.10.1':
|
||||||
resolution: {integrity: sha512-9CLixogEb/4UkEyuDr4JdOlLvphcOVfZMdNMKmUVQdqo4MuZCdTDyK5ypfTPQJl8aUo0oCiEhqE0bQerYlueJQ==}
|
resolution: {integrity: sha512-7R31ytEtyYKNrj3g610sHiUvseRnNyzxMlYtwXEQIZ8w3St5QduwJm+AMOygS4Nmdg88C1zsu1VIiRZCKFutbw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/extensions': ^3.6.5
|
'@tiptap/extensions': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-strike@3.6.5':
|
'@tiptap/extension-strike@3.10.1':
|
||||||
resolution: {integrity: sha512-QR7CUmRJ7fJkHtxqKajKIaX/B4xpKFOsAOJHbnqZ8wzOtnEL5IlsmoUnbKBoVn0+2R2YKKvMK3lepGtAcVCfIQ==}
|
resolution: {integrity: sha512-NYnQOQM/HRvOcCRdetZthMMOZFpxpJ2PBuYg6u6ysotFJPWVVaegtNfZ4se0UdxDNPYInTW3gAgF05Tq/XszRQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-text@3.6.5':
|
'@tiptap/extension-text@3.10.1':
|
||||||
resolution: {integrity: sha512-PVZDWUa25xPzmEN6WWA103yvYJn+NBvWb7WrQwWu9LkKUgd98ZgV3yFaEem/Ybugl/NDPV7q8GGaH+2wEg/VeA==}
|
resolution: {integrity: sha512-Af0WBQJvjiTnEArutOZENCVNGuK7Ln3BwUH3jXsk4OUHxOyt5JK9qsDePsO46Dj9OlXHbnBi5hAnhJGI8zGLzw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-underline@3.6.5':
|
'@tiptap/extension-underline@3.10.1':
|
||||||
resolution: {integrity: sha512-Ul1mO0H1e2vfvN5g48X/YQ8w1xFTpLqce+GUhi0OmXaZnVOTIMtLuN/zAAPjD+uw+79JVGjYa53lbo1dyhOfAw==}
|
resolution: {integrity: sha512-U56hHqCSjwP8wAq28n6A+l+aNW/DxJXiaNwXs7YlC4IjRDkbsl5q53UcOlRCoVnYVY2mxj1L6Zmu2u6dhjeuSQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/extensions@3.6.5':
|
'@tiptap/extensions@3.10.1':
|
||||||
resolution: {integrity: sha512-7aadEaRjSbFAIp3WGYR1LXrvtVprmBNxw3FakEUMJ+XKmGNErDJgDMZh+siAYw5MWwCCGa5kKu8Qi/i+DU+ILg==}
|
resolution: {integrity: sha512-tZZ1IGIcch4ezuoid3iPSirh0s2GQuSKY6ceWRJCVeZ2gT2LsN3i10tqfidcYrsmyQRMuM7QUfRmH5HOKJZ73Q==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
'@tiptap/pm': ^3.6.5
|
'@tiptap/pm': ^3.10.1
|
||||||
|
|
||||||
'@tiptap/pm@3.6.5':
|
'@tiptap/markdown@3.10.1':
|
||||||
resolution: {integrity: sha512-S+j6MPgUXRIQd5/mdaLjaJnOt4ptFwjqGjGMUfBbf9a3uKpXUXaCCzfuC6ZikwaUtoVh4KN9BU3HCYDtgtENPA==}
|
resolution: {integrity: sha512-uWXFAO34u36PYU95kjIl3k1FeNXoZ4Vv4wMR2tZDU1B5xyTgYddLCBpr4Brl2FPAW97VNsqkFabZA1pHXC9OEQ==}
|
||||||
|
|
||||||
'@tiptap/react@3.6.5':
|
|
||||||
resolution: {integrity: sha512-kum9fYzY6qmHuabcXDUTX2sVLdtJtZS0kN91mwD29Ue8HUkjVvEX92PwV2HtgNw3WFMaVxgm/dtm3XPTAlUEwg==}
|
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.6.5
|
'@tiptap/core': ^3.10.1
|
||||||
'@tiptap/pm': ^3.6.5
|
'@tiptap/pm': ^3.10.1
|
||||||
|
|
||||||
|
'@tiptap/pm@3.10.1':
|
||||||
|
resolution: {integrity: sha512-LhTRI+bECLFqitWN821A7faVFVw5OitFGWn45LIIRc/1Jg3lkqsaqx3LcLN1sjXd+f/vfoeXLKSD6VJvv/B/nQ==}
|
||||||
|
|
||||||
|
'@tiptap/react@3.10.1':
|
||||||
|
resolution: {integrity: sha512-skL1a+WorLKv+m0bkbPKIbavN2CSBueWqEWxYs1AxI0qk2v49oRj/cyvv7lLUC2sdzds9GqXHcSBDqsw8Th+hw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^3.10.1
|
||||||
|
'@tiptap/pm': ^3.10.1
|
||||||
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
|
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
'@types/react-dom': ^17.0.0 || ^18.0.0 || ^19.0.0
|
'@types/react-dom': ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
react: ^17.0.0 || ^18.0.0 || ^19.0.0
|
react: ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
|
react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
|
||||||
'@tiptap/starter-kit@3.6.5':
|
'@tiptap/starter-kit@3.10.1':
|
||||||
resolution: {integrity: sha512-LNAJQstB/VazmMlRbUyu3rCNVQ9af25Ywkn3Uyuwt3Ks9ZlliIm/x/zertdXTY2adoig+b36zT5Xcx1O4IdJ3A==}
|
resolution: {integrity: sha512-7IRZqLbvb6VWTS1nIRClQiE54I37aXFejdViTBRvxWb2TiWW8wpsfSdNAMklfwmFbg7RmOO9vaOHlilVu+donw==}
|
||||||
|
|
||||||
'@tiptap/suggestion@3.7.2':
|
'@tiptap/suggestion@3.10.1':
|
||||||
resolution: {integrity: sha512-CYmIMeLqeGBotl7+4TrnGux/ov9IJoWTUQN/JcHp0aOoN3z8c/dQ6cziXXknr51jGHSdVYMWEyamLDZfcaGC1w==}
|
resolution: {integrity: sha512-QpSMsMtpsBSapCDytjdKXLcuPunnd00fGSrYp23C4BDI2Ph7JOYHsgv/wIKgpAYg2fpbJT6DIIbpSHhWluEFyw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tiptap/core': ^3.7.2
|
'@tiptap/core': ^3.10.1
|
||||||
'@tiptap/pm': ^3.7.2
|
'@tiptap/pm': ^3.10.1
|
||||||
|
|
||||||
'@tweenjs/tween.js@23.1.3':
|
'@tweenjs/tween.js@23.1.3':
|
||||||
resolution: {integrity: sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==}
|
resolution: {integrity: sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==}
|
||||||
|
|
@ -3917,6 +3929,11 @@ packages:
|
||||||
resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
|
resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
marked@16.4.1:
|
||||||
|
resolution: {integrity: sha512-ntROs7RaN3EvWfy3EZi14H4YxmT6A5YvywfhO+0pm+cH/dnSQRmdAmoFIc3B9aiwTehyk7pESH4ofyBY+V5hZg==}
|
||||||
|
engines: {node: '>= 20'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
math-intrinsics@1.1.0:
|
math-intrinsics@1.1.0:
|
||||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
@ -6945,129 +6962,135 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tauri-apps/api': 2.8.0
|
'@tauri-apps/api': 2.8.0
|
||||||
|
|
||||||
'@tiptap/core@3.6.5(@tiptap/pm@3.6.5)':
|
'@tiptap/core@3.10.1(@tiptap/pm@3.10.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/pm': 3.6.5
|
'@tiptap/pm': 3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-blockquote@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-blockquote@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-bold@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-bold@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-bubble-menu@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)':
|
'@tiptap/extension-bubble-menu@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/dom': 1.7.4
|
'@floating-ui/dom': 1.7.4
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/pm': 3.6.5
|
'@tiptap/pm': 3.10.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@tiptap/extension-bullet-list@3.6.5(@tiptap/extension-list@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-bullet-list@3.10.1(@tiptap/extension-list@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/extension-list': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extension-list': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-code-block@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)':
|
'@tiptap/extension-code-block@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/pm': 3.6.5
|
'@tiptap/pm': 3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-code@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-code@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-document@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-document@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-dropcursor@3.6.5(@tiptap/extensions@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-dropcursor@3.10.1(@tiptap/extensions@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/extensions': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extensions': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-floating-menu@3.6.5(@floating-ui/dom@1.7.4)(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)':
|
'@tiptap/extension-floating-menu@3.10.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/dom': 1.7.4
|
'@floating-ui/dom': 1.7.4
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/pm': 3.6.5
|
'@tiptap/pm': 3.10.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@tiptap/extension-gapcursor@3.6.5(@tiptap/extensions@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-gapcursor@3.10.1(@tiptap/extensions@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/extensions': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extensions': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-hard-break@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-hard-break@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-heading@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-heading@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-horizontal-rule@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)':
|
'@tiptap/extension-horizontal-rule@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/pm': 3.6.5
|
'@tiptap/pm': 3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-italic@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-italic@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-link@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)':
|
'@tiptap/extension-link@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/pm': 3.6.5
|
'@tiptap/pm': 3.10.1
|
||||||
linkifyjs: 4.3.2
|
linkifyjs: 4.3.2
|
||||||
|
|
||||||
'@tiptap/extension-list-item@3.6.5(@tiptap/extension-list@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-list-item@3.10.1(@tiptap/extension-list@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/extension-list': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extension-list': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-list-keymap@3.6.5(@tiptap/extension-list@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-list-keymap@3.10.1(@tiptap/extension-list@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/extension-list': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extension-list': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-list@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)':
|
'@tiptap/extension-list@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/pm': 3.6.5
|
'@tiptap/pm': 3.10.1
|
||||||
|
|
||||||
'@tiptap/extension-mention@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)(@tiptap/suggestion@3.7.2(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-mention@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)(@tiptap/suggestion@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/pm': 3.6.5
|
'@tiptap/pm': 3.10.1
|
||||||
'@tiptap/suggestion': 3.7.2(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/suggestion': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-ordered-list@3.6.5(@tiptap/extension-list@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-ordered-list@3.10.1(@tiptap/extension-list@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/extension-list': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extension-list': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-paragraph@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-paragraph@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-placeholder@3.6.5(@tiptap/extensions@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-placeholder@3.10.1(@tiptap/extensions@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/extensions': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extensions': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-strike@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-strike@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-text@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-text@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extension-underline@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))':
|
'@tiptap/extension-underline@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
|
|
||||||
'@tiptap/extensions@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)':
|
'@tiptap/extensions@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/pm': 3.6.5
|
'@tiptap/pm': 3.10.1
|
||||||
|
|
||||||
'@tiptap/pm@3.6.5':
|
'@tiptap/markdown@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)':
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
|
'@tiptap/pm': 3.10.1
|
||||||
|
marked: 16.4.1
|
||||||
|
|
||||||
|
'@tiptap/pm@3.10.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
prosemirror-changeset: 2.3.1
|
prosemirror-changeset: 2.3.1
|
||||||
prosemirror-collab: 1.3.1
|
prosemirror-collab: 1.3.1
|
||||||
|
|
@ -7088,10 +7111,10 @@ snapshots:
|
||||||
prosemirror-transform: 1.10.4
|
prosemirror-transform: 1.10.4
|
||||||
prosemirror-view: 1.41.2
|
prosemirror-view: 1.41.2
|
||||||
|
|
||||||
'@tiptap/react@3.6.5(@floating-ui/dom@1.7.4)(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
|
'@tiptap/react@3.10.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/pm': 3.6.5
|
'@tiptap/pm': 3.10.1
|
||||||
'@types/react': 18.3.26
|
'@types/react': 18.3.26
|
||||||
'@types/react-dom': 18.3.7(@types/react@18.3.26)
|
'@types/react-dom': 18.3.7(@types/react@18.3.26)
|
||||||
'@types/use-sync-external-store': 0.0.6
|
'@types/use-sync-external-store': 0.0.6
|
||||||
|
|
@ -7100,42 +7123,42 @@ snapshots:
|
||||||
react-dom: 19.2.0(react@19.2.0)
|
react-dom: 19.2.0(react@19.2.0)
|
||||||
use-sync-external-store: 1.6.0(react@19.2.0)
|
use-sync-external-store: 1.6.0(react@19.2.0)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@tiptap/extension-bubble-menu': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extension-bubble-menu': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/extension-floating-menu': 3.6.5(@floating-ui/dom@1.7.4)(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extension-floating-menu': 3.10.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@floating-ui/dom'
|
- '@floating-ui/dom'
|
||||||
|
|
||||||
'@tiptap/starter-kit@3.6.5':
|
'@tiptap/starter-kit@3.10.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/extension-blockquote': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))
|
'@tiptap/extension-blockquote': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-bold': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))
|
'@tiptap/extension-bold': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-bullet-list': 3.6.5(@tiptap/extension-list@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))
|
'@tiptap/extension-bullet-list': 3.10.1(@tiptap/extension-list@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-code': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))
|
'@tiptap/extension-code': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-code-block': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extension-code-block': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/extension-document': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))
|
'@tiptap/extension-document': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-dropcursor': 3.6.5(@tiptap/extensions@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))
|
'@tiptap/extension-dropcursor': 3.10.1(@tiptap/extensions@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-gapcursor': 3.6.5(@tiptap/extensions@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))
|
'@tiptap/extension-gapcursor': 3.10.1(@tiptap/extensions@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-hard-break': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))
|
'@tiptap/extension-hard-break': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-heading': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))
|
'@tiptap/extension-heading': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-horizontal-rule': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extension-horizontal-rule': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/extension-italic': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))
|
'@tiptap/extension-italic': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-link': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extension-link': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/extension-list': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extension-list': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/extension-list-item': 3.6.5(@tiptap/extension-list@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))
|
'@tiptap/extension-list-item': 3.10.1(@tiptap/extension-list@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-list-keymap': 3.6.5(@tiptap/extension-list@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))
|
'@tiptap/extension-list-keymap': 3.10.1(@tiptap/extension-list@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-ordered-list': 3.6.5(@tiptap/extension-list@3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5))
|
'@tiptap/extension-ordered-list': 3.10.1(@tiptap/extension-list@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-paragraph': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))
|
'@tiptap/extension-paragraph': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-strike': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))
|
'@tiptap/extension-strike': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-text': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))
|
'@tiptap/extension-text': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extension-underline': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))
|
'@tiptap/extension-underline': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))
|
||||||
'@tiptap/extensions': 3.6.5(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)
|
'@tiptap/extensions': 3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/pm': 3.6.5
|
'@tiptap/pm': 3.10.1
|
||||||
|
|
||||||
'@tiptap/suggestion@3.7.2(@tiptap/core@3.6.5(@tiptap/pm@3.6.5))(@tiptap/pm@3.6.5)':
|
'@tiptap/suggestion@3.10.1(@tiptap/core@3.10.1(@tiptap/pm@3.10.1))(@tiptap/pm@3.10.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tiptap/core': 3.6.5(@tiptap/pm@3.6.5)
|
'@tiptap/core': 3.10.1(@tiptap/pm@3.10.1)
|
||||||
'@tiptap/pm': 3.6.5
|
'@tiptap/pm': 3.10.1
|
||||||
|
|
||||||
'@tweenjs/tween.js@23.1.3': {}
|
'@tweenjs/tween.js@23.1.3': {}
|
||||||
|
|
||||||
|
|
@ -8968,6 +8991,8 @@ snapshots:
|
||||||
punycode.js: 2.3.1
|
punycode.js: 2.3.1
|
||||||
uc.micro: 2.1.0
|
uc.micro: 2.1.0
|
||||||
|
|
||||||
|
marked@16.4.1: {}
|
||||||
|
|
||||||
math-intrinsics@1.1.0: {}
|
math-intrinsics@1.1.0: {}
|
||||||
|
|
||||||
mdn-data@2.12.2: {}
|
mdn-data@2.12.2: {}
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,20 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react"
|
||||||
import { formatDistanceToNow } from "date-fns"
|
import { formatDistanceToNow } from "date-fns"
|
||||||
import { ptBR } from "date-fns/locale"
|
import { ptBR } from "date-fns/locale"
|
||||||
import { IconLock, IconMessage, IconFileText } from "@tabler/icons-react"
|
import { IconLock, IconMessage, IconFileText } from "@tabler/icons-react"
|
||||||
import { Download, FileIcon, Image as ImageIcon, PencilLine, Trash2, X } from "lucide-react"
|
import { Download, FileCode, FileIcon, Image as ImageIcon, PencilLine, Trash2, X, ClipboardCopy } from "lucide-react"
|
||||||
import { useAction, useMutation, useQuery } from "convex/react"
|
import { useAction, useMutation, useQuery } from "convex/react"
|
||||||
import { api } from "@/convex/_generated/api"
|
import { api } from "@/convex/_generated/api"
|
||||||
import { useAuth } from "@/lib/auth-client"
|
import { useAuth } from "@/lib/auth-client"
|
||||||
import type { Id } from "@/convex/_generated/dataModel"
|
import type { Id } from "@/convex/_generated/dataModel"
|
||||||
import type { TicketWithDetails } from "@/lib/schemas/ticket"
|
import type { TicketWithDetails } from "@/lib/schemas/ticket"
|
||||||
|
import type { Editor } from "@tiptap/react"
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||||
import { Badge } from "@/components/ui/badge"
|
import { Badge } from "@/components/ui/badge"
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { toast } from "sonner"
|
import { toast } from "sonner"
|
||||||
import { Dropzone } from "@/components/ui/dropzone"
|
import { Dropzone } from "@/components/ui/dropzone"
|
||||||
|
import { Textarea } from "@/components/ui/textarea"
|
||||||
import {
|
import {
|
||||||
RichTextEditor,
|
RichTextEditor,
|
||||||
RichTextContent,
|
RichTextContent,
|
||||||
|
|
@ -38,6 +40,9 @@ const selectTriggerClass = "h-8 w-[140px] rounded-lg border border-slate-300 bg-
|
||||||
const submitButtonClass =
|
const submitButtonClass =
|
||||||
"inline-flex items-center gap-2 rounded-lg border border-black bg-black px-3 py-2 text-sm font-semibold text-white transition hover:bg-[#18181b]/85 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#18181b]/30"
|
"inline-flex items-center gap-2 rounded-lg border border-black bg-black px-3 py-2 text-sm font-semibold text-white transition hover:bg-[#18181b]/85 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#18181b]/30"
|
||||||
|
|
||||||
|
const COMMENT_ATTACHMENT_LIMIT = 10
|
||||||
|
const COMMENT_ATTACHMENT_MAX_FILE_SIZE = 5 * 1024 * 1024
|
||||||
|
|
||||||
type CommentsOrder = "descending" | "ascending"
|
type CommentsOrder = "descending" | "ascending"
|
||||||
|
|
||||||
export function TicketComments({ ticket }: TicketCommentsProps) {
|
export function TicketComments({ ticket }: TicketCommentsProps) {
|
||||||
|
|
@ -60,6 +65,8 @@ export function TicketComments({ ticket }: TicketCommentsProps) {
|
||||||
() => attachmentsToSend.reduce((acc, item) => acc + (item.size ?? 0), 0),
|
() => attachmentsToSend.reduce((acc, item) => acc + (item.size ?? 0), 0),
|
||||||
[attachmentsToSend]
|
[attachmentsToSend]
|
||||||
)
|
)
|
||||||
|
const editorRef = useRef<Editor | null>(null)
|
||||||
|
const dropzoneUploadHandlerRef = useRef<((files: File[]) => Promise<void>) | null>(null)
|
||||||
const [preview, setPreview] = useState<string | null>(null)
|
const [preview, setPreview] = useState<string | null>(null)
|
||||||
const [pending, setPending] = useState<Pick<TicketWithDetails["comments"][number], "id" | "author" | "visibility" | "body" | "attachments" | "createdAt" | "updatedAt">[]>([])
|
const [pending, setPending] = useState<Pick<TicketWithDetails["comments"][number], "id" | "author" | "visibility" | "body" | "attachments" | "createdAt" | "updatedAt">[]>([])
|
||||||
const [visibility, setVisibility] = useState<"PUBLIC" | "INTERNAL">("INTERNAL")
|
const [visibility, setVisibility] = useState<"PUBLIC" | "INTERNAL">("INTERNAL")
|
||||||
|
|
@ -69,6 +76,9 @@ export function TicketComments({ ticket }: TicketCommentsProps) {
|
||||||
const [savingCommentId, setSavingCommentId] = useState<string | null>(null)
|
const [savingCommentId, setSavingCommentId] = useState<string | null>(null)
|
||||||
const [localBodies, setLocalBodies] = useState<Record<string, string>>({})
|
const [localBodies, setLocalBodies] = useState<Record<string, string>>({})
|
||||||
const [commentsOrder, setCommentsOrder] = useState<CommentsOrder>("descending")
|
const [commentsOrder, setCommentsOrder] = useState<CommentsOrder>("descending")
|
||||||
|
const [markdownDialogOpen, setMarkdownDialogOpen] = useState(false)
|
||||||
|
const [markdownDraft, setMarkdownDraft] = useState("")
|
||||||
|
const [isEditorReady, setIsEditorReady] = useState(false)
|
||||||
|
|
||||||
const templateArgs =
|
const templateArgs =
|
||||||
convexUserId && isStaff
|
convexUserId && isStaff
|
||||||
|
|
@ -91,6 +101,119 @@ export function TicketComments({ ticket }: TicketCommentsProps) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleEditorInstance = useCallback((instance: Editor | null) => {
|
||||||
|
editorRef.current = instance
|
||||||
|
setIsEditorReady(Boolean(instance))
|
||||||
|
}, [setIsEditorReady])
|
||||||
|
|
||||||
|
const handleEditorPasteFiles = useCallback(
|
||||||
|
(files: File[]) => {
|
||||||
|
if (!files.length) return
|
||||||
|
if (!canComment) {
|
||||||
|
toast.error("Você não tem permissão para anexar arquivos neste comentário.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const uploader = dropzoneUploadHandlerRef.current
|
||||||
|
if (!uploader) {
|
||||||
|
toast.error("Uploader de arquivos indisponível no momento.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const remainingSlots = Math.max(0, COMMENT_ATTACHMENT_LIMIT - attachmentsToSend.length)
|
||||||
|
if (remainingSlots <= 0) {
|
||||||
|
toast.warning(`Limite de ${COMMENT_ATTACHMENT_LIMIT} anexos atingido.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const sizeLimitMb = Math.round(COMMENT_ATTACHMENT_MAX_FILE_SIZE / (1024 * 1024))
|
||||||
|
const withinSizeLimit: File[] = []
|
||||||
|
let oversized = 0
|
||||||
|
for (const file of files) {
|
||||||
|
if (file.size <= COMMENT_ATTACHMENT_MAX_FILE_SIZE) {
|
||||||
|
withinSizeLimit.push(file)
|
||||||
|
} else {
|
||||||
|
oversized += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (oversized > 0) {
|
||||||
|
toast.warning(`${oversized} imagem(ns) foram ignoradas por excederem ${sizeLimitMb}MB.`)
|
||||||
|
}
|
||||||
|
if (!withinSizeLimit.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const selected = withinSizeLimit.slice(0, remainingSlots)
|
||||||
|
if (selected.length < withinSizeLimit.length) {
|
||||||
|
toast.warning("Algumas imagens foram ignoradas para respeitar o limite de anexos.")
|
||||||
|
}
|
||||||
|
const toastId = "clipboard-attachments"
|
||||||
|
toast.loading("Processando imagens coladas...", { id: toastId })
|
||||||
|
void uploader(selected)
|
||||||
|
.then(() => {
|
||||||
|
toast.success("Imagens coladas adicionadas como anexos.", { id: toastId })
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Failed to upload clipboard images", error)
|
||||||
|
toast.error("Não foi possível anexar as imagens coladas.", { id: toastId })
|
||||||
|
})
|
||||||
|
},
|
||||||
|
[attachmentsToSend.length, canComment]
|
||||||
|
)
|
||||||
|
|
||||||
|
const handleCopyMarkdown = useCallback(async () => {
|
||||||
|
const editor = editorRef.current
|
||||||
|
if (!editor) return
|
||||||
|
const markdownStorage = (editor.storage as { markdown?: { getMarkdown?: () => string } } | undefined)?.markdown
|
||||||
|
const markdown = markdownStorage?.getMarkdown?.()
|
||||||
|
if (!markdown) {
|
||||||
|
toast.warning("Não há conteúdo em Markdown para copiar.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!navigator.clipboard || typeof navigator.clipboard.writeText !== "function") {
|
||||||
|
toast.error("Copiar para a área de transferência não é suportado neste navegador.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(markdown)
|
||||||
|
toast.success("Markdown copiado para a área de transferência.")
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to copy markdown", error)
|
||||||
|
toast.error("Não foi possível copiar o Markdown.")
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleOpenMarkdownImport = useCallback(() => {
|
||||||
|
const editor = editorRef.current
|
||||||
|
const markdownStorage = (editor?.storage as { markdown?: { getMarkdown?: () => string } } | undefined)?.markdown
|
||||||
|
const currentMarkdown = markdownStorage?.getMarkdown?.() ?? ""
|
||||||
|
setMarkdownDraft(currentMarkdown)
|
||||||
|
setMarkdownDialogOpen(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleApplyMarkdownImport = useCallback(() => {
|
||||||
|
const editor = editorRef.current
|
||||||
|
if (!editor) return
|
||||||
|
const draft = markdownDraft.trim()
|
||||||
|
if (!draft) {
|
||||||
|
editor.commands.clearContent(true)
|
||||||
|
editor.commands.focus("end")
|
||||||
|
setMarkdownDialogOpen(false)
|
||||||
|
setMarkdownDraft("")
|
||||||
|
toast.success("Editor limpo.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const toastId = "markdown-import"
|
||||||
|
toast.loading("Convertendo Markdown...", { id: toastId })
|
||||||
|
try {
|
||||||
|
editor.commands.setContent(draft, { contentType: "markdown" })
|
||||||
|
editor.commands.focus("end")
|
||||||
|
toast.success("Markdown convertido em rich text.", { id: toastId })
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to import markdown", error)
|
||||||
|
toast.error("Não foi possível converter o Markdown.", { id: toastId })
|
||||||
|
} finally {
|
||||||
|
setMarkdownDialogOpen(false)
|
||||||
|
setMarkdownDraft("")
|
||||||
|
}
|
||||||
|
}, [markdownDraft])
|
||||||
|
|
||||||
const startEditingComment = useCallback((commentId: string, currentBody: string) => {
|
const startEditingComment = useCallback((commentId: string, currentBody: string) => {
|
||||||
const normalized = normalizeTicketMentionHtml(currentBody || "")
|
const normalized = normalizeTicketMentionHtml(currentBody || "")
|
||||||
setEditingComment({ id: commentId, value: normalized })
|
setEditingComment({ id: commentId, value: normalized })
|
||||||
|
|
@ -440,12 +563,18 @@ export function TicketComments({ ticket }: TicketCommentsProps) {
|
||||||
className="rounded-2xl border border-slate-200"
|
className="rounded-2xl border border-slate-200"
|
||||||
disabled={!canComment}
|
disabled={!canComment}
|
||||||
ticketMention={{ enabled: allowTicketMentions }}
|
ticketMention={{ enabled: allowTicketMentions }}
|
||||||
|
onEditorReady={handleEditorInstance}
|
||||||
|
onPasteFiles={handleEditorPasteFiles}
|
||||||
/>
|
/>
|
||||||
<Dropzone
|
<Dropzone
|
||||||
onUploaded={(files) => setAttachmentsToSend((prev) => [...prev, ...files])}
|
onUploaded={(files) => setAttachmentsToSend((prev) => [...prev, ...files])}
|
||||||
currentFileCount={attachmentsToSend.length}
|
currentFileCount={attachmentsToSend.length}
|
||||||
currentTotalBytes={attachmentsToSendTotalBytes}
|
currentTotalBytes={attachmentsToSendTotalBytes}
|
||||||
disabled={!canComment}
|
disabled={!canComment}
|
||||||
|
maxFiles={COMMENT_ATTACHMENT_LIMIT}
|
||||||
|
onRegisterUploadHandler={(handler) => {
|
||||||
|
dropzoneUploadHandlerRef.current = handler ?? null
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
{attachmentsToSend.length > 0 ? (
|
{attachmentsToSend.length > 0 ? (
|
||||||
<div className="grid max-w-xl grid-cols-[repeat(auto-fill,minmax(96px,1fr))] gap-3">
|
<div className="grid max-w-xl grid-cols-[repeat(auto-fill,minmax(96px,1fr))] gap-3">
|
||||||
|
|
@ -537,6 +666,28 @@ export function TicketComments({ ticket }: TicketCommentsProps) {
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
) : null}
|
) : null}
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="inline-flex items-center gap-2 border-slate-200 text-sm text-neutral-700 hover:bg-slate-50"
|
||||||
|
onClick={handleOpenMarkdownImport}
|
||||||
|
disabled={!canComment || !isEditorReady}
|
||||||
|
>
|
||||||
|
<FileCode className="size-4" />
|
||||||
|
Colar Markdown
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="inline-flex items-center gap-2 border-slate-200 text-sm text-neutral-700 hover:bg-slate-50"
|
||||||
|
onClick={handleCopyMarkdown}
|
||||||
|
disabled={!isEditorReady}
|
||||||
|
>
|
||||||
|
<ClipboardCopy className="size-4" />
|
||||||
|
Copiar Markdown
|
||||||
|
</Button>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
Visibilidade:
|
Visibilidade:
|
||||||
<Select
|
<Select
|
||||||
|
|
@ -562,6 +713,46 @@ export function TicketComments({ ticket }: TicketCommentsProps) {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<Dialog
|
||||||
|
open={markdownDialogOpen}
|
||||||
|
onOpenChange={(open) => {
|
||||||
|
setMarkdownDialogOpen(open)
|
||||||
|
if (!open) {
|
||||||
|
setMarkdownDraft("")
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DialogContent className="sm:max-w-xl space-y-4">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Colar Markdown</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
Cole conteúdo em Markdown para convertê-lo automaticamente em rich text. Isso substitui o texto atual do editor.
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<Textarea
|
||||||
|
value={markdownDraft}
|
||||||
|
onChange={(event) => setMarkdownDraft(event.target.value)}
|
||||||
|
rows={10}
|
||||||
|
placeholder="Cole aqui o texto em Markdown..."
|
||||||
|
className="min-h-[200px]"
|
||||||
|
/>
|
||||||
|
<div className="flex justify-end gap-2">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
onClick={() => {
|
||||||
|
setMarkdownDialogOpen(false)
|
||||||
|
setMarkdownDraft("")
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Cancelar
|
||||||
|
</Button>
|
||||||
|
<Button type="button" onClick={handleApplyMarkdownImport} disabled={!markdownDraft.trim()}>
|
||||||
|
Converter
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
<Dialog open={!!attachmentToRemove} onOpenChange={(open) => { if (!open && !removingAttachment) setAttachmentToRemove(null) }}>
|
<Dialog open={!!attachmentToRemove} onOpenChange={(open) => { if (!open && !removingAttachment) setAttachmentToRemove(null) }}>
|
||||||
<DialogContent className="max-w-sm space-y-4">
|
<DialogContent className="max-w-sm space-y-4">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ export function Dropzone({
|
||||||
currentFileCount = 0,
|
currentFileCount = 0,
|
||||||
currentTotalBytes = 0,
|
currentTotalBytes = 0,
|
||||||
disabled = false,
|
disabled = false,
|
||||||
|
onRegisterUploadHandler,
|
||||||
}: {
|
}: {
|
||||||
onUploaded?: (files: Uploaded[]) => void;
|
onUploaded?: (files: Uploaded[]) => void;
|
||||||
maxFiles?: number;
|
maxFiles?: number;
|
||||||
|
|
@ -28,6 +29,7 @@ export function Dropzone({
|
||||||
currentFileCount?: number;
|
currentFileCount?: number;
|
||||||
currentTotalBytes?: number;
|
currentTotalBytes?: number;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
onRegisterUploadHandler?: (handler: ((files: File[]) => Promise<void>) | null) => void;
|
||||||
}) {
|
}) {
|
||||||
const generateUrl = useAction(api.files.generateUploadUrl);
|
const generateUrl = useAction(api.files.generateUploadUrl);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
@ -122,6 +124,15 @@ export function Dropzone({
|
||||||
if (uploaded.length) onUploaded?.(uploaded);
|
if (uploaded.length) onUploaded?.(uploaded);
|
||||||
}, [disabled, generateUrl, maxFiles, maxSize, normalizedFileCount, onUploaded]);
|
}, [disabled, generateUrl, maxFiles, maxSize, normalizedFileCount, onUploaded]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!onRegisterUploadHandler) return;
|
||||||
|
const handler = (files: File[]) => startUpload(files);
|
||||||
|
onRegisterUploadHandler(handler);
|
||||||
|
return () => {
|
||||||
|
onRegisterUploadHandler(null);
|
||||||
|
};
|
||||||
|
}, [onRegisterUploadHandler, startUpload]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn("space-y-3", className)}>
|
<div className={cn("space-y-3", className)}>
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import StarterKit from "@tiptap/starter-kit"
|
||||||
import Placeholder from "@tiptap/extension-placeholder"
|
import Placeholder from "@tiptap/extension-placeholder"
|
||||||
import Mention from "@tiptap/extension-mention"
|
import Mention from "@tiptap/extension-mention"
|
||||||
import TiptapLink from "@tiptap/extension-link"
|
import TiptapLink from "@tiptap/extension-link"
|
||||||
|
import { Markdown } from "@tiptap/markdown"
|
||||||
import { ReactRenderer } from "@tiptap/react"
|
import { ReactRenderer } from "@tiptap/react"
|
||||||
import tippy, { type Instance, type Props as TippyProps } from "tippy.js"
|
import tippy, { type Instance, type Props as TippyProps } from "tippy.js"
|
||||||
// Nota: o CSS do Tippy não é obrigatório, mas melhora muito a renderização
|
// Nota: o CSS do Tippy não é obrigatório, mas melhora muito a renderização
|
||||||
|
|
@ -51,6 +52,8 @@ type RichTextEditorProps = {
|
||||||
ticketMention?: {
|
ticketMention?: {
|
||||||
enabled?: boolean
|
enabled?: boolean
|
||||||
}
|
}
|
||||||
|
onEditorReady?: (editor: Editor | null) => void
|
||||||
|
onPasteFiles?: (files: File[]) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type TicketMentionItem = {
|
type TicketMentionItem = {
|
||||||
|
|
@ -117,6 +120,24 @@ type TicketMentionAttributes = Record<string, unknown>
|
||||||
const TICKET_MENTION_FALLBACK_STATUS = "PENDING"
|
const TICKET_MENTION_FALLBACK_STATUS = "PENDING"
|
||||||
const TICKET_MENTION_FALLBACK_PRIORITY = "MEDIUM"
|
const TICKET_MENTION_FALLBACK_PRIORITY = "MEDIUM"
|
||||||
|
|
||||||
|
const MAX_PASTED_IMAGE_FILES = 10
|
||||||
|
|
||||||
|
function extractImageFilesFromClipboard(event: ClipboardEvent): File[] {
|
||||||
|
const clipboard = event.clipboardData
|
||||||
|
if (!clipboard) return []
|
||||||
|
|
||||||
|
const filesFromItems = Array.from(clipboard.items ?? [])
|
||||||
|
.filter((item) => item.kind === "file")
|
||||||
|
.map((item) => item.getAsFile())
|
||||||
|
.filter((file): file is File => Boolean(file && file.type.startsWith("image/")))
|
||||||
|
|
||||||
|
if (filesFromItems.length > 0) {
|
||||||
|
return filesFromItems
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(clipboard.files ?? []).filter((file) => file.type.startsWith("image/"))
|
||||||
|
}
|
||||||
|
|
||||||
function toPlainString(value: unknown): string {
|
function toPlainString(value: unknown): string {
|
||||||
if (value === null || value === undefined) return ""
|
if (value === null || value === undefined) return ""
|
||||||
return String(value)
|
return String(value)
|
||||||
|
|
@ -767,6 +788,8 @@ export function RichTextEditor({
|
||||||
disabled,
|
disabled,
|
||||||
minHeight = 120,
|
minHeight = 120,
|
||||||
ticketMention,
|
ticketMention,
|
||||||
|
onEditorReady,
|
||||||
|
onPasteFiles,
|
||||||
}: RichTextEditorProps) {
|
}: RichTextEditorProps) {
|
||||||
const normalizedInitialContent = useMemo(() => {
|
const normalizedInitialContent = useMemo(() => {
|
||||||
if (!ticketMention?.enabled) {
|
if (!ticketMention?.enabled) {
|
||||||
|
|
@ -790,6 +813,7 @@ export function RichTextEditor({
|
||||||
protocols: ["http", "https", "mailto"],
|
protocols: ["http", "https", "mailto"],
|
||||||
HTMLAttributes: { rel: "noopener noreferrer", target: "_blank" },
|
HTMLAttributes: { rel: "noopener noreferrer", target: "_blank" },
|
||||||
}),
|
}),
|
||||||
|
Markdown,
|
||||||
Placeholder.configure({ placeholder }),
|
Placeholder.configure({ placeholder }),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -797,14 +821,21 @@ export function RichTextEditor({
|
||||||
}, [placeholder, ticketMention?.enabled])
|
}, [placeholder, ticketMention?.enabled])
|
||||||
|
|
||||||
const editor = useEditor({
|
const editor = useEditor({
|
||||||
extensions: [
|
extensions,
|
||||||
...extensions,
|
|
||||||
],
|
|
||||||
editorProps: {
|
editorProps: {
|
||||||
attributes: {
|
attributes: {
|
||||||
class:
|
class:
|
||||||
"prose prose-sm max-w-none focus:outline-none text-foreground",
|
"prose prose-sm max-w-none focus:outline-none text-foreground",
|
||||||
},
|
},
|
||||||
|
handlePaste(_, event) {
|
||||||
|
if (!onPasteFiles) return false
|
||||||
|
const imageFiles = extractImageFilesFromClipboard(event)
|
||||||
|
if (imageFiles.length === 0) return false
|
||||||
|
event.preventDefault()
|
||||||
|
const limited = imageFiles.slice(0, MAX_PASTED_IMAGE_FILES)
|
||||||
|
onPasteFiles(limited)
|
||||||
|
return true
|
||||||
|
},
|
||||||
},
|
},
|
||||||
content: normalizedInitialContent,
|
content: normalizedInitialContent,
|
||||||
onUpdate({ editor }) {
|
onUpdate({ editor }) {
|
||||||
|
|
@ -817,6 +848,14 @@ export function RichTextEditor({
|
||||||
immediatelyRender: false,
|
immediatelyRender: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!editor) return
|
||||||
|
onEditorReady?.(editor)
|
||||||
|
return () => {
|
||||||
|
onEditorReady?.(null)
|
||||||
|
}
|
||||||
|
}, [editor, onEditorReady])
|
||||||
|
|
||||||
const [linkPopoverOpen, setLinkPopoverOpen] = useState(false)
|
const [linkPopoverOpen, setLinkPopoverOpen] = useState(false)
|
||||||
const [linkUrl, setLinkUrl] = useState("")
|
const [linkUrl, setLinkUrl] = useState("")
|
||||||
const linkInputRef = useRef<HTMLInputElement>(null)
|
const linkInputRef = useRef<HTMLInputElement>(null)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue