feat: tiptap
This commit is contained in:
parent
734c68df9f
commit
97e82593ec
|
|
@ -8,45 +8,59 @@ import { textSlicer } from '@gitroom/helpers/utils/count.length';
|
|||
import interClass from '@gitroom/react/helpers/inter.font';
|
||||
import Image from 'next/image';
|
||||
import { useLaunchStore } from '@gitroom/frontend/components/new-launch/store';
|
||||
import { stripHtmlValidation } from '@gitroom/helpers/utils/strip.html.validation';
|
||||
export const GeneralPreviewComponent: FC<{
|
||||
maximumCharacters?: number;
|
||||
}> = (props) => {
|
||||
const { value: topValue, integration } = useIntegration();
|
||||
const current = useLaunchStore((state) => state.current);
|
||||
const mediaDir = useMediaDirectory();
|
||||
const newValues = useFormatting(topValue, {
|
||||
removeMarkdown: true,
|
||||
saveBreaklines: true,
|
||||
specialFunc: (text: string) => {
|
||||
const { start, end } = textSlicer(
|
||||
integration?.identifier || '',
|
||||
props.maximumCharacters || 10000,
|
||||
text
|
||||
);
|
||||
return (
|
||||
text.slice(start, end) +
|
||||
'<mark class="bg-red-500" data-tooltip-id="tooltip" data-tooltip-content="This text will be cropped">' +
|
||||
text?.slice(end) +
|
||||
'</mark>'
|
||||
);
|
||||
},
|
||||
|
||||
const renderContent = topValue.map((p) => {
|
||||
const newContent = stripHtmlValidation(p.content, true)
|
||||
.replace(/(@.+?)(\s)/gi, (match, match1, match2) => {
|
||||
return `<span class="font-bold" style="color: #ae8afc">${match1.trim()}${match2}</span>`;
|
||||
})
|
||||
.replace(/@\[(.+?)]\((.+?)\)/gi, (match, name, id) => {
|
||||
return `<span class="font-bold" style="color: #ae8afc">@${name}</span>`;
|
||||
});
|
||||
|
||||
const { start, end } = textSlicer(
|
||||
integration?.identifier || '',
|
||||
props.maximumCharacters || 10000,
|
||||
newContent
|
||||
);
|
||||
|
||||
const finalValue =
|
||||
newContent.slice(start, end) +
|
||||
`<mark class="bg-red-500" data-tooltip-id="tooltip" data-tooltip-content="This text will be cropped">` +
|
||||
newContent.slice(end) +
|
||||
`</mark>`;
|
||||
|
||||
return { text: finalValue, images: p.image };
|
||||
});
|
||||
|
||||
console.log(renderContent);
|
||||
return (
|
||||
<div className={clsx('w-full md:w-[555px] px-[16px]')}>
|
||||
<div className="w-full h-full relative flex flex-col">
|
||||
{newValues.map((value, index) => (
|
||||
{renderContent.map((value, index) => (
|
||||
<div
|
||||
key={`tweet_${index}`}
|
||||
style={{}}
|
||||
className={clsx(
|
||||
`flex gap-[8px] relative`,
|
||||
index === newValues.length - 1 ? 'pb-[12px]' : 'pb-[24px]'
|
||||
index === renderContent.length - 1 ? 'pb-[12px]' : 'pb-[24px]'
|
||||
)}
|
||||
>
|
||||
<div className="w-[40px] flex flex-col items-center">
|
||||
<div className="relative">
|
||||
<img
|
||||
src={current === 'global' ? '/no-picture.jpg' : (integration?.picture || '/no-picture.jpg')}
|
||||
src={
|
||||
current === 'global'
|
||||
? '/no-picture.jpg'
|
||||
: integration?.picture || '/no-picture.jpg'
|
||||
}
|
||||
alt="x"
|
||||
className="rounded-full relative z-[2]"
|
||||
/>
|
||||
|
|
@ -84,7 +98,9 @@ export const GeneralPreviewComponent: FC<{
|
|||
</svg>
|
||||
</div>
|
||||
<div className="text-[15px] font-[400] text-customColor27 ms-[4px]">
|
||||
{current === 'global' ? '' : integration?.display || '@username'}
|
||||
{current === 'global'
|
||||
? ''
|
||||
: integration?.display || '@username'}
|
||||
</div>
|
||||
</div>
|
||||
<pre
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ import {
|
|||
useEditor,
|
||||
EditorContent,
|
||||
Extension,
|
||||
Mark,
|
||||
mergeAttributes,
|
||||
Node,
|
||||
} from '@tiptap/react';
|
||||
|
|
@ -45,6 +44,7 @@ import Text from '@tiptap/extension-text';
|
|||
import Paragraph from '@tiptap/extension-paragraph';
|
||||
import Underline from '@tiptap/extension-underline';
|
||||
import { stripHtmlValidation } from '@gitroom/helpers/utils/strip.html.validation';
|
||||
import { History } from '@tiptap/extension-history';
|
||||
|
||||
const InterceptBoldShortcut = Extension.create({
|
||||
name: 'preventBoldWithUnderline',
|
||||
|
|
@ -500,7 +500,7 @@ export const Editor: FC<{
|
|||
);
|
||||
|
||||
const paste = useCallback(
|
||||
async (event: ClipboardEvent<HTMLDivElement> | File[]) => {
|
||||
async (event: ClipboardEvent | File[]) => {
|
||||
// @ts-ignore
|
||||
const clipboardItems = event.clipboardData?.items;
|
||||
if (!clipboardItems) {
|
||||
|
|
@ -532,10 +532,16 @@ export const Editor: FC<{
|
|||
InterceptBoldShortcut,
|
||||
InterceptUnderlineShortcut,
|
||||
Span,
|
||||
History.configure({
|
||||
depth: 100, // default is 100
|
||||
newGroupDelay: 100, // default is 500ms
|
||||
}),
|
||||
],
|
||||
content: props.value || '',
|
||||
shouldRerenderOnTransaction: true,
|
||||
immediatelyRender: false,
|
||||
// @ts-ignore
|
||||
onPaste: paste,
|
||||
onUpdate: (innerProps) => {
|
||||
props?.onChange?.(innerProps.editor.getHTML());
|
||||
},
|
||||
|
|
|
|||
|
|
@ -203,16 +203,13 @@ export const ManageModal: FC<AddEditModalProps> = (props) => {
|
|||
});
|
||||
|
||||
for (const item of sliceNeeded) {
|
||||
if (
|
||||
!(await deleteDialog(
|
||||
`${item?.integration?.name} (${item?.integration?.identifier}) post is too long, it will be cropped, do you want to continue?`,
|
||||
'Yes, continue'
|
||||
))
|
||||
) {
|
||||
item.preview();
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
toaster.show(
|
||||
`${item?.integration?.name} (${item?.integration?.identifier}) post is too long, please fix it`,
|
||||
'warning'
|
||||
);
|
||||
item.preview();
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +248,7 @@ export const ManageModal: FC<AddEditModalProps> = (props) => {
|
|||
settings: { ...(post.settings || {}) },
|
||||
value: post.values.map((value: any) => ({
|
||||
...(value.id ? { id: value.id } : {}),
|
||||
content: value.content.slice(0, post.maximumCharacters || 1000000),
|
||||
content: value.content,
|
||||
image:
|
||||
(value?.media || []).map(
|
||||
({ id, path, alt, thumbnail, thumbnailTimestamp }: any) => ({
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@
|
|||
"@tailwindcss/postcss": "^4.1.7",
|
||||
"@tiptap/extension-bold": "^3.0.6",
|
||||
"@tiptap/extension-document": "^3.0.6",
|
||||
"@tiptap/extension-history": "^3.0.7",
|
||||
"@tiptap/extension-paragraph": "^3.0.6",
|
||||
"@tiptap/extension-text": "^3.0.6",
|
||||
"@tiptap/extension-underline": "^3.0.6",
|
||||
|
|
|
|||
|
|
@ -120,6 +120,9 @@ importers:
|
|||
'@tiptap/extension-document':
|
||||
specifier: ^3.0.6
|
||||
version: 3.0.6(@tiptap/core@3.0.6(@tiptap/pm@3.0.6))
|
||||
'@tiptap/extension-history':
|
||||
specifier: ^3.0.7
|
||||
version: 3.0.7(@tiptap/extensions@3.0.6(@tiptap/core@3.0.6(@tiptap/pm@3.0.6))(@tiptap/pm@3.0.6))
|
||||
'@tiptap/extension-paragraph':
|
||||
specifier: ^3.0.6
|
||||
version: 3.0.6(@tiptap/core@3.0.6(@tiptap/pm@3.0.6))
|
||||
|
|
@ -5489,6 +5492,11 @@ packages:
|
|||
peerDependencies:
|
||||
'@tiptap/core': ^3.0.6
|
||||
|
||||
'@tiptap/extension-history@3.0.7':
|
||||
resolution: {integrity: sha512-F+zjS7Wz53sNCWh3KqSAug4/COgxs060tR9up0OXjw7iB3gJz6JMNpGaWmYF5WdOsLxph7FGRMb/Mr5keCqVDA==}
|
||||
peerDependencies:
|
||||
'@tiptap/extensions': ^3.0.7
|
||||
|
||||
'@tiptap/extension-horizontal-rule@3.0.6':
|
||||
resolution: {integrity: sha512-we803tmjQc7SIxw05DNCjrVg6e+eM8bJNM9qPTU4Uo2PkJxvGPshhhfvCz5wchz2ohL3zjEUKJ1FCB6j6iL2nA==}
|
||||
peerDependencies:
|
||||
|
|
@ -21187,6 +21195,10 @@ snapshots:
|
|||
dependencies:
|
||||
'@tiptap/core': 3.0.6(@tiptap/pm@3.0.6)
|
||||
|
||||
'@tiptap/extension-history@3.0.7(@tiptap/extensions@3.0.6(@tiptap/core@3.0.6(@tiptap/pm@3.0.6))(@tiptap/pm@3.0.6))':
|
||||
dependencies:
|
||||
'@tiptap/extensions': 3.0.6(@tiptap/core@3.0.6(@tiptap/pm@3.0.6))(@tiptap/pm@3.0.6)
|
||||
|
||||
'@tiptap/extension-horizontal-rule@3.0.6(@tiptap/core@3.0.6(@tiptap/pm@3.0.6))(@tiptap/pm@3.0.6)':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.0.6(@tiptap/pm@3.0.6)
|
||||
|
|
|
|||
Loading…
Reference in New Issue