Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/components/editor/common/File.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export interface FileAttributes {
src: string;
title: string;
alignment: string;
}

const API_URL = import.meta.env.VITE_API_KEY;
export const createFileNodeHTML = (attrs: FileAttributes): HTMLElement => {
const fileWrapper = document.createElement('div');
fileWrapper.className =
'flex items-center justify-between p-3 border border-gray-300 rounded-lg shadow-sm bg-white max-w-md';
fileWrapper.className = `${attrs.alignment} mt-[30px] flex items-center justify-between p-3 border border-gray-300 shadow-sm bg-white max-w-md`;

const leftDiv = document.createElement('div');
leftDiv.className = 'flex items-center space-x-2';
Expand All @@ -29,7 +29,7 @@ export const createFileNodeHTML = (attrs: FileAttributes): HTMLElement => {
'flex items-center justify-center w-8 h-8 text-blue-600 rounded-full transition';

const downloadLink = document.createElement('a');
downloadLink.href = `http://43.200.90.72/file/download/${attrs.src}`;
downloadLink.href = `${API_URL}file/download/${attrs.src}`;
downloadLink.target = '_blank';
downloadLink.rel = 'noopener noreferrer';

Expand Down
14 changes: 14 additions & 0 deletions src/components/editor/common/extractPaywallData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Editor } from '@tiptap/react';
import { JSONContent } from '@tiptap/core';
import { DOMSerializer } from '@tiptap/pm/model';
import { createFileNodeHTML, FileAttributes } from './File';
import { createLinkNodeHTML, LinkAttributes } from './link';

interface PaywallData {
isPremium: boolean;
Expand Down Expand Up @@ -30,9 +31,22 @@ const extractPaywallData = (editor: Editor): PaywallData => {
const fileWrapper = createFileNodeHTML({
src: node.attrs.src,
title: node.attrs.title,
alignment: node.attrs.alignment,
} as FileAttributes);

tempDiv.appendChild(fileWrapper);
} else if (
['link', 'oglink', 'verticalLink'].includes(node.type) &&
node.attrs?.url
) {
const linkElement = createLinkNodeHTML({
thumbnail: node.attrs.thumbnail,
title: node.attrs.title,
summary: node.attrs.summary,
url: node.attrs.url,
alignment: node.attrs.alignment,
} as LinkAttributes);
tempDiv.appendChild(linkElement);
} else {
const pmNode = schema.nodeFromJSON(node);
const serializedNode = domSerializer.serializeNode(pmNode);
Expand Down
73 changes: 73 additions & 0 deletions src/components/editor/common/link.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
export interface LinkAttributes {
thumbnail?: string;
title: string;
summary: string;
url: string;
alignment: string;
}

export const createLinkNodeHTML = (attrs: LinkAttributes): HTMLElement => {
const linkWrapper = document.createElement('div');

const alignmentClass = attrs.alignment;
linkWrapper.className = `mt-10 max-w-[490px] w-full relative border border-black/10 shadow-md ${alignmentClass}`;

let formattedUrl = attrs.url.trim();
if (
!formattedUrl.startsWith('https://') &&
!formattedUrl.startsWith('http://')
) {
formattedUrl = 'https://' + formattedUrl;
}

if (attrs.thumbnail) {
const imageLink = document.createElement('a');
imageLink.href = formattedUrl;
imageLink.target = '_blank';
imageLink.className = 'block decoration-none';

const imageContainer = document.createElement('div');
imageContainer.className =
'max-h-[450px] overflow-hidden block z-10 relative';

const imgElement = document.createElement('img');
imgElement.src = attrs.thumbnail;
imgElement.className = 'w-full h-auto align-top';
imgElement.alt = attrs.title || '링크 썸네일';

imageContainer.appendChild(imgElement);
imageLink.appendChild(imageContainer);
linkWrapper.appendChild(imageLink);
}

const textLink = document.createElement('a');
textLink.href = formattedUrl;
textLink.target = '_blank';
textLink.className = 'block decoration-none';

const textContainer = document.createElement('div');
textContainer.className =
'px-[26px] pt-[21px] pb-[18px] leading-[1.4] block relative text-left box-border';

const titleElement = document.createElement('strong');
titleElement.className =
'text-[15px] text-ellipsis whitespace-nowrap overflow-hidden break-all block font-bold text-[#333]';
titleElement.textContent = attrs.title;

const summaryElement = document.createElement('p');
summaryElement.className =
'whitespace-nowrap overflow-hidden text-ellipsis break-all max-h-9 leading-[18px] mt-[7px] text-[13px] text-[#999]';
summaryElement.textContent = attrs.summary;

const urlElement = document.createElement('p');
urlElement.className = 'text-[12px] text-[#a1885f] underline';
urlElement.textContent = formattedUrl;

textContainer.appendChild(titleElement);
textContainer.appendChild(summaryElement);
textContainer.appendChild(urlElement);
textLink.appendChild(textContainer);
linkWrapper.appendChild(textLink);

return linkWrapper;
};
75 changes: 41 additions & 34 deletions src/components/editor/customComponent/CustomOgLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@ const CustomOgLink = Node.create({
return [
'div',
{
class: `mt-10 max-w-[450px] w-full relative ${HTMLAttributes.alignment} border border-black/10 overflow-hidden flex`,
class: `mt-10 max-w-[450px] w-full relative ${HTMLAttributes.alignment} border border-black/10 inset-0 text-inherit vertical-align-baseline`,
},
[
'div',
{ class: 'se-module se-module-oglink __se-unit group' },
{
class: 'block relative w-full bg-[#fff] decoration-none shadow-md',
},
[
'div',
{ class: 'w-[110px] block relative z-10' },
Expand All @@ -86,46 +88,51 @@ const CustomOgLink = Node.create({
[
'div',
{
class:
'absolute inset-0 w-px h-4 bg-white transform origin-center -rotate-45',
class: 'absolute inset-0 border-black/10',
},
],
],
],
[
'div',
{
class:
'px-[26px] pt-[21px] pb-[18px] leading-[1.4] block relative text-left box-border text-[0] obsolute inset-0 border border-black/10',
},

[
'div',
{ class: 'inline-block max-w-full align-middle' },
[
'strong',
{
class:
'text-[15px] text-ellipsis whitespace-nowrap overflow-hidden break-all block font-bold text-[#333] ',
},
HTMLAttributes.title,
],
[
'p',
{
class:
'whitespace-nowrap overflow-hidden text-ellipsis break-all max-h-9 leading-[18px] mt-[7px] text-[13px] text-[#999]',
},
HTMLAttributes.summary,
],
{
class: `left-[110px] absolute inset-0 px-[26px] pt-[21px] pb-[18px] leading-[1.4] block text-left box-border text-[0] before:content-[''] before:inline-block before:h-full before:align-middle`,
},
[
'p',
{
class:
'whitespace-nowrap overflow-hidden text-ellipsis break-all mt-[9px] text-[#a1885f] text-[13px] no-underline',
},
HTMLAttributes.url,
'div',
{ class: 'inline-block max-w-full align-middle' },
[
'strong',
{
class:
'text-[15px] font-bold text-[#333] break-all block mb-1 whitespace-nowrap overflow-hidden text-ellipsis',
},
HTMLAttributes.title,
],
[
'p',
{
class:
'mt-[7px] text-[13px] leading-[1.4] text-[#999] break-all whitespace-nowrap overflow-hidden text-ellipsis',
},
HTMLAttributes.summary,
],
[
'p',
{
class:
'mt-[9px] text-[#a1885f] text-[13px] break-all whitespace-nowrap overflow-hidden text-ellipsis no-underline',
},
HTMLAttributes.url,
],
],
],
[
'div',
{
class: 'absolute inset-0 border border-black/10',
},
],
],
];
},
Expand Down
4 changes: 2 additions & 2 deletions src/components/editor/customComponent/CustomVerticalLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ const CustomVerticalLink = Node.create({
[
'div',
{
class: `text-left border-box relative block px-[26px] pt-[21px] pb-[18px] leading-[1.4] before:content-[''] before:inline-block before:h-full before:vertical-align-middle`,
class: `text-left border-box relative block px-[26px] pt-[21px] pb-[18px] leading-[1.4] before:content-[''] before:inline-block before:h-full before:align-middle`,
},
[
'div',
{
class: 'inline-block max-w-full vertical-align-middle',
class: 'inline-block max-w-full align-middle',
},
[
'strong',
Expand Down
2 changes: 1 addition & 1 deletion src/components/editor/customComponent/FileComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const FileComponent = ({ node }: NodeViewProps) => {

return (
<NodeViewWrapper
className={`${alignment} flex items-center justify-between p-3 border border-gray-300 rounded-lg shadow-sm bg-white max-w-md`}
className={`${alignment} mt-[30px] flex items-center justify-between p-3 border border-gray-300 shadow-sm bg-white max-w-md`}
>
<div className="flex items-center space-x-2">
<svg
Expand Down
42 changes: 21 additions & 21 deletions src/components/editor/handler/AddLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,42 @@ const AddLink = ({ editor }: { editor: Editor }) => {
thumbnail: data.hybridGraph.image || '',
title: data.hybridGraph.title || '제목 없음',
summary: data.hybridGraph.description || '설명 없음',
url: data.hybridGraph.url || url,
};
} catch (error) {
console.error('미리보기 데이터를 가져오는 중 오류 발생:', error);
return {
thumbnail: 'https://via.placeholder.com/150',
title: '링크 제목',
summary: '링크 요약 내용',
url: url,
};
}
};

const determineLinkType = ({
thumbnail,
url,
}: {
thumbnail: string;
url: string;
}) => {
if (
url.includes('n.news.naver.com/mnews/article/018/') ||
thumbnail.includes('imgnews.pstatic.net/image/018/')
) {
return 'oglink';
}
return 'link';
};

return (
<button
onClick={async () => {
const url = prompt('링크를 입력하세요:');
if (!url) return;

fetchPreviewData(url).then(({ thumbnail, title, summary }) => {
fetchPreviewData(url).then(({ url, thumbnail, title, summary }) => {
if (url.includes('instagram.com')) {
editor
.chain()
Expand All @@ -46,30 +64,12 @@ const AddLink = ({ editor }: { editor: Editor }) => {
return;
}

if (
editor.getAttributes('is-small') &&
!editor.getAttributes('alt')
) {
editor
.chain()
.focus()
.insertContent({
type: 'oglink',
attrs: {
thumbnail,
title,
summary,
url,
},
})
.run();
return;
}
const linkType = determineLinkType({ thumbnail, url });
editor
.chain()
.focus()
.insertContent({
type: 'link',
type: linkType,
attrs: {
thumbnail,
title,
Expand Down